Google Geocoding API returns ZERO_RESULTS for web-normalized address

sootsnoot picture sootsnoot · Jul 9, 2015 · Viewed 15.5k times · Source

I've seen several questions about getting ZERO_RESULTS for addresses that the user believes to be correct, which were resolved by correcting usage errors (e.g. failure to urlencode the address), or by tweaking the address to a form that google expects (e.g. spelling out "street" instead of using the ambiguous abbreviation "st").

But I'm seeing a couple of addresses where my original form gets corrected by maps.google.com on the web, which then shows the location on the map correctly. But feeding that corrected form to the geocoding API still gets ZERO_RESULTS.

I've found by trial-and-error with the example below that removing the name of the town (Guilford), leaving just the post town (Craigavon), allows it to geocode to the street address. The google maps web application included the town (and corrected its spelling) when correcting the user input. And the "formatted_address" field in the geocoding result actually adds the town back in (as "locality"). But the presence of the town in the input address for geocoding causes it to find no results. Can anyone explain this? Is this something special about UK addresses? Is there something in Google's documentation that might explain this behavior?

Here is a specific example:

Original address: 30 Drumnascumph Rd,Guildford,Craigavon,United Kingdom,BT63 6DU maps corrects to: 30 Drumnascamph Road,Gilford,Craigavon,United Kingdom,BT63 6DU

Both the original and corrected address give identical results from geocoding:

{"results" : [], "status" : "ZERO_RESULTS" }

If I change the corrected form just to remove the town (locality), then the geocoding result changes to:

{
   "results" : [
      {
         "address_components" : [
            {
               "long_name" : "30",
               "short_name" : "30",
               "types" : [ "street_number" ]
            },
            {
               "long_name" : "Drumnascamph Road",
               "short_name" : "Drumnascamph Rd",
               "types" : [ "route" ]
            },
            {
               "long_name" : "Gilford",
               "short_name" : "Gilford",
               "types" : [ "locality", "political" ]
            },
            {
               "long_name" : "Craigavon",
               "short_name" : "Craigavon",
               "types" : [ "postal_town" ]
            },
            {
               "long_name" : "Banbridge",
               "short_name" : "Banbridge",
               "types" : [ "administrative_area_level_2", "political" ]
            },
            {
               "long_name" : "United Kingdom",
               "short_name" : "GB",
               "types" : [ "country", "political" ]
            },
            {
               "long_name" : "BT63 6DU",
               "short_name" : "BT63 6DU",
               "types" : [ "postal_code" ]
            }
         ],
         "formatted_address" : "30 Drumnascamph Road, Gilford, Craigavon, Banbridge BT63 6DU, UK",
         "geometry" : {
            "location" : {
               "lat" : 54.3892242,
               "lng" : -6.3126861
            },
            "location_type" : "ROOFTOP",
            "viewport" : {
               "northeast" : {
                  "lat" : 54.3905731802915,
                  "lng" : -6.311337119708497
               },
               "southwest" : {
                  "lat" : 54.3878752197085,
                  "lng" : -6.314035080291502
               }
            }
         },
         "partial_match" : true,
         "place_id" : "ChIJnzmv0ELkYEgR12ArIQ1GTnk",
         "types" : [ "street_address" ]
      }
   ],
   "status" : "OK"
}

UPDATE: @Dr.Molle I was not aware of the geocoder tool, thank you very much! I get the same result that you do, so it must be my code. Here it is:

    $address = implode(',', $address_array);
    $url_encoded = urlencode($address);
    require 'Phpclasses/Google/private/keys.php';
    $geo_url = "https://maps.googleapis.com/maps/api/geocode/json?address=$url_encoded;key=$GOOGLE_API_KEY";
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $geo_url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
    $result = curl_exec($ch);
    curl_close($ch);
    if ($result === false) {
        throw new Exception("curl_exec() failed, \$geo_url = '$geo_url'");
    }
    $response = json_decode($result);

The values I posted were the values of the $result variable copy-pasted from xdebug. I notice that the end-point I'm using doesn't contain the string "v3" in it - am I using an outdated end-point? If not, then I wonder how I could be getting a different result from the tool? Maybe something about curl or the server I'm running on?

UPDATE2: Thanks to Dr. Molle's comment making me post the code, I checked my code again for the 10,001'th time and noticed I separated the key from the address with a ';' instead of a '&'. Fixed that, and now I also get correct results for both forms of address. Boy is my face red, good thing that shotgun in the corner isn't loaded :-) Of course that makes me wonder how that invalid url produces correct result for most addresses and causes this one to work when the town is removed, but I guess the old rule "garbage in, garbage out" applies. Thank you, Stack Overflow.

Answer

sootsnoot picture sootsnoot · Jul 9, 2015

The problem was just that in the maps api query, the 'key' parameter was separated from the 'address' parameter by a ';' instead of a '&'.

I noted this in the 2nd update to the question, but then I thought I should answer it so that it could have an accepted answer. Credit really belongs to Dr.Molle.