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.

post.rb 1.8 KiB

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