forked from openaustralia/planningalerts
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Use geocoder gem for doing the distance based database searches
Still using geokit gem for doing the actual geocoding as that should hopefully still work under Rails 3. However, the geocoder gem currently has a bug where the calculated distance is always returned in miles even when the search units are set to kilometres. For the time being doing the conversions back to km inline.
- Loading branch information
Showing
21 changed files
with
880 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
README.rdoc | ||
lib/**/*.rb | ||
bin/* | ||
features/**/*.feature | ||
LICENSE |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
= Changelog | ||
|
||
Per-release changes to Geocoder. | ||
|
||
== 0.9.5 (TBA) | ||
|
||
* Fix broken PostgreSQL compatibility (now 100% compatible). | ||
* Switch from Google's XML to JSON geocoding API. | ||
* Separate Rails 2 and Rails 3-compatible branches. | ||
* Don't allow :conditions hash in 'options' argument to 'nearbys' method (was deprecated in 0.9.3). | ||
|
||
== 0.9.4 (2010 Aug 2) | ||
|
||
* Google Maps API key no longer required (uses geocoder v3). | ||
|
||
== 0.9.3 (2010 Aug 2) | ||
|
||
* Fix incompatibility with Rails 3 RC 1. | ||
* Deprecate 'options' argument to 'nearbys' method. | ||
* Allow inclusion of 'nearbys' in Arel method chains. | ||
|
||
== 0.9.2 (2010 Jun 3) | ||
|
||
* Fix LIMIT clause bug in PostgreSQL (reported by kenzie). | ||
|
||
== 0.9.1 (2010 May 4) | ||
|
||
* Use scope instead of named_scope in Rails 3. | ||
|
||
== 0.9.0 (2010 Apr 2) | ||
|
||
* Fix bug in PostgreSQL support (caused "PGError: ERROR: column "distance" does not exist"), reported by developish. | ||
|
||
== 0.8.9 (2010 Feb 11) | ||
|
||
* Add Rails 3 compatibility. | ||
* Avoid querying Google when query would be an empty string. | ||
|
||
== 0.8.8 (2009 Dec 7) | ||
|
||
* Automatically select a less accurate but compatible distance algorithm when SQLite database detected (fixes SQLite incompatibility). | ||
|
||
== 0.8.7 (2009 Nov 4) | ||
|
||
* Added Geocoder.geographic_center method. | ||
* Replaced _get_coordinates class method with read_coordinates instance method. | ||
|
||
== 0.8.6 (2009 Oct 27) | ||
|
||
* The fetch_coordinates method now assigns coordinates to attributes (behaves like fetch_coordinates! used to) and fetch_coordinates! both assigns and saves the attributes. | ||
* Added geocode:all rake task. | ||
|
||
== 0.8.5 (2009 Oct 26) | ||
|
||
* Avoid calling deprecated method from within Geocoder itself. | ||
|
||
== 0.8.4 (2009 Oct 23) | ||
|
||
* Deprecate <tt>find_near</tt> class method in favor of +near+ named scope. | ||
|
||
== 0.8.3 (2009 Oct 23) | ||
|
||
* Update Google URL query string parameter to reflect recent changes in Google's API. | ||
|
||
== 0.8.2 (2009 Oct 12) | ||
|
||
* Allow a model's geocoder search string method to be something other than an ActiveRecord attribute. | ||
* Clean up documentation. | ||
|
||
== 0.8.1 (2009 Oct 8) | ||
|
||
* Extract XML-fetching code from Geocoder.search and place in Geocoder._fetch_xml (for ease of mocking). | ||
* Add tests for coordinate-fetching instance methods. | ||
|
||
== 0.8.0 (2009 Oct 1) | ||
|
||
First release. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
Copyright (c) 2009-10 Alex Reisner | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining | ||
a copy of this software and associated documentation files (the | ||
"Software"), to deal in the Software without restriction, including | ||
without limitation the rights to use, copy, modify, merge, publish, | ||
distribute, sublicense, and/or sell copies of the Software, and to | ||
permit persons to whom the Software is furnished to do so, subject to | ||
the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be | ||
included in all copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | ||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
= 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 scope like <tt>Venue.near("Billings, MT")</tt>. Since it does not rely on proprietary database functions finding geocoded objects in a given area works with out-of-the-box MySQL or even SQLite. | ||
|
||
Geocoder is currently compatible with Rails 2.x and 3.x. <b>This is the README for the 2.x branch.</b> Please see the 3.x branch for the lastest installation instructions, documentation, and issues. | ||
|
||
|
||
== 1. Install | ||
|
||
Install as a plugin: | ||
|
||
script/plugin install git://github.com/alexreisner/geocoder.git -r rails2 | ||
|
||
|
||
== 2. Configure | ||
|
||
A) Add +latitude+ and +longitude+ columns to your model: | ||
|
||
script/generate migration AddLatitudeAndLongitudeToYourModel latitude:float longitude:float | ||
rake db:migrate | ||
|
||
B) Tell geocoder where your model stores its address: | ||
|
||
geocoded_by :address | ||
|
||
C) 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 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 objects or points | ||
Geocoder.geographic_center([ city1, city2, city3, [40.22,-73.99], city4 ]) | ||
|
||
|
||
== 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). | ||
|
||
|
||
== SQLite | ||
|
||
SQLite's lack of trigonometric functions requires an alternate implementation of the +near+ method (scope). When using SQLite, Geocoder will automatically use a less accurate algorithm for finding objects near a given point. Results of this algorithm should not be trusted too much as it will return objects that are outside the given radius. | ||
|
||
It is also not possible to calculate distances between points without the trig functions so you cannot sort results by "nearness." | ||
|
||
|
||
=== Discussion | ||
|
||
There are few options for finding objects near a given point in SQLite without installing extensions: | ||
|
||
1. Use a square instead of a circle for finding nearby points. For example, if you want to find points near 40.71, 100.23, search for objects with latitude between 39.71 and 41.71 and longitude between 99.23 and 101.23. One degree of latitude or longitude is at most 69 miles so divide your radius (in miles) by 69.0 to get the amount to add and subtract from your center coordinates to get the upper and lower bounds. The results will not be very accurate (you'll get points outside the desired radius--at worst 29% farther away), but you will get all the points within the required radius. | ||
|
||
2. Load all objects into memory and compute distances between them using the <tt>Geocoder.distance_between</tt> method. This will produce accurate results but will be very slow (and use a lot of memory) if you have a lot of objects in your database. | ||
|
||
3. If you have a large number of objects (so you can't use approach #2) and you need accurate results (better than approach #1 will give), you can use a combination of the two. Get all the objects within a square around your center point, and then eliminate the ones that are too far away using <tt>Geocoder.distance_between</tt>. | ||
|
||
Because Geocoder needs to provide this functionality as a scope, we must go with option #1, but feel free to implement #2 or #3 if you need more accuracy. | ||
|
||
|
||
== Known Issue | ||
|
||
You cannot use the +near+ scope with another scope that provides an +includes+ option because the +SELECT+ clause generated by +near+ will overwrite it (or vice versa). Instead, try using +joins+ and pass a <tt>:select</tt> option to the +near+ scope to get the columns you want. For example, in Rails 2 syntax: | ||
|
||
# instead of :includes => :venues: | ||
City.near("Omaha, NE", 20, :select => "venues.*").all(:joins => :venues) | ||
|
||
If anyone has a more elegant solution to this problem I am very interested in seeing it. | ||
|
||
|
||
Copyright (c) 2009-10 Alex Reisner, released under the MIT license |
Oops, something went wrong.