UK Geocoding with Google and Graticule
At long last, there’s a good, free geocoding service for the UK. Finding coordinates based on post code and/or address data has long been a free service in many countries. But in the UK, the Royal Mail’s control of post code data – coupled with the ever-changing nature of that data – has meant geocoding has been difficult or expensive. Services like Postcode Anywhere and iShareMaps have provided equivalents to Google’s geocoder, but for a fee. That changed in early July 2007, when Google released geocoding for the UK.
If you’re a Ruby programmer and you’ve been doing geocoding, it’s possible you’ve been using a gem called Graticule. This gem makes light work of plugging into various geocoding services and performing distance calculations.
Graticule includes a couple of classes for UK geocoding, one based on Postcode Anywhere and one based on Local Search Maps. The first requires a Postcode Anywhere account, which is not free. The second is free, but in my experience, not very reliable.
Neither matter anymore, though, since you can now just use the Google geocoder. This post explains how to use Graticule to take advantage of Google’s new UK geocoding service.
I’m assuming you have a Google Maps API key, and that you have the Graticule gem installed. (If you don’t have Graticule, it’s just “gem install graticule”.)
In the simplest case, using the UK geocoding service is easy right out of the box. Just pass the address data to the standard Graticule Google service, and you’re there:
require 'rubygems'
require 'graticule'
> g = Graticule.service(:google).new GMAP_API_KEY
#=> #<Graticule::Geocoder::Google:0xb73959f0 @key="xxxxxxxxxx",
@url=#<URI::HTTP:0xfdb9cabfe URL:http://maps.google.com/maps/geo>>
> g.locate "NW1 8BX"
#=> #<Graticule::Location:0xb7367064 @longitude=-0.145855,
@region="England", @precision=:zip, @latitude=51.542272,
@locality="London", @country="GB", @street=nil, @postal_code="NW1 8BX">As you can see, the service correctly found the location in the UK.
But sometimes you don’t have such complete data. You might be using a partial post code, or a street address and no post code. In those cases, the service might find a location in the wrong country—the US, Canada, or Australia, for instance.
The easiest way to avoid that problem is to use the UK-specific geocoding service URL. Graticule’s Google geocoding class sets its URL to maps.google.com/maps/geo. What we want is maps.google.co.uk/maps/geo.
When you call the method Graticule.service, it returns a geocoder class based on the symbol argument you pass in. If you pass in :google, it returns the Graticule::Geocoder::Google class. You could just as easily call Graticule::Geocoder::Google.new. In either case, the way to get a UK-oriented geocoder is to make a new class that inherits from Graticule::Geocoder::Google, since the UK geocoding service is identical to the international one with the exception of the URL.
In fact, the only method you need to write in the new class is the initialize method, which sets the URL. Below is the code for the new class.
require 'rubygems'
require 'graticule'
module Graticule
module Geocoder
class GoogleUk < Graticule::Geocoder::Google
def initialize(*args)
super
@url = URI.parse("http://maps.google.co.uk/maps/geo")
end
end
end
endPut this code in the file “google_uk.rb”, in the directory graticule/geocoder somewhere in Ruby’s include path. For instance, if you’re using Rails, you can put it in lib/graticule/geocoder.
Now you should be able to use the new UK-oriented geocoder as follows:
> g = Graticule.service(:google_uk).new GMAP_API_KEY
#=> #<Graticule::Geocoder::GoogleUk:0xb734bcb0 @key="xxxxxxxxxx",
@url=#<URI::HTTP:0xfdb9a4b3e URL:http://maps.google.co.uk/maps/geo>>
> g.locate "NW1 8BX"
#=> #<Graticule::Location:0xb7367064 @longitude=-0.145855,
@region="England", @precision=:zip, @latitude=51.542272,
@locality="London", @country="GB", @street=nil, @postal_code="NW1 8BX">The UK geocoder works best if you pass it a string containing a complete postcode, or a street address (no apartment number or anything else) plus a partial post code. Eg, “AB1 3CD”, or “10 Whatever Street, AB1”.
A good way to learn more about the Graticule gem is to explore the RDoc documentation and visit the Graticule web site.