How do you get the corresponding street address details for a geographic location expressed as latitude and longitude data only? Oh, and it should be a server side procdure too (i.e. no JavaScript). Well, here a a couple of solutions for PHP.
1. Google Maps
The following HTTP GET request…
http://maps.google.com/maps/geo?q=37.34,-121.94&output=json&sensor=false
…spits out a JSON response from the Google servers:
{ "name": "37.34,-121.94", "Status": { "code": 200, "request": "geocode" }, "Placemark": [ { "id": "p1", "address": "1060 Highland Ct, Santa Clara, CA 95050, USA", "AddressDetails": { "Accuracy" : 8, "Country" : { "AdministrativeArea" : { "AdministrativeAreaName" : "CA", "SubAdministrativeArea" : { "Locality" : { "LocalityName" : "Santa Clara", "PostalCode" : { "PostalCodeNumber" : "95050" }, "Thoroughfare" : { "ThoroughfareName" : "1060 Highland Ct" } }, "SubAdministrativeAreaName" : "Santa Clara" } }, "CountryName" : "USA", "CountryNameCode" : "US" } }, "ExtendedData": { "LatLonBox": { "north": 37.3431416, "south": 37.3368464, "east": -121.9368374, "west": -121.9431326 } }, "Point": { "coordinates": [ -121.9399850, 37.3399940, 0 ] } } ] }
Accessing the JSON info via PHP is fairly easy:
$url = 'http://maps.google.com/maps/geo?q=37.34,-121.94&output=json&sensor=false'; $data = @file_get_contents($url); //read the HTTP request $jsondata = json_decode($data,true); //parse the JSOPN response if(is_array($jsondata) && $jsondata['Status']['code']==200) //check data { $addr = $jsondata['Placemark'][0]['address']; } echo $addr;
There you go. There’s one catch, though. Google’s terms and conditions disallow using the JSON requests outside the context of a Google Map. So it can’t be used to automatically populate a database for example.
2. Open Street Map (OSM)
Open Street Map offers a legal alternative, albeit a limited and not as accurate one as the Google API. The JSON request URL for OSM is as follows:
http://nominatim.openstreetmap.org/reverse?format=json&lat=37.34&lon=-121.94
This returns the following – compared to the Google output rather simple – output:
{ "place_id":"16539418", "licence":"Data Copyright OpenStreetMap Contributors, Some Rights Reserved. CC-BY-SA 2.0.", "osm_type":"way","osm_id":"8936657", "display_name":"Highland Court, Santa Clara, Santa Clara County, California, 95050, United States of America", "address":{"road":"Highland Court", "city":"Santa Clara", "county":"Santa Clara County", "state":"California", "postcode":"95050", "country":"United States of America", "country_code":"us" } }
The corresponding PHP code is pretty much the same as already stated above but for clarity here is the whole block
$url = 'http://nominatim.openstreetmap.org/reverse?format=json&lat=37.34&lon=-121.94'; $data = @file_get_contents($url); //read the HTTP request $jsondata = json_decode($data,true); //parse the JSOPN response if(is_array($jsondata)) //check data { $addr = $jsondata['display_name']; } echo $addr;
As I said, the OSM data is not as accurate and for some regions doesn’t feature house numbers or suburb names. That is not to say that this won’t get better in time.
Compared to the Google request, OSM responses are quite slow, so parsing lots of addresses takes time. So PHP script execution time limits need to be considered.