-
Get Geo Coordinates from Google Maps in PHP
Posted on February 5th, 2010 No commentsGoogle maps offers a rich api for getting a lot of information as you are probably already aware. I’ve written a few locators in the last couple of years involving the use of google maps and doing radial searches based on zip codes. The difficult part for me was getting the geo coordinates of the queried zip code to use as a reference point for doing the radial search. I ended up writing a nice simple class to encapsulate converting zip codes into geo-coordinates.
Credit totally goes to Marc at http://www.blogama.org/node/53 for providing the know-how for the base of this class. I took his concept and extended it.
-
-
class FP_Google_Maps {
-
-
public static function getAddressGeoCoordinates($pAddress, $pCity, $pState, $pZip, $pKey, $pCountryCode=‘US’){
-
return self::getZipGeoCoordinates("{$pAddress}, {$pCity}, {$pState} {$pZip}", $pKey, $pCountryCode);
-
}
-
-
-
if (!$d)
-
return false; // Failed to open connection
-
-
-
return $d;
-
-
}
-
-
-
-
return false;
-
-
if ($pCache){
-
if ($geo = $pCache->load(‘google_geo_coordinates_’ . $pZip))
-
return $geo;
-
}
-
-
-
$query = ‘http://maps.google.com/maps/geo?q=’ . $pZip . ‘&output=xml&key=’ . $pKey;
-
-
$d = self::_geo($query);
-
-
if (!$d)
-
return false; // Failed to open connection
-
-
$coord = new SimpleXMLElement($d);
-
-
$status_code = (string) $coord->Response->Status->code;
-
-
if ($status_code != ’200′){
-
$success = false;
-
-
if ($status_code = ’620′){
-
$delay = 0;
-
$attempts = 0;
-
-
while (($attempts <= 5) && $status_code != ’200′){
-
$attempts += 1;
-
$delay += 2000000;
-
-
$d = self::_geo($query);
-
-
if (!$d)
-
return false; // Failed to open connection
-
else {
-
$coord = new SimpleXMLElement($d);
-
$status_code = (string) $coord->Response->Status->code;
-
}
-
}
-
-
if ($status_code == ’200′)
-
$success = true;
-
}
-
-
if (!$success){
-
return false; // Invalid status code
-
}
-
}
-
-
$CA_results = 0;
-
-
for ($i=0;$i<$nb_results;$i++){
-
-
//get the accuracy. Result of 5 is a postal code
-
foreach($coord->Response->Placemark[$i]->AddressDetails->attributes() as $a => $b) {
-
$accuracy = $b;
-
}
-
-
if (($coord->Response->Placemark[$i]->AddressDetails->Country->CountryNameCode == $pCountryCode) && ($accuracy == 5)){
-
$CA_results++;
-
$ONLY_results = $i;
-
}
-
}
-
-
//multiple results
-
if ($CA_results > 1){
-
return false;
-
}
-
-
//no results
-
if ($CA_results < 1){
-
return false;
-
}
-
-
//Get the latitude and longitude
-
-
if ($pCache)
-
$pCache->save($geo, ‘google_geo_coordinates_’ . $pZip);
-
-
return $geo;
-
}
-
}
-
?>
-
So at the moment, this class has only one useful method, getZipGeoCoordinates(). At a minimum it requires the zip could you wish to translate into geo-coordinates as well as your google maps api key. One of the extensions I made was the optional parameter to pass in a Zend_Cache object which allows frequently queried zip codes to remain cached rather than increasing your request count to the google maps api.
The method takes your zip code and key and constructs a url which it uses to retrieve an xml response from the api. The xml is parsed for the information you desire and is passed back as an array with two elements, the longitude and latitude respectively.
You may have noticed the loop that occurs if the api does not return the expected response code 200. If you have a really traffic site, like I did when I wrote this, you may run into the 620 code that google maps returns if you are making too many requests too quickly. If that happens, this class will retry it’s requests using a progressively longer delay (2 additional seconds) between each request.
This class makes a great base for your google maps functionality and scales well on high traffic sites in a way that doesn’t get you black listed from the api. Enjoy
Leave a reply
-


