Advertisement

How to Create a Mashup by Combining 3 Different APIs

by

This tutorial will show you how to create a mashup of three different APIs including integration with Google Maps. This idea came about when I was searching through ProgrammableWeb's API directory for a couple APIs that complimented each other enough that I could use one to provide the other with data. What I came up with will be known as the "Beer Mashup".

Step 1. API Discovery

While looking through ProgrammableWeb's directory, I found an IP geolocating tool called ipLoc. It simply accepts in an IP address and returns relevant location-specific data on it such as it's state, city, country, postal code, etc.

I then found the very cool Beer Mapping Project, which has a huge directory of bars and pubs from not only across the US, but many other countries as well. Instantly I noticed that this was a perfect compliment to ipLoc because the BeerMapping API requires a city (which we can get from the ipLoc API) to return a list of local bars and pubs.

Lastly, I also wanted to integrate Google Maps into this mashup to plot out the addresses of the bars and pubs to add a bit of interactivity to the page instead of just displaying each bar in a simple HTML list.

Step 2. Variable Initialization

I usually find it best to start PHP documents off with some of the variables that I want to set globally within the script. Here I add a line that silences PHP warning messages (Google Maps spits out many of these if you happen to try to map an invalid address) and my BeerMashup and Google Maps API keys. We will end up using these API keys when we get to their respective steps below.

<?php
	error_reporting(E_ERROR|E_PARSE);  //Silence Errors
	
//Initialize Variables
	$beer_api = 'YOUR_BEERMAPPING_API_KEY';
	$gmaps_api = 'YOUR_GOOGLEMAPS_API_KEY';

Step 3. IP Geolocation Setup

The ipLoc API allows you to either specify an IP address to get data on, or use the default IP address that the script finds.

Default Version: http://iploc.mwudka.com/iploc/json/
Static Version (IP address is hardcoded): http://iploc.mwudka.com/iploc/68.162.155.110/json/

//Set Location
	//Visitor IP Address
	$ip = getenv("REMOTE_ADDR");
	
	//via IPLoc
	$iploc = file_get_contents("http://iploc.mwudka.com/iploc/$ip/json/");  //Format: JSON
	$ipdata = json_decode($iploc, true);

After a little testing, I realized that the default version of the ipLoc API was finding the location (Scottsdale, AZ, USA) of my hosting provider's server rather than my home computer's IP location (Pittsburgh, PA, USA). To circumvent this, I decided to use the static IP version of the API (Line 2 above) and passed in the IP address that is detected by the getenv("REMOTE_ADDR") php variable.

After checking if the data has been successfully returned as a decoded json formatted string, we need to extract only the specific data we want to pass to the BeerMapping API, which is the city and state.

	// Error checking
	if ($ipdata['city']) { 
		$city = $ipdata['city'];
		$state = $ipdata['region'];
		$location = $city .", ". $state;
	} else {
		$err = "No location data returned for your IP address: ". $ip; 

	}

Step 4. Integrating Google Maps

This step needs to be done now because the next step will add the location points to Google Maps – and Google Maps has to be initialized before any of that can happen.

To make the Google Maps integration as easy and painless as possible, I've enlisted the help of a great PHP class called Phoogle from System Seven Designs. This class takes care of all the Google Maps API heavy lifting for us while just allowing us to worry about the data.

All we need to do to get this to work is to first include the class file we downloaded: phoogle.php, then set some basic map parameters such as the height, width, zoom level and your Google Maps API key. (Get one of those here).

//Phoogle - GoogleMaps PHP Class
	require_once 'phoogle.php';
	$map = new PhoogleMap();
	$map->setAPIKey($gmaps_api); //Using the variable we set in Step 2
	$map->setHeight(450);
	$map->setWidth(750);
	$map->zoomLevel = 6;
	$map->showType = false;

Step 5. BeerMapping API

Since we have the combined city and state in the variable $location from Step 3, we have everything we need to pull data from the BeerMapping API. Of course we also need one of their API keys, which can be requested here (about a 30 seconds process, start to finish).

A BeerMapping API call looks like this according to their examples:
Real Example: http://beermapping.com/webservice/loccity/71515667a86b8ec7f58cd22e3af86f6e/pittsburgh,pa

After substituting our variables in for the API Key (Step 2) and Location (Step 3), our BeerMapping API call now looks like this:
Our Example: http://beermapping.com/webservice/loccity/$beer_api/$location

After a little playing around with this API, I found that the location can't have any spaces. So the below code first gets rid of the space bewtween the "city, state" format. Then it replaces all other spaces within the location with underscores "_".

//Format Location for use with API
	$locationF = str_replace(", ", ",", $location); // Remove space before "State"
	$locationF = str_replace(" ", "_", $locationF); // Replace space with underscore in "City" name

Their data can only be returned in xml format, so we can easily extract the data returned by this call with the simplexml_load_file PHP function.

//BeerMapping - Format: XML
	$beerdata = simplexml_load_file ("http://beermapping.com/webservice/loccity/$beer_api/$locationF");

As the image shows, we first load the whole file into the variable $beerdata. After checking to see if we returned any results…

	// Error checking
	$beererr = $beerdata->location->id; //$beererr will be 0 if there were no locations returned
	if ($beererr == '0') { 
		$err = "No breweries were found in ". $location; 
	} else {

…the next step is to cycle through each bar/pub returned in the call, extracting all the data we need to pass into Google Maps (Step 4).

		$breweries = $beerdata->location;
		$barcount = count($breweries); //How Many?
		
		foreach ($breweries as $brewery) {
			$name = $brewery->name;
			$link = $brewery->reviewlink;
			$street = $brewery->street;
			$city = $brewery->city;
			$state = $brewery->state;
			$zip = $brewery->zip;
			$phone = $brewery->phone;
			
			//Location Point set for the Google Maps API
			$map->addAddress("$street $city $state $zip", "<a href='$link' title='$name BeerMap'>$name</a><br/>$street<br />$city, $state $zip<br />Phone: $phone");
		} 
	}
?>

Line 1 above sets the structure location of the "locations". Line 2 counts the amount of "locations" the API result returned. The remaining lines use a foreach loop to cycle though each "location" and pull out it's address information. Line 14 sets a "point" for each brewery on our Google Map.

Step 6. HTML Generation

After finishing all the PHP code that we've created, we can now work on displaying it. The first few lines shown below are standard in any HTML document, but after that we get back to using PHP. We first check to see if the variable $err is FALSE – which would mean that the $err variable is empty, or that we never received an error. If we never got an error, we spit out the Google Map, otherwise we spit out an error message.

<html xmlns="http://www.w3.org/1999/xhtml">
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" type="text/css" href="styles.css" />
<title>Bars Near <?php echo $location; ?></title>
</head>
	<body>
	<div class="wrapper">
		<div class="header">
			<img class="logo" src="images/logo.png" alt="The Beer Mashup" />
			
			<p class="footer">Developed by <a href="http://www.cagintranet.com">Chris Cagle</a> for <a href="http://www.nettuts.com">NETTUTS</a></p>
			
			<div class="mapdiv">
				<?php 
				if (!$err) {
					echo "<div>";
					$map->printGoogleJS();
					$map->showMap();
					echo "<h3>". $location ." <span>(". $barcount ." Bars)</span></h3>";
				} else {
					echo "<p class=\"error\"><b>". $err ."</b></p>";;
				} 
				?>
			</div>
		</div>	
	</div>	
	</body>
</html>

After adding in some text and CSS and you now have a great looking web page that displays all the bars and pubs within the vicinity of the location of whoever is viewing the web page.

View the demo of the page as it stands now. The mashup is working great now, but we have one more improvement that will make all the difference when it comes to UI.

Step 7. Changing the Code to Allow Locations to be Input by the Visitor

At this point, our page works just fine but there is one small caveat: The visitor can only view bars from his or her current location. What if the visitor wants research bars in a different town rather than the one our IP API returned for him or her? Any visitor would want the ability to specify the location to research in.

To allow this, we will have a simple form that will accept in a city and state from the visitor then reload the page for the given location and skip the ipLoc API call completely. We will insert this code right before our <div class="mapdiv"> line in Step 6.

<form method="post" id="form" action="beermashup2.php">
	<span>location: (ex. New Orleans, LA)</span>
	<input type="text" value="" name="loc" id="loc" /><br class="clear" />
	<input type="submit" id="submitted" value="SEARCH" name="submitted" />
</form>

In order to make this work, we will need to wrap the code we made in the ipLoc step (Step 3) in an if-statement that checks if the form was submitted or not. If the form *was not* submitted (which will happen each time the page is initially loaded), then it will use the ipLoc IP geolocation code. If the form *was* submitted, it will take what the user submitted and set our $location variable to that.

//Set Location
	if ( isset($_POST['loc']) ) {
		//via user input
		$location = $_POST['loc']; 
	} else {
		//Visitor IP Address
		$ip = getenv("REMOTE_ADDR");

		//via IPLoc
		$iploc = file_get_contents("http://iploc.mwudka.com/iploc/$ip/json/");  //Format: JSON
		$ipdata = json_decode($iploc, true);
		
		// Error checking
		if ($ipdata['city']) { 
			$city = $ipdata['city'];
			$state = $ipdata['region'];
			$location = $city .", ". $state;
		} else {
			$err = "No location data returned for your IP address: ". $ip; 
		}

Step 8. Putting it all Together

View the demo of the final application.

You can view the source code of the final project (which is pretty much just the steps above pushed together) and see how I ended up combining 3 separate APIs into one application. Take a stroll for yourself through the API directory over at ProgrammableWeb and see what you can come up with on your own. Working with APIs is my new obsession because it is exciting to be able to create something new and useful from someone else's data. If this tutorial has helped you mashup a couple of APIs, post them here - I would love to see them.