|
@@ -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 |
|
|