= Geocoder Geocoder adds object geocoding and database-agnostic distance calculations to Ruby on Rails. It's as simple as calling <tt>fetch_coordinates!</tt> on your objects, and then using a named scope like <tt>Venue.near("Billings, MT")</tt>. Geocoder does not rely on proprietary database functions so finding geocoded objects in a given area is easily done using out-of-the-box MySQL or even SQLite. == 1. Install Install either as a plugin: script/plugin install git://github.com/alexreisner/geocoder.git or as a gem: # add to config/environment.rb: config.gem "rails-geocoder", :lib => "geocoder", :source => "http://gemcutter.org/" # at command prompt: sudo rake gems:install == 2. Configure A) Get a Google Maps API key (see http://code.google.com/apis/maps/signup.html) and store it in a constant: # eg, in config/initializers/google_maps.rb GOOGLE_MAPS_API_KEY = "..." B) Add +latitude+ and +longitude+ columns to your model: script/generate migration AddLatitudeAndLongitudeToYourModel latitude:float longitude:float rake db:migrate C) Tell geocoder where your model stores its address: geocoded_by :address D) Optionally, auto-fetch coordinates every time your model is saved: after_validation :fetch_coordinates <i>Note that you are not stuck with the +latitude+ and +longitude+ column names, or the +address+ method. See "More On Configuration" below for details.</i> == 3. Use Assuming +obj+ is an instance of a geocoded class, you can get its coordinates: obj.fetch_coordinates # fetches and assigns coordinates obj.fetch_coordinates! # also saves lat, lon attributes If you have a lot of objects you can use this Rake task to geocode them all: rake geocode:all CLASS=YourModel Once +obj+ is geocoded you can do things like this: obj.nearbys(30) # other objects within 30 miles obj.distance_to(40.714, -100.234) # distance to arbitrary point To find objects by location, use the following named scopes: Venue.near('Omaha, NE, US', 20) # venues within 20 miles of Omaha Venue.near([40.71, 100.23], 20) # venues within 20 miles of a point Venue.geocoded # venues with coordinates Venue.not_geocoded # venues without coordinates Some utility methods are also available: # distance (in miles) between Eiffel Tower and Empire State Building Geocoder.distance_between( 48.858205,2.294359, 40.748433,-73.985655 ) # look up coordinates of some location (like searching Google Maps) Geocoder.fetch_coordinates("25 Main St, Cooperstown, NY") # find the geographic center (aka center of gravity) of several points Geocoder.geographic_center([ [40.22,-73.99], [40.72,-73.98], [40.57,-74.61] ]) == More On Configuration You are not stuck with using the +latitude+ and +longitude+ database column names for storing coordinates. For example, to use +lat+ and +lon+: geocoded_by :address, :latitude => :lat, :longitude => :lon The string to use for geocoding can be anything you'd use to search Google Maps. For example, any of the following are acceptable: 714 Green St, Big Town, MO Eiffel Tower, Paris, FR Paris, TX, US If your model has +address+, +city+, +state+, and +country+ attributes you might do something like this: geocoded_by :location def location [address, city, state, country].compact.join(', ') end Please see the code for more methods and detailed information about arguments (eg, working with kilometers). == To-do List * <tt>install.rb</tt> should do some setup when installed as a plugin Copyright (c) 2009 Alex Reisner, released under the MIT license