Find Records with X Miles of a known point in rails
I have a table containing a number of records with their long / lat coordinates. I'm trying to do the common "Show all within X miles" type search where my point of origin is the user's current long / lat pulled using geolocation in the browser.
Does anyone know an efficient away to calculate the distance between my point of origin and the various potential destinations without retrieving all of them from the database and looping through them to calculate the distance? That seems like itll be really inefficient as we get more and more records in the potential destination table.
If there's a ruby/rails orient solution awesome, otherwise any suggestions would be appreciated.开发者_如何学C
If you database supports spatial data, by all means use that. I like geokit but I needed to query based upon spatial data not select all and filter through GIS. We are running SQL Server 2005, which does not support spatial data (2008 does). This is what I had to do:
def self.within_distance(miles, from_longitude, from_latitude)
self.scoped(:conditions => ["((DEGREES(ACOS(SIN(RADIANS(:from_latitude)) *
SIN(RADIANS(latitude)) +
COS(RADIANS(:from_latitude)) *
COS(RADIANS(latitude)) *
COS(RADIANS(:from_longitude - longitude))))) * 69.09) < :miles",
{:from_longitude => from_longitude, :from_latitude => from_latitude, :miles => miles}])
end
I hope you are able to be spared the pain of putting this or something like it in, but so far it has worked like a charm.
check out the Thinking sphinx search plugin for rails: http://freelancing-god.github.com/ts/en/geosearching.html
You should look at the spatial extensions for your database of choice, Postres and Mysql both support these extensions.
You could then look at some of the gems available to add GIS support to Rails. Geokit is one example.
If your database doesn't support spatial data, one straightforward possibility to optimize the search would be to compute a table with "grid square" coordinates - set an arbitrary grid resolution of, say, 10 miles, figure out which grid square each record is in, and store that information. Then the query can say something like "where grid_x >= 5 and grid_x <= 7 and grid_y >= 13 and grid_y <= 15" to have the server do a coarse filtering, then compute actual distances on the client side.
精彩评论