Reverse Geocoder Concepts

The term Geocoding is often used to describe the mapping between an address and its geographical coordinate. The Google Map API offers this service trough the GClientGeocoder class.

Reverse Geocoding is the inverse relationship where each geographical coordinate is mapped to the nearest known address. Currently this features is not directly supported by the Google Map API. But can be done by the Reverse Geocoder for Google Maps, as explained below.

The API is based upon the Google Maps API, and uses both GClientGeocoder as GDirections and is thus bound to their limits (15.000 and 10.000 request per IP and per 24h, thus the GReverseGeocoder can support a maximum of 10.000 reverse geocode requests per IP and per 24h, if the house number support is enabled the actual limit is lower). See Google Maps API Terms of Use and Terms of Service for Google Maps

The API is new, so there may be bugs and slightly less than perfect Documentation. Bear with me as I try to fill in the holes, and feel free to give feedback and discuss the API.

IMPORTANT NEWS

News

Version update v1.0.8

Nico Goeminne - nicogoeminne at gmail.com

Table of Contents

Audience

This Documentation is designed for people familiar with JavaScript programming and object-oriented programming concepts. You should also be familiar with the Google Maps API

Introduction

The "Hello, World" of Reverse Geocoding

The easiest way to start learning about this API is to see a simple example. The following web page displays a 500x300 map centered on the city of Gent, it Reverse geocodes the centre of the map:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
    <title>Reverser Geocoder for Google Maps Example</title>
    <script src="http://maps.google.com/maps?file=api&v=2&key=yourkey"
      type="text/javascript"></script>
    <script src="http://nicogoeminne.googlepages.com/greversegeocoder.js"
      type="text/javascript"></script>
    <script type="text/javascript">
    //<![CDATA[

    function load() {
      if (GBrowserIsCompatible()) {
        var map = new GMap2(document.getElementById("map"));
        map.setCenter(new GLatLng(51.05226693177032, 3.723893165588379), 15);
        var reversegeocoder = new GReverseGeocoder(map);

        GEvent.addListener(reversegeocoder, "load",
          function(placemark) {
            alert(placemark.address);
          }
        );

        reversegeocoder.reverseGeocode(new GLatLng(51.05234786289687, 3.7240219116210938));
      }
    }

    //]]>
    </script>
  </head>
  <body onload="load()" onunload="GUnload()">
    <div id="map" style="width: 500px; height: 300px"></div>
  </body>
</html>

You can download this example to edit and play around with it, but you'll have to replace the key in that file with your own Google Maps API key.

The URL in the example above (http://nicogoeminne.googlepages.com/greversegeocoder.js) is the location of a JavaScript file that includes all of the symbols you need for adding Reverse Geocoding to your Google Maps Application. Your page must contain a script tag pointing to that URL. It always includes the latest version of the API, if for some reason you need a specific version you need to include greversergeocodervXXX.js where XXX is the version number e.g. 106.

Reverse Geocoding

Each of the following examples shows only the relevant JavaScript code, not the full HTML file. You can plug the JS code into the skeleton HTML file shown earlier, or you can download the full HTML file for each example by clicking the link after the example.

The Basics

The following example creates the Reverse geocoder.

var map = new GMap2(document.getElementById("map"));
var reversegeocoder = new GReverseGeocoder(map);

Setting The Country - DEPRICATED IN V1.0.2

DEPRICATED: You should always set the target country before doing a Reverse Geocoding request. The country defaults setting is "Belguim"

reversegeocoder.setBaseCountry("United Kingdom");

Adding Event Listeners

The Reverse geocoder supports two kind of events. The "load" event occurs when a request was handled succesfull. The resulting JSON placemark object is passed along. When the Reverse geocode request fails the "error" event is triggered.

GEvent.addListener(reversegeocoder, "load",
  function(placemark) {
    alert(placemark.address);
  }
);
GEvent.addListener(reversegeocoder, "error",
  function() {
    alert("Unable to Reverse geocode");
  }
);

Here we show an example of the JSON object returned by the Reverse geocoder

{
   "address": "1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA",
   "AddressDetails": {
     "Country": {
       "CountryNameCode": "US",
       "AdministrativeArea": {
         "AdministrativeAreaName": "CA",
         "SubAdministrativeArea": {
           "SubAdministrativeAreaName": "Santa Clara",
           "Locality": {
             "LocalityName": "Mountain View",
             "Thoroughfare": {
               "ThoroughfareName": "1600 Amphitheatre Pkwy"
             },
             "PostalCode": {
               "PostalCodeNumber": "94043"
             }
           }
         }
       }
     },
     "Accuracy": 8
   },
   "Point": {
     "coordinates": [-122.083739, 37.423021, 0]
   }
}

Reverse Geocoding

Once the Reverse geocoder is set up and the events are bound, a Reverse geocode request can be done by:

reversegeocoder.reverseGeocode(new GLatLng(-122.083739, 37.423021));

Full Example

This full example alows you to click on the map or fill in the coordinates directly, before doing the Reverse Geocoding.

Full Example for v1.0.7

Compare Example for v1.0.6

Full Example for v1.0.5

Full Example for v1.0.4

Full Example for v1.0.2

Full Example for v1.0.1

Experimental House Number Support

Since v1.0.2. Once the Reverse geocoder is set up experimental house number support is enabled by calling the setExperimentalHouseNumber method as shown in the example.
THIS FEATURE IS EXPERIMENTAL AND USES MULTIPLE GClientGeocoder AND GDirections REQUESTS WHICH COULD EXCESS THE GOOGLE REQUEST LIMITS. That's exactly why it is disabled (uncommented) in the full example. Use it on own risk.

reversegeocoder.setExperimentalHouseNumber(true);

House Number Example for v1.0.2 (limited to 5 requests per http session)

Accuracy Information

Since v1.0.3. The resulting placemark object contains some more accuracy information when using the house number support.

  • Point: The GLatLng point of the end result (the closest address on the road)
  • PointOnRoad: The closest GLatLng Point on the road (snap to road)
  • RequestPoint: The original requested GLatLng point.
  • Distance: The distance in meters between request point and result point.
  • DistanceOnRoad: The distance in meters between road point and result point.

Be aware that google returns [lng, lat] in the JSON object!

{
   "address": "1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA",
   "AddressDetails": {
     "Country": {
       "CountryNameCode": "US",
       "AdministrativeArea": {
         "AdministrativeAreaName": "CA",
         "SubAdministrativeArea": {
           "SubAdministrativeAreaName": "Santa Clara",
           "Locality": {
             "LocalityName": "Mountain View",
             "Thoroughfare": {
               "ThoroughfareName": "1600 Amphitheatre Pkwy"
             },
             "PostalCode": {
               "PostalCodeNumber": "94043"
             }
           }
         }
       }
     },
     "Accuracy": 8
   },
   "Point": {
     "coordinates": [-122.083739, 37.423021, 0]
   },
   "PointOnRoad": {
     "coordinates": [-122.08345, 37.423068, 0]
   },
   "RequestPoint": {
     "coordinates": [-122.08349, 37.423072, 0]
   },
   "Distance": 45.36,
   "DistanceOnRoad": 5.07
}

Use the following result handler to obtain the accuracy information

  GEvent.addListener(rg, "load",
    function(placemark) {
      var reqpoint = new GLatLng(placemark.RequestPoint.coordinates[1],
                                   placemark.RequestPoint.coordinates[0]);
      var roadpoint = new GLatLng(placemark.PointOnRoad.coordinates[1],
                                   placemark.PointOnRoad.coordinates[0]);
      var respoint = new GLatLng(placemark.Point.coordinates[1],
                                   placemark.Point.coordinates[0]);

      alert('Requested Point:' + reqpoint);
      alert('Closest Point On Road:' + roadpoint);
      alert('Address Result Point:' + respoint);

      alert('Distance On Road:' + placemark.DistanceOnRoad);
      alert('Distance:' + placemark.Distance);

      alert(placemark.address);
    }
  );

Acurracy Information example for v1.0.3 (limited to 5 requests per http session)

Obtaining a Placemark Property

Since v1.0.5. The getPlacemarkProperty help function is useful to investigate the resulting placemark. The placemark structure and available poperties depend on the used data provider. Therfore the structure and property names may be different. This method searches the placemark for a certain property name and returns the corresponding object or null when it is not present. The example below searches for the postal code number.

GEvent.addListener(reversegeocoder, "load",
  function(placemark) {
    var postalcodenumber = reversegeocoder.getPlacemarkProperty(placemark,"PostalCodeNumber");
    if (postalcodenumber != null) alert("Postal Code Number: " + postalcodenumber);
    else alert("Postal Code Number Unknown");
  }
);

Full Example for v1.0.5

FAQ

What is the license for the GReverseGeocoder API?

The API is based upon the Google Maps API, and uses both GClientGeocoder as GDirections. Therefore the usage of the GReverseGeocder is bound to the Google Maps API Terms of Use and Terms of Service for Google Maps. The API itself is licensed under Apache License Version 2.0

What countries is reverse geocoding available in?

The table below lists googles geocode and direction capabilities for each country. The third colom shows if reverse geocoding is available. (x=available, n=not available, p=probably available but not tested) Some other countries do work by they are not officialy supported by google.(e.g. Mexico) You are always free to try the above example on your country, and see if it returns something.

CountryGClientGeocoderGDirectionsGReverseGeocoder
Austria x x p
Australia x x p
Belgium x x x
Brazil x x x
Canada x x p
The Czech Republic x x p
Denmark x x p
Finland x x p
France x x x
Germany x x x
Hong Kong x n n
Hungary x x p
India x n n
Ireland x x p
Italy x x x
Japan x n n
Luxembourg x x x
The Netherlands x x x
New Zealand x x x
Norway x x p
Poland x x p
Portugal x x p
Singapore x x p
Spain x x p
Sweden x x p
Switzerland x x x
Taiwan x n n
Thailand x x p
the United Kingdom x x x
the United States x x x

Can I use the reverse geocoding server side, e.g. with a php script or in Java?

Short answer: No.

However, it is technically possible to port the greversegeocoder code into anny language supporting the HTTP protocol including PhP, Java and others. The reverse geocoder is layered on top of the Google's GClientGeocoder API which has an official HTTP interface, see "Geocoding via HTTP" and Google's GDirection API which does NOT have an official interface, therefore it can technically be queried through HTTP, but is leagally forbidden, since the Google's terms of use explicitly forbid data access in other ways than the provided API's, in this case the javascript API, if this would be to change, I'd gladly make a Java version.

Why does the api does not work on a local server?(e.g. "http://localhost/simple.html")

Each Google Map API key used to be valid for exactly one url. So you had to sign up for a key vaild for the url "http://localhost/". Later they changed the policy so that "file://" and "http://localhost/" could be used with any key. For "file://" urls the GDirections class can be used with any key. Unfortunately for "http://localhost" urls you need to sign up for a localhost key in order to make the GDirections class work. The GReverseGeocoder builds upon the GDirections class so it shares this behavour.

"file://" urls are used to open html files form the hard disk. In your browser choose "open file" and select your html file
"http://localhost/" urls are used when you are running a webserver on the same machine as your browser.

How does GReverseGeocoder compares with GeoNames findNearbyAddressJSON service?

They offer the same service and the resulting data is much alike, but structured in a different way. The GeoNames service is only available in the US, while the GReverseGeocoder is supported in more countries. If you only need a nearby postal code, town/city or country GeoNames has other services available in other countries as well. The GeoNames service is a bit faster but the real advantage is that they offer a web service interface.

You can compare the results here: Compare Example

Change Log

API v1.0.8

  • now include "http://nicogoeminne.googlepages.com/greversegeocoderv108.js" in your script tag
  • The bounding box used for the GClientGeocoder.setViewport method was too narrowly choosen. The new default value is 0.1 instead of 0.01 degrees. This can be set by changing the GReverseGeocoder.bounds value, before doing a request.
  • Added the last requested GLatLng coordinate in the error event handler :
    GEvent.addListener(reversegeocoder, "error", function (lastpoint) {
           map.addOverlay(new GMarker(lastpoint, {title:"Unknown street address"}));
    });
  • Example using the new implementation full.

API v1.0.7

  • now include "http://nicogoeminne.googlepages.com/greversegeocoderv107.js" in your script tag
  • Removed extracting street name form html description, instead it uses the GDirection.getGeocode method.
  • Example using the new implementation full.

API v1.0.6

  • now include "http://nicogoeminne.googlepages.com/greversegeocoderv106.js" in your script tag
  • Bug fix for house number support. The US uses "nr" "streetname" while in Belguim it is "streetname" "nr"
  • Example Comparing Geonames and GReverseGeocoder Compare.

API v1.0.5

  • now include "http://nicogoeminne.googlepages.com/greversegeocoderv105.js" in your script tag
  • Bug fix for numbered roads. (See v1.04)
  • Added a help function for obtaining placemark properties : getPlacemarkProperty
  • Test the new capabilities in the Full Example for v1.0.5.

API v1.0.4

  • now include "http://nicogoeminne.googlepages.com/greversegeocoderv104.js" in your script tag
  • Returns the acctual road name in the UK (and possibly others) instead of the Great Britain road numbering scheme
  • The returned post code is now related to the acutal request
  • Test the new capabilities in the Full Example for v1.0.4.

API v1.0.3

  • now include "http://nicogoeminne.googlepages.com/greversegeocoderv103.js" in your script tag
  • When using the house number support there is more accuracy information
  • Result now includes the request point.
  • Result now includes the closest point on the road.
  • Result now includes the closest point on the road that is an address.
  • Result now includes the Distance (between request and result).
  • Result now includes the Distance On Road (between road point and result).
  • Experiment with these new features in the example below.

API v1.0.2

  • now include "http://nicogoeminne.googlepages.com/greversegeocoderv102.js" in your script tag
  • Removed the setBaseCountry method.
  • Now there's experimental house number support. See below

API v1.0.1

  • Include "http://nicogoeminne.googlepages.com/greversegeocoderv102.js" in your script tag