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.
Ruby is better than PHP
Lots of web developers use PHP. It’s an open source programming language and one of the most popular for making web sites. We don’t use it, though. We use Ruby.
This is not an arbitrary choice, like preferring purple to green. We use Ruby because it’s better. That’s what we tell our clients when they ask why we use Ruby. The next question is usually, “What makes it better?”
It’s pretty hard to answer that question directly, because the reasons are all highly technical. Instead, we say something such as, “Ruby is like well-crafted writing.” Or, “It’s just better designed.” Both of them are true. But how do you know we’re right, and not just expressing our opinion? Mightn’t other people think that PHP is a better language than Ruby?
Actually, probably not. What you’ll find is that people who’ve learned Ruby and also PHP nearly all think Ruby is better. People who know PHP but not Ruby, or PHP and a little Ruby, might tell you that the two languages are equivalent.
When talking about any two programming languages used for the same purpose – call them X and Y – you’ll find one of two things. 1: everyone will agree that X and Y are equivalent; or, 2: some people will say X is better than Y, and some people will say X and Y are equivalent.
What you almost never find is some people saying “X is better than Y”, and some saying “Y is better than X”. Why not? The reason is that X really is better than Y – it’s a fact – but you have to know how to program in X pretty well before you realise it.
The people who say X and Y are equivalent are Y programmers who can’t understand the more advanced features of X. To them, X just looks like another version of Y, with a bunch of other random stuff tacked on. They don’t say “Y is better than X”, because they can at least see that X can do everything Y can do. What they can’t see is what X can do that their language can’t.
So if you find experienced Ruby programmers saying “Ruby is better than PHP”, and PHP programmers saying “Ruby and PHP are equivalent”, believe the Ruby guys.