Extending acts_as_geocodable

After writing my review of acts_as_geocodable/graticule earlier in the week, I decided to go searching for geocoding services that might offer data for addresses outside of North America. One that I came across is at Local Search Maps. There’s an introductory blog entry here.

The API is a little different in that it returns its data as javascript strings, but otherwise it’s simple enough to send a GET for a given address and get back the data. To see how easy it is, I decided to code up an extra geocoder for graticule that would use this service.

The main change I had to make was to allow for extra arguments to the locate method. For the geocoders distributed with the gem there’s just one argument: the address. For this service to retrieve data outside the USA it requires more structured data, so I added an optional argument for the locate method and built my query based on its existence. The code turned out to be very simple:

require 'graticule'
module Graticule

  # A library for lookup of coordinates with http://geo.localsearchmaps.com/
  class LocalSearchMapsGeocoder  address
      else
        get args.merge(:street => address)
      end
    end

    def check_error(js)
      raise AddressError, "Empty Response" if js.nil? or js.text.nil?
      raise AddressError, js.text.match(/alert\('(.+)'\)/)[1] if js.text == "alert('location not found');"
    end

    def parse_response(js)
      location = Location.new
      coords = js.text.match(/map.centerAndZoom\(new GPoint\((.+?), (.+?)\)/)
      location.longitude = coords[1]
      location.latitude = coords[2]
      location
    end
  end

end

So now I can use graticule and specify an address such as:

g = Graticule::LocalSearchMapsGeocoder.new
location = g.locate '14, Avenue Claude Vellefaux',
	:zip => '75010', :city => 'Paris', :country => 'France'

and find out that that address is at latitude 48.873016, longitude 2.369934. Unfortunately it is still quite a limited service; when I threw in some addresses in China, Malaysia and even New Zealand I got Graticule::AddressError exceptions. But such is the current state of geocoding, and getting some of Western Europe on top of North America is progress.

Another extension for graticule that might be nice would be a way to specify countries that a geocoder does/doesn’t support. That way the gem could intelligently choose a geocoder that will work out for the specified address.

Update (March 21st): This code is now included in the latest release of the graticule gem.

Tags: , , , ,

Comments are closed.