| @@ -3,11 +3,12 @@ class Post < ActiveRecord::Base | |||||
| EARTH_RADIUS_METRES = 6378000 | EARTH_RADIUS_METRES = 6378000 | ||||
| def self.near(lat, lon, radius_metres) | |||||
| def self.near(lat, lon, radius_metres, layer_id) | |||||
| # Santize inputs. Is this necessary? | # Santize inputs. Is this necessary? | ||||
| lat = lat.to_f | lat = lat.to_f | ||||
| lon = lon.to_f | lon = lon.to_f | ||||
| radius_metres = radius_metres.to_i | radius_metres = radius_metres.to_i | ||||
| layer_id = layer_id.to_i | |||||
| # Calculate distance using the Haversine formula | # Calculate distance using the Haversine formula | ||||
| self.find_by_sql(<<-ENDQUERY | self.find_by_sql(<<-ENDQUERY | ||||
| @@ -34,13 +35,31 @@ class Post < ActiveRecord::Base | |||||
| ON p.feed_id = f.id | ON p.feed_id = f.id | ||||
| WHERE | WHERE | ||||
| ( #{EARTH_RADIUS_METRES} | |||||
| * acos( cos( radians('#{lat}') ) | |||||
| * cos( radians( p.lat ) ) | |||||
| * cos( radians( p.lon ) | |||||
| - radians('#{lon}') ) | |||||
| + sin( radians('#{lat}') ) | |||||
| * sin( radians( p.lat ) ) ) ) | |||||
| p.id IN | |||||
| ( -- Subquery returns a list of post_ids for posts on this layer | |||||
| SELECT p.id | |||||
| FROM feeds_layers fl | |||||
| INNER JOIN feeds f | |||||
| ON fl.feed_id = f.id | |||||
| INNER JOIN posts p | |||||
| ON p.feed_id = f.id | |||||
| WHERE fl.layer_id = #{layer_id} | |||||
| ) | |||||
| AND | |||||
| ( | |||||
| #{EARTH_RADIUS_METRES} | |||||
| * acos( cos( radians('#{lat}') ) | |||||
| * cos( radians( p.lat ) ) | |||||
| * cos( radians( p.lon ) | |||||
| - radians('#{lon}') ) | |||||
| + sin( radians('#{lat}') ) | |||||
| * sin( radians( p.lat ) ) ) | |||||
| ) | |||||
| <= #{radius_metres} | <= #{radius_metres} | ||||
| ORDER BY distance | ORDER BY distance | ||||