Geocoding in Ruby
November 21st, 2007 cpetersen
The Geocode Module
Have you ever needed to turn a partial address into a full one? Have you ever wanted to get the latitude or longitude for a particular address? Maybe you want to plot addresses on a Google Map, or maybe, like a colleague of mine, you find it redundant to ask for city, state AND zip when creating a form. If any of these apply to you, you might be interested in geocoding.
Geocoding is the process of turning an address (or in some cases a partial address) into latitude and longitude. Often times during the process you get more information about the address. For instance if you geocode "1000 5th Ave, 92101", not only with you get the latitude and longitude (32.715714, -117.160158), you also find out that it's in San Diego, CA.
There are many services out there that will geocode addresses for you. For instance the Cartographer plugin provides a couple of nice Geocoding modules. One for Geocoder.us and one for Ontok. Both are great alternatives for geocoding. However, I wanted to use Google, and I didn't want to use the full Cartographer plugin. So I wrote the following module that allows you to geocode addresses in Ruby using Google's service.1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
module Geocode def geocode(input) uri = "/maps/geo?q=#{input.gsub(/\s/, "%20")}&output=xml&key=<your google map's key>" res = Net::HTTP.start("maps.google.com") {|http| http.get(uri) } begin doc = REXML::Document.new(res.body) if doc && doc.root coordinateNode = doc.root.get_elements("//coordinates").first addressNode = doc.root.get_elements("//ThoroughfareName").first stateNode = doc.root.get_elements("//AdministrativeAreaName").first cityNode = doc.root.get_elements("//SubAdministrativeAreaName").first cityNode = doc.root.get_elements("//LocalityName").first unless cityNode zipcodeNode = doc.root.get_elements("//PostalCodeNumber").first longitude,latitude = coordinateNode.text.split(",") if coordinateNode address = addressNode.text if addressNode state = stateNode.text if stateNode city = cityNode.text if cityNode zipcode = zipcodeNode.text if zipcodeNode return { :latitude => latitude.to_f, :longitude => longitude.to_f, :description => nil, :original_address => input, :score => nil, :street_number => nil, :prefix => nil, :street_name => nil, :street_type => nil, :suffix => nil, :address1 => address, :city => city, :state => state, :zipcode => zipcode } end rescue # Do something useful... end # if nothing has returned yet, then return nil return nil end end |
You'll notice a few returned items that are always nil, that's because it is a drop in replacement for the Geocoding modules in Cartographer. So even if you use the Cartographer plugin, you can still use this module.
Using the Geocode Module
To use the Geocode module, simply include it, and pass it an address or partial address.
1 2 3 4 |
include Geocode result = geocode("92121") puts "#{result[:address1]}, #{result[:city]}, #{result[:state]}, #{result[:zipcode]}" puts "#{result[:latitude]}, #{result[:longitude]}" |



November 21st, 2007 at 09:27 PM [...] here to [...]
November 26th, 2007 at 02:15 AM assay depot: development blog » Blog Archive » Geocoding in Ruby... assay depot: development blog » Blog Archive » Geocoding in Ruby...
November 26th, 2007 at 05:24 AM [...] Geocoding in Ruby (tags: ruby module) [...]
November 26th, 2007 at 11:13 AM [...] Geocoding in Ruby [...]
November 29th, 2007 at 10:31 AM [...] decided that a more direct approach of querying Google for the results was necessary. The result is a 49 line module that can return latitude, longitude, address, street, and other geographical inform... when provided with, say, a ZIP or a street [...]
November 29th, 2007 at 03:06 PM [...] shin31 wrote an interesting post today onHere’s a quick excerpt [...]
November 30th, 2007 at 12:59 AM Just out of curiosity, why not just use Graticule?
November 30th, 2007 at 02:39 AM Brandon, Thanks for the link, it looks like an excellent library. The short and perfectly honest/blunt answer to your question... I didn't see it before I wrote this module. Still, I hope people find this module helpful. Thanks for posting! Chris
June 4th, 2008 at 03:27 PM Thank u .. Instead we have another way to get longitude and latitude of given address #server = XMLRPC::Client.new2('http://rpc.geocoder.us/service/xmlrpc') # result = server.call2('geocode', address) # return {:success=> true, :latitude=> result[1][0]['lat'], :longitude=> result[1][0]['long']}