1
0

location.rb 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. require 'liquid'
  2. Location = Struct.new(:lat, :lng, :radius, :speed, :course)
  3. class Location
  4. include LiquidDroppable
  5. protected :[]=
  6. def initialize(data = {})
  7. super()
  8. case data
  9. when Array
  10. raise ArgumentError, 'unsupported location data' unless data.size == 2
  11. self.lat, self.lng = data
  12. when Hash, Location
  13. data.each { |key, value|
  14. case key.to_sym
  15. when :lat, :latitude
  16. self.lat = value
  17. when :lng, :longitude
  18. self.lng = value
  19. when :radius
  20. self.radius = value
  21. when :speed
  22. self.speed = value
  23. when :course
  24. self.course = value
  25. end
  26. }
  27. else
  28. raise ArgumentError, 'unsupported location data'
  29. end
  30. yield self if block_given?
  31. end
  32. def lat=(value)
  33. self[:lat] = floatify(value) { |f|
  34. if f.abs <= 90
  35. f
  36. else
  37. raise ArgumentError, 'out of bounds'
  38. end
  39. }
  40. end
  41. alias latitude lat
  42. alias latitude= lat=
  43. def lng=(value)
  44. self[:lng] = floatify(value) { |f|
  45. if f.abs <= 180
  46. f
  47. else
  48. raise ArgumentError, 'out of bounds'
  49. end
  50. }
  51. end
  52. alias longitude lng
  53. alias longitude= lng=
  54. def radius=(value)
  55. self[:radius] = floatify(value) { |f| f if f >= 0 }
  56. end
  57. def speed=(value)
  58. self[:speed] = floatify(value) { |f| f if f >= 0 }
  59. end
  60. def course=(value)
  61. self[:course] = floatify(value) { |f| f if (0..360).cover?(f) }
  62. end
  63. def present?
  64. lat && lng
  65. end
  66. def empty?
  67. !present?
  68. end
  69. def latlng
  70. "#{lat},#{lng}"
  71. end
  72. private
  73. def floatify(value)
  74. case value
  75. when nil, ''
  76. nil
  77. else
  78. float = Float(value)
  79. if block_given?
  80. yield(float)
  81. else
  82. float
  83. end
  84. end
  85. end
  86. public def to_liquid
  87. Drop.new(self)
  88. end
  89. class Drop < LiquidDroppable::Drop
  90. KEYS = Location.members.map(&:to_s).concat(%w[latitude longitude latlng])
  91. def liquid_method_missing(key)
  92. if KEYS.include?(key)
  93. @object.__send__(key)
  94. end
  95. end
  96. end
  97. end