More work on optimisation the location of nearby users - it turns out
that getting the database to do the filtering is much better as it avoids us constructing thousands of user objects only to then throw most of them away again.
This commit is contained in:
parent
857eeae8b2
commit
5de81dc4b0
2 changed files with 8 additions and 3 deletions
|
@ -98,9 +98,9 @@ class User < ActiveRecord::Base
|
|||
if self.home_lon and self.home_lat
|
||||
gc = OSM::GreatCircle.new(self.home_lat, self.home_lon)
|
||||
bounds = gc.bounds(radius)
|
||||
nearby = User.find(:all, :conditions => ["visible = ? and home_lat between #{bounds[:minlat]} and #{bounds[:maxlat]} and home_lon between #{bounds[:minlon]} and #{bounds[:maxlon]} and data_public = ? and id != #{self.id}", true, true])
|
||||
nearby = nearby.sort_by { |u| gc.distance(u.home_lat, u.home_lon) }.first(num)
|
||||
nearby.delete_if { |u| gc.distance(u.home_lat, u.home_lon) > radius }
|
||||
sql_for_distance = gc.sql_for_distance("home_lat", "home_lon")
|
||||
nearby = User.find(:all,
|
||||
:conditions => ["id != ? AND visible = ? AND data_public = ? AND #{sql_for_distance} <= ?", id, true, true, radius], :order => sql_for_distance, :limit => num)
|
||||
else
|
||||
nearby = []
|
||||
end
|
||||
|
|
|
@ -334,6 +334,11 @@ module OSM
|
|||
maxlon = (@lon + lonradius) * 180 / PI
|
||||
return { :minlat => minlat, :maxlat => maxlat, :minlon => minlon, :maxlon => maxlon }
|
||||
end
|
||||
|
||||
# get the SQL to use to calculate distance
|
||||
def sql_for_distance(lat_field, lon_field)
|
||||
"6372.795 * 2 * asin(sqrt(power(sin((radians(#{lat_field}) - #{@lat}) / 2), 2) + cos(#{@lat}) * cos(radians(#{lat_field})) * power(sin((radians(#{lon_field}) - #{@lon})/2), 2)))"
|
||||
end
|
||||
end
|
||||
|
||||
class GeoRSS
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue