Fri, 13 Jul 07

Web service to convert UK Postcodes (outcode) to Latitude and Longitude

Using the data supplied in this article, by Nik Sargent, I’ve created a simple web service that returns JSON formatted data about UK Outcodes (the first bit of the postcode).

The idea is that you can request, for example, /postcodes/se1 and get some json in return. For se1, we receive the following data.

{"latitude":"51.498","x":"532600","postcode":"SE1","y":"179500","longitude":"51.498"}

The service is currently running at http://seagul.co.uk/postcodes (se1) but I make no guarantees as to its reliability. I’d suggest that if anyone actually finds this useful that they go host it somewhere for themselves in order to control the availability.

The code is, as always, on google code and pasted below.

I’ve created it as a proof of concept but I figure that, given a little love, it may prove useful to some folks.

require 'rubygems'
require 'mongrel'
require 'json'

postcodes_file = File.dirname(__FILE__) + '/uk-postcodes.json'
Postcodes = JSON.parse(File.open(postcodes_file) { |f| f.read })
Index = Postcodes.inject([]) { |index, postcode| index << postcode['postcode'].downcase }

class PostcodeHandler < Mongrel::HttpHandler
  def process(request, response)
    outcode = request.params['PATH_INFO'].sub(/^\//, '').downcase
    postcode_index = Index.index(outcode)
    if postcode_index
      response.start do |head, out|
        head["Content-Type"] = "text/plain"
        out << Postcodes[postcode_index].to_json
      end
    else
      response.start(404) do |head,out|
        out << "Postcode not found\n"
      end
    end
  end
end

config = Mongrel::Configurator.new :host => 'localhost', :port => '4000' do
  listener do
    uri "/postcodes", :handler => PostcodeHandler.new
  end
  trap("INT") { stop }
  run
end

config.join