home about

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]}"

9 Responses to “Geocoding in Ruby”

  1. in47 &raquo; Blog Archive &raquo; Geocoding in Ruby Says:
    [...] here to [...]
  2. roScripts &#45; Webmaster resources and websites Says:
    assay depot: development blog » Blog Archive » Geocoding in Ruby... assay depot: development blog » Blog Archive » Geocoding in Ruby...
  3. links for 2007-11-26 - Cyberpunk???? Says:
    [...] Geocoding in Ruby (tags: ruby module) [...]
  4. &raquo; The Links &raquo; roarin&#8217; reporter Says:
    [...] Geocoding in Ruby [...]
  5. Interesting Ruby Tidbits That Don't Need Separate Posts #11 Says:
    [...] 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 [...]
  6. assay depot: development blog » Blog Archive » Geocoding in Ruby Says:
    [...] shin31 wrote an interesting post today onHere’s a quick excerpt [...]
  7. Brandon Keepers Says:
    Just out of curiosity, why not just use Graticule?
  8. Christopher L Petersen Says:
    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
  9. Ch.SrinivasReddy Says:
    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']}

Leave a Reply