gplana
asked on
Why Google API returns different results than Google Maps?
Hi.
I have this function in php which uses Google API to convert an address to its GPS coordinates:
It works ok, but for some addres I'm getting innacurate coordinates. For example, if I call this function with address "calle don jaime I, 26 50001 zaragoza Spain" this function returns coordinates 41.6524051,-0.879501 instead of 41.692248,1.745868 which are the coordinates returned by google map: https://maps.google.es/maps?q=calle+don+jaime+I,+26+%0950001+%09zaragoza+%09Spain&hl=es&sll=41.692248,1.745868&sspn=3.359188,4.938354&hnear=Calle+Don+Jaime+I,+26,+50003+Zaragoza&t=m&z=17
Why?
Thanks.
I have this function in php which uses Google API to convert an address to its GPS coordinates:
$googleKey = 'my google key here';
function gps_coordinates($address) {
global $googleKey;
$url = 'http://maps.google.com/maps/geo?q='. urlencode($address) . '&output=json&oe=utf8&sensor=false&key='.$googleKey;
//echo "$url <br />\n";
$content = file_get_contents($url);
//echo htmlentities($content)."<br />\n";
$json = json_decode($content);
return $json->Placemark[0]->Point->coordinates;
}
It works ok, but for some addres I'm getting innacurate coordinates. For example, if I call this function with address "calle don jaime I, 26 50001 zaragoza Spain" this function returns coordinates 41.6524051,-0.879501 instead of 41.692248,1.745868 which are the coordinates returned by google map: https://maps.google.es/maps?q=calle+don+jaime+I,+26+%0950001+%09zaragoza+%09Spain&hl=es&sll=41.692248,1.745868&sspn=3.359188,4.938354&hnear=Calle+Don+Jaime+I,+26,+50003+Zaragoza&t=m&z=17
Why?
Thanks.
ASKER
Thank you for your answer. I have searched for Google forums and found that I should put my question on stackoverflow.
Here is the link:
http://stackoverflow.com/questions/15706215/why-google-api-returns-different-results-than-google-maps
Or may I post on somewhere else?
Here is the link:
http://stackoverflow.com/questions/15706215/why-google-api-returns-different-results-than-google-maps
Or may I post on somewhere else?
Is the question, "Why?" or is the question, "Which is the canonical geocoding service?" I don't think we can help with "Why" unless we can spot an error in the response strings.
Here is how I would go about finding the geocode. Interestingly, these responses are quite close together, yet they do not match either answer you got! Note also that both of the Geocoders changed 50001 zaragoza to 50003 Zaragoza
http://www.laprbass.com/RAY_temp_gplana.php
Here is the response from the Geocoders:
http://www.laprbass.com/RAY_temp_gplana.php
Here is the response from the Geocoders:
YAHOO! DATA FOR calle don jaime I, 26 50001 zaragoza Spain
SimpleGeoCoder Object
(
[location] => Calle Don Jaime I 26, 50003 Zaragoza
[address] => Calle Don Jaime I 26
[city] => Zaragoza
[state] => AR
[zip] => 50003
[latitude] => 41.65329
[longitude] => -0.87836
[precision] => 87
[warning] =>
[geocoder] => Yahoo!
)
GOOGLE DATA FOR calle don jaime I, 26 50001 zaragoza Spain
SimpleGeoCoder Object
(
[location] => Calle Don Jaime I, 26, 50003 Zaragoza, Spain
[address] =>
[city] =>
[state] =>
[zip] =>
[latitude] => 41.6534376
[longitude] => -0.8781994
[precision] => street_address
[warning] =>
[geocoder] => Google
)
And here is the code I used to get that response.<?php // RAY_temp_gplana.php
error_reporting(E_ALL);
$location = 'calle don jaime I, 26 50001 zaragoza Spain';
// PREPARE THE GEOCODER
$y_demo = new SimpleGeoCoder;
$y_demo->location = $location;
// TEST THE YAHOO! GEOCODER
$y_demo->geocodeYahoo();
echo "<pre>";
echo PHP_EOL;
echo "YAHOO! DATA FOR <strong>$location</strong>";
echo PHP_EOL;
print_r($y_demo);
echo "</pre>";
// PREPARE THE GEOCODER
$g_demo = new SimpleGeoCoder;
$g_demo->location = $location;
// TEST THE GOOGLE GEOCODER
$g_demo->geocodeGoogle();
echo "<pre>";
echo PHP_EOL;
echo "GOOGLE DATA FOR <strong>$location</strong>";
echo PHP_EOL;
print_r($g_demo);
echo "</pre>";
// ALL DONE
die();
// SIMPLE GEOCODER CLASS
class SimpleGeoCoder
{
// DECLARE THE INPUT DATA
public $location; // USE THIS FOR A FREEFORM QUERY, OR USE THESE PARTS
public $address;
public $city;
public $state;
public $zip;
// DECLARE THE OUTPUT DATA
public $latitude;
public $longitude;
public $precision;
public $warning;
public $geocoder;
// DECLARE THE CONSTRUCTOR
public function __construct()
{
$this->latitude = 0.0;
$this->longitude = 0.0;
$this->precision = 0; // HIGHER IS BETTER, BUT Y AND G USE DIFFERENT SCALES
$this->warning = '';
$this->geocoder = '';
}
// DECLARE THE YAHOO! VERSION OF THE WORKHORSE
public function geocodeYahoo()
{
$this->geocoder = 'Yahoo!';
// SET THE URL AND OPTIONAL API KEY
$yahooUrl = "http://where.yahooapis.com/geocode?gflags=Q&appid=";
if (defined("YAHOO_API"))
{
$yahooUrl .= YAHOO_API;
}
// YOU CAN ASK FOR A FREEFORM QUERY
if ($this->location != '')
{
$yahooUrl .= "&location=" . urlencode($this->location);
}
// YOU CAN ASK FOR INDIVIDUAL PIECES OF AN ADDRESS
else
{
$loc = urlencode
( trim($this->address)
. ', '
. trim($this->city)
. ', '
. trim($this->state)
. ' '
. trim($this->zip)
)
;
$yahooUrl .= "&location=" . $loc;
}
// EXECUTE YAHOO GEOCODER QUERY SEE http://developer.yahoo.com/geo/placefinder/guide/requests.html
// NOTE - USE ERROR SUPPRESSION OR IT WILL BARK OUT THE YAHOO API KEY - ON FAILURE RETURNS HTTP 400 BAD REQUEST
if ($yfp = @fopen($yahooUrl, 'r'))
{
$yahooResponse = '';
while (!feof($yfp)) { $yahooResponse .= fgets($yfp); }
fclose($yfp);
}
else
{
return FALSE;
}
// EXAMINE THE RESULT
if ($yahooResponse != '') // NOT EMPTY, WE GOT DATA
{
$ydata = new SimpleXMLElement($yahooResponse);
// echo "<pre>";var_dump($ydata);
// CHECK FOR ANY ERROR MESSAGE, IF NONE, EXTRACT THE DATA POINTS
$y_err = (string)$ydata->Error;
if ($y_err)
{
$this->warning = $ydata->ErrorMessage;
return FALSE;
}
else
{
$this->precision = (string)$ydata->Result->quality;
$this->latitude = (string)$ydata->Result->latitude;
$this->longitude = (string)$ydata->Result->longitude;
$this->address = (string)$ydata->Result->line1;
$this->city = (string)$ydata->Result->city;
$this->state = (string)$ydata->Result->statecode;
$this->zip = (string)$ydata->Result->postal;
$this->location
= (string)$ydata->Result->line1
. ', '
. (string)$ydata->Result->line2
. ' '
. (string)$ydata->Result->line3
;
}
}
// NO RESULT - SOMETHING IS SICK AT YAHOO
else
{
return FALSE;
}
return TRUE;
} // END function geocodeYahoo
// DECLARE THE GOOGLE VERSION OF THE WORKHORSE
public function geocodeGoogle()
{
$this->geocoder = 'Google';
// SET THE URL AND OPTIONAL API KEY
$googleUrl = "http://maps.googleapis.com/maps/api/geocode/xml?sensor=false";
if (defined("GOOGLE_API"))
{
$googleUrl .= "&key=" . GOOGLE_API;
}
// YOU CAN ASK FOR A FREEFORM QUERY
if ($this->location != '')
{
$googleUrl .= "&address=" . urlencode(trim($this->location));
}
// YOU CAN ASK FOR INDIVIDUAL PIECES OF AN ADDRESS
else
{
$loc = urlencode
( trim($this->address)
. ', '
. trim($this->city)
. ', '
. trim($this->state)
. ' '
. trim($this->zip)
)
;
$googleUrl .= "&address=$loc";
}
// EXECUTE GOOGLE GEOCODER QUERY SEE http://code.google.com/apis/maps/documentation/geocoding/
if ($gfp = @fopen($googleUrl, 'r'))
{
$googleResponse = '';
while (!feof($gfp)) { $googleResponse .= fgets($gfp); }
fclose($gfp);
}
else
{
return FALSE;
}
// EXTRACT THE DATA
$gdata = new SimpleXMLElement($googleResponse);
// ON FAILURE
if ($gdata->status != 'OK') return FALSE;
// GEOCODE ACCURACY IS A TEXT STRING NOW
$this->location = (string)$gdata->result->formatted_address;
$this->precision = (string)$gdata->result->type;
$this->latitude = (string)$gdata->result->geometry->location->lat;
$this->longitude = (string)$gdata->result->geometry->location->lng;
return TRUE;
} // END function geocodeGoogle
} // END class SimpleGeocoder
Also, I found that I can zoom in closer to the destination address when I start from Google Search. When I start from Google Maps, I could not zoom as far in. Odd, but that's what you get from a free service! If I went to Search first, then switched to Maps, I got this map. I did not try to compute the center point
https://maps.google.com/maps?q=Calle%2BDon%2BJaime%2BI,%2B26,%2B50003%2BZaragoza,%2BSpain&hl=en&ll=41.653439,-0.878198&spn=0.001591,0.003484&sll=38.930454,-77.148131&sspn=0.001657,0.003484&hnear=Calle+Don+Jaime+I,+26,+50003+Zaragoza,+Spain&t=m&z=19
https://maps.google.com/maps?q=Calle%2BDon%2BJaime%2BI,%2B26,%2B50003%2BZaragoza,%2BSpain&hl=en&ll=41.653439,-0.878198&spn=0.001591,0.003484&sll=38.930454,-77.148131&sspn=0.001657,0.003484&hnear=Calle+Don+Jaime+I,+26,+50003+Zaragoza,+Spain&t=m&z=19
ASKER
Thank you for your answer. Isn't the center point the value marked by ll ? i.e. ll=41.653439,-0.878198 ?
Also I didn't understand 100% your answers. What I'm doing wrong on my code?
Also I didn't understand 100% your answers. What I'm doing wrong on my code?
It looks like the center point is marked by the ll=
ll=41.653439,-0.878198 seems to be pretty close to the same location identified by the (corrected) address. How many meters off are you finding the other geocodes?
ll=41.653439,-0.878198 seems to be pretty close to the same location identified by the (corrected) address. How many meters off are you finding the other geocodes?
ASKER
I think it's about 100 meters.
If you put "41.6524051,-0.879501" on the search bar of maps.google.es you will see the difference between this and putting the address "calle don jaime I, 26 50001 zaragoza Spain"
If you put "41.6524051,-0.879501" on the search bar of maps.google.es you will see the difference between this and putting the address "calle don jaime I, 26 50001 zaragoza Spain"
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thank you for your answer. I tryied to put 50003 instead of 50001 and the the result is exact.
Many thanks.
Many thanks.
Thanks for the points. I think when the Geocoders correct the address, it should be treated as a red flag, and at least checked, if not changed in your data model. Best regards, ~Ray
Cd&