Class: GeoMonitor::BoundingBox

Inherits:
Object
  • Object
show all
Defined in:
lib/geo_monitor/bounding_box.rb

Overview

Bounding Box

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(north:, south:, east:, west:) ⇒ BoundingBox

Returns a new instance of BoundingBox.



7
8
9
10
11
12
# File 'lib/geo_monitor/bounding_box.rb', line 7

def initialize(north:, south:, east:, west:)
  @north = north.to_f
  @south = south.to_f
  @east = east.to_f
  @west = west.to_f
end

Instance Attribute Details

#eastObject (readonly)

Returns the value of attribute east.



5
6
7
# File 'lib/geo_monitor/bounding_box.rb', line 5

def east
  @east
end

#northObject (readonly)

Returns the value of attribute north.



5
6
7
# File 'lib/geo_monitor/bounding_box.rb', line 5

def north
  @north
end

#southObject (readonly)

Returns the value of attribute south.



5
6
7
# File 'lib/geo_monitor/bounding_box.rb', line 5

def south
  @south
end

#westObject (readonly)

Returns the value of attribute west.



5
6
7
# File 'lib/geo_monitor/bounding_box.rb', line 5

def west
  @west
end

Instance Method Details

#tile_boundsObject

Calculates the tilebounds for a tile within the existing bounds.



20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/geo_monitor/bounding_box.rb', line 20

def tile_bounds
  tile = tile_number
  zoom = zoom_level
  sw = ::GeoMonitor::LatLngPoint.from_number(tile[:x], tile[:y], zoom).to_3857
  ne = ::GeoMonitor::LatLngPoint.from_number(tile[:x] + 1, tile[:y] - 1, zoom).to_3857
  self.class.new(
    north: ne.lat,
    east: ne.lng,
    south: sw.lat,
    west: sw.lng
  )
end

#tile_numberObject



52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/geo_monitor/bounding_box.rb', line 52

def tile_number
  lat_rad = south / 180 * Math::PI
  n = 2.0**zoom_level
  x = ((west + 180.0) / ::GeoMonitor::Constants::DEGREES_IN_CIRCLE * n).to_i
  y = ((1.0 - Math.log(Math.tan(lat_rad) + (1 / Math.cos(lat_rad))) / Math::PI) / 2.0 * n)
  y = if y.infinite?.nil?
        y.to_i
      else
        x
      end
  { x: x, y: y }
end

#to_sObject



14
15
16
# File 'lib/geo_monitor/bounding_box.rb', line 14

def to_s
  "#{west},#{south},#{east},#{north}"
end

#zoom_levelObject

Calculates the “zoom level” that can best view the bounds. wiki.openstreetmap.org/wiki/Zoom_levels



36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/geo_monitor/bounding_box.rb', line 36

def zoom_level
  lat_diff = north - south
  lng_diff = east - west
  max_diff = [lat_diff, lng_diff].max

  if max_diff < ::GeoMonitor::Constants::DEGREES_IN_CIRCLE / 2**20
    zoom = 21
  else
    zoom = -1 * ((Math.log(max_diff) / Math.log(2)) - (Math.log(::GeoMonitor::Constants::DEGREES_IN_CIRCLE) / Math.log(2)))
    zoom = 1 if zoom < 1
  end
  zoom.ceil
end