]> git.openstreetmap.org Git - rails.git/blob - app/models/concerns/geo_record.rb
Merge remote-tracking branch 'upstream/pull/4178'
[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 to_s
9       format("%<coord>.7f", :coord => self)
10     end
11
12     def as_json(_)
13       format("%<coord>.7f", :coord => self).to_f
14     end
15   end
16
17   # This scaling factor is used to convert between the float lat/lon that is
18   # returned by the API, and the integer lat/lon equivalent that is stored in
19   # the database.
20   SCALE = 10000000
21
22   included do
23     scope :bbox, ->(bbox) { where(OSM.sql_for_area(bbox, "#{table_name}.")) }
24     before_save :update_tile
25   end
26
27   # Is this node within -90 >= latitude >= 90 and -180 >= longitude >= 180
28   # * returns true/false
29   def in_world?
30     return false if lat < -90 || lat > 90
31     return false if lon < -180 || lon > 180
32
33     true
34   end
35
36   def update_tile
37     self.tile = QuadTile.tile_for_point(lat, lon)
38   end
39
40   def lat=(l)
41     self.latitude = (l * SCALE).round
42   end
43
44   def lon=(l)
45     self.longitude = (l * SCALE).round
46   end
47
48   # Return WGS84 latitude
49   def lat
50     Coord.new(latitude.to_f / SCALE)
51   end
52
53   # Return WGS84 longitude
54   def lon
55     Coord.new(longitude.to_f / SCALE)
56   end
57 end