GeoRSS aggregator and Layar augmented reality server
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 
 
 

71 lignes
1.6 KiB

  1. class Post < ActiveRecord::Base
  2. belongs_to :feed
  3. EARTH_RADIUS_METRES = 6378000
  4. def self.near(lat, lon, radius_metres, layer_id)
  5. # Santize inputs. Is this necessary?
  6. lat = lat.to_f
  7. lon = lon.to_f
  8. radius_metres = radius_metres.to_i
  9. layer_id = layer_id.to_i
  10. # Calculate distance using the Haversine formula
  11. self.find_by_sql(<<-ENDQUERY
  12. SELECT
  13. p.id,
  14. p.title,
  15. p.summary,
  16. p.url,
  17. p.lat,
  18. p.lon,
  19. p.published,
  20. f.title as feed_title,
  21. ( #{EARTH_RADIUS_METRES}
  22. * acos( cos( radians('#{lat}') )
  23. * cos( radians( p.lat ) )
  24. * cos( radians( p.lon )
  25. - radians('#{lon}') )
  26. + sin( radians('#{lat}') )
  27. * sin( radians( p.lat ) ) ) )
  28. As distance
  29. FROM posts p
  30. INNER JOIN feeds f
  31. ON p.feed_id = f.id
  32. WHERE
  33. p.id IN
  34. ( -- Subquery returns a list of post_ids for posts on this layer
  35. SELECT p.id
  36. FROM feeds_layers fl
  37. INNER JOIN feeds f
  38. ON fl.feed_id = f.id
  39. INNER JOIN posts p
  40. ON p.feed_id = f.id
  41. WHERE fl.layer_id = #{layer_id}
  42. )
  43. AND
  44. (
  45. #{EARTH_RADIUS_METRES}
  46. * acos( cos( radians('#{lat}') )
  47. * cos( radians( p.lat ) )
  48. * cos( radians( p.lon )
  49. - radians('#{lon}') )
  50. + sin( radians('#{lat}') )
  51. * sin( radians( p.lat ) ) )
  52. )
  53. <= #{radius_metres}
  54. ORDER BY distance
  55. ENDQUERY
  56. )
  57. end
  58. end