1/20/08 update: 1.0.1 release: fixes for distance calculation (in-memory and database) when distances are either very small or 0. NOTE: older versions of MySQL/Postgres may not work. See readme for more info.
10/12/07 update: GeoKit is now Rails 2.0 / Edge friendly.
7/22/07 updates: GeoKit got some significant new features:
- auto geocoding: an option to automatically geocode a model's address field on create
- in-memory sort-by-distance for arrays of location objects
- bounding box queries:
Location.find :all, :bounds=>[sw,ne] - improved performance by automatically adding a bounding box condition to radial queries
- new Bounds class for in-memory bounds-related operations
- ability to calculate heading and midpoint between two points
- ability to calculate endpoint given a point, heading, and distance
There's more detail at my blog, and there is also an updated Readme.
What is GeoKit?
Geokit is a Rails plugin for building location-based apps. It provides geocoding, location finders, and distance calculation in one cohesive package. If you have any tables with latitude/longitude columns in your database, or if you every wanted to easily query for "all the stores within a 50 mile radius," then GeoKit is for you.
What can GeoKit do for you?
- Distance calculations between two points on the earth. Calculate the distance in miles or KM, with all the trigonometry abstracted away by GeoKit.
- ActiveRecord distance-based finders. For example, you can find all the points in your database within a 50-mile radius.
- Geocoding from multiple providers. It currently supports Google, Yahoo, Geocoder.us, and Geocoder.ca geocoders, and it provides a uniform response structure from all of them. It also provides a fail-over mechanism, in case your input fails to geocode in one service.
- IP-based location lookup utilizing hostip.info. Provide an IP address, and get city name and latitude/longitude in return.
- A before_filter helper to geocode the user's location based on IP address, and retain the location in a cookie.
Examples?
Find near latitude and longitude:
Store.find(:all, :origin =>[37.792,-122.393], :within=>10)
Find near an address:
Store.find(:all, :origin=>'100 Spear st, San Francisco, CA', :within=>10)
Order by distance from the center of a zipcode:
Store.find(:all, :origin=>'94117', :within=>10,
:order=>'distance asc')
Combine distance conditions with regular conditions
Store.find(:all, :origin=>'94117', :within=>10,
:conditions=>['shop_type = ?', 'CAFE'])
Geocode an address:
include GeoKit::Geocoders
res=MultiGeocoder.geocode('100 Spear st, San Francisco, CA')
puts res.ll # ll=latitude,longitude
Find distances, headings, endpoints, and midpoints:
distance=home.distance_from(work, :units=>:miles)
heading=home.heading_to(work) # result is in degrees, 0 is north
endpoint=home.endpoint(90,2) # two miles due east
midpoing=home.midpoint_to(work)
Test if a point is contained within bounds:
bounds=Bounds.new(sw_point,ne_point)
bounds.contains?(home)
Find within bounds:
bounds=Bounds.new(sw_point,ne_point)
Store.find :all, :bounds=>bounds
Find distance to a second location with on-the-fly geocoding:
s = Store.find(:first)
distance = s.distance_from('100 spear st, San Francisco, CA')
Where can you get it?
Install it as a plugin:
ruby script/plugin install svn://rubyforge.org/var/svn/geokit/trunk
windows users: having trouble installing? You might need to install svn for windows. See comments here
