1
0

location.rb 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  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. private
  70. def floatify(value)
  71. case value
  72. when nil, ''
  73. return nil
  74. else
  75. float = Float(value)
  76. if block_given?
  77. yield(float)
  78. else
  79. float
  80. end
  81. end
  82. end
  83. end
  84. class LocationDrop
  85. KEYS = Location.members.map(&:to_s).concat(%w[latitude longitude])
  86. def before_method(key)
  87. if KEYS.include?(key)
  88. @object.__send__(key)
  89. end
  90. end
  91. end