]> git.openstreetmap.org Git - rails.git/blob - app/models/concerns/geo_record.rb
Merge remote-tracking branch 'upstream/pull/2667'
[rails.git] / app / models / concerns / geo_record.rb
1 module GeoRecord
2   extend ActiveSupport::Concern
3
4   # Ensure that when coordinates are printed that they are always in decimal degrees,
5   # and not e.g. 4.0e-05
6   # Unfortunately you can't extend Numeric classes directly (e.g. `Coord < Float`).
7   class Coord < DelegateClass(Float)
8     def initialize(obj)
9       super(obj)
10     end
11
12     def to_s
13       format("%<coord>.7f", :coord => self)
14     end
15
16     def as_json(_)
17       format("%<coord>.7f", :coord => self).to_f
18     end
19   end
20
21   # This scaling factor is used to convert between the float lat/lon that is
22   # returned by the API, and the integer lat/lon equivalent that is stored in
23   # the database.
24   SCALE = 10000000
25
26   included do
27     scope :bbox, ->(bbox) { where(OSM.sql_for_area(bbox, "#{table_name}.")) }
28     before_save :update_tile
29   end
30
31   # Is this node within -90 >= latitude >= 90 and -180 >= longitude >= 180
32   # * returns true/false
33   def in_world?
34     return false if lat < -90 || lat > 90
35     return false if lon < -180 || lon > 180
36
37     true
38   end
39
40   def update_tile
41     self.tile = QuadTile.tile_for_point(lat, lon)
42   end
43
44   def lat=(l)
45     self.latitude = (l * SCALE).round
46   end
47
48   def lon=(l)
49     self.longitude = (l * SCALE).round
50   end
51
52   # Return WGS84 latitude
53   def lat
54     Coord.new(latitude.to_f / SCALE)
55   end
56
57   # Return WGS84 longitude
58   def lon
59     Coord.new(longitude.to_f / SCALE)
60   end
61 end