ruby, geonames and photography
Recently I've been working on some ruby code that serves up the photography content of my website as a ruby object (no, it's not available for download anywhere, it wouldn't be any use to anyone else). The point behind it is that it lets me query my photographs in all sorts of different ways (especially handy when working in irb as it means I've got a kind of REPL for working with my photographs) and also makes it easy to write programs that generate useful data.
Last night I got to thinking that it would be interesting to use this code to try and "reverse geocode" the ICBM address that every album has so that I could display the nearest centre of population to the album.
After a bit of searching on the net I found GeoNames. A handy enough site itself but even more handy because it has an API and a list of client libraries that are available. Handily there's a library for ruby.
A little bit of hacking later and I had this:Put simply: it gets a list of the unique locations that I've recorded and runs through them getting the nearest known location. I then use the resulting data on my site to display the name of the nearest location to where the album is from.#!/usr/bin/env ruby
require 'geonames'
require 'photography'
include Photography
include Geonames
# Get place names for all the icbm locations
Albums.new.load.collect {|album|
[ album.latitude, album.longitude ]
}.uniq.each {|icbm|
near = WebService.find_nearby_place_name( icbm[ 0 ], icbm[ 1 ] )
puts( "#{icbm[ 0 ]}\t" +
"#{icbm[ 1 ]}\t" +
"#{near[ 0 ].name}\t" +
"#{near[ 0 ].country_name}\t" +
"#{near[ 0 ].distance}" )
}
It isn't perfect. For example, most of the photographs I've shot in and around Billingborough end up being shown as being near Horbling (the next village north of here, and somewhat smaller than Billingborough). Still, it's a start.
Currently I've got the text linking to a search on nearby.org.uk. Via that there's some fascinating (for varying values of fascinating) links to further searches that can be done based on location.
