Geocoder
Geocoder is a complete geocoding solution for Ruby. With Rails it adds geocoding (by street or IP address), reverse geocoding (find street address based on given coordinates), and distance queries. It's as simple as calling geocode
on your objects, and then using a scope like Venue.near("Billings, MT")
.
Compatibility
- Supports multiple Ruby versions: Ruby 1.9.2, 1.9.3, 2.0.0, 2.1.0, JRuby and Rubinius.
- Supports multiple databases: MySQL, PostgreSQL, SQLite, and MongoDB (1.7.0 and higher).
- Supports Rails 3 and 4. If you need to use it with Rails 2 please see the
rails2
branch (no longer maintained, limited feature set). - Works very well outside of Rails, you just need to install either the
json
(for MRI) orjson_pure
(for JRuby) gem.
Rails 4.1 Note
Due to a change in ActiveRecord's count
method you will need to use count(:all)
to explicitly count all columns ("*") when using a near
scope. Using near
and calling count
with no argument will cause exceptions in many cases.
Installation
Install Geocoder like any other Ruby gem:
gem install geocoder
Or, if you're using Rails/Bundler, add this to your Gemfile:
gem "geocoder"
and run at the command prompt:
bundle install
Object Geocoding
ActiveRecord
Your model must have two attributes (database columns) for storing latitude and longitude coordinates. By default they should be called latitude
and longitude
but this can be changed (see "Model Configuration" below):
rails generate migration AddLatitudeAndLongitudeToModel latitude:float longitude:float
rake db:migrate
For reverse geocoding your model must provide a method that returns an address. This can be a single attribute, but it can also be a method that returns a string assembled from different attributes (eg: city
, state
, and country
).
Next, your model must tell Geocoder which method returns your object's geocodable address:
geocoded_by :full_street_address # can also be an IP address
after_validation :geocode # auto-fetch coordinates
For reverse geocoding, tell Geocoder which attributes store latitude and longitude:
reverse_geocoded_by :latitude, :longitude
after_validation :reverse_geocode # auto-fetch address
Mongoid
First, your model must have an array field for storing coordinates:
field :coordinates, :type => Array
You may also want an address field, like this:
field :address
but if you store address components (city, state, country, etc) in separate fields you can instead define a method called address
that combines them into a single string which will be used to query the geocoding service.
Once your fields are defined, include the Geocoder::Model::Mongoid
module and then call geocoded_by
:
include Geocoder::Model::Mongoid
geocoded_by :address # can also be an IP address
after_validation :geocode # auto-fetch coordinates
Reverse geocoding is similar:
include Geocoder::Model::Mongoid
reverse_geocoded_by :coordinates
after_validation :reverse_geocode # auto-fetch address
Once you've set up your model you'll need to create the necessary spatial indices in your database:
rake db:mongoid:create_indexes
Be sure to read Latitude/Longitude Order in the Notes on MongoDB section below on how to properly retrieve latitude/longitude coordinates from your objects.
MongoMapper
MongoMapper is very similar to Mongoid, just be sure to include Geocoder::Model::MongoMapper
.
Mongo Indices
By default, the methods geocoded_by
and reverse_geocoded_by
create a geospatial index. You can avoid index creation with the :skip_index option
, for example:
include Geocoder::Model::Mongoid
geocoded_by :address, :skip_index => true