class GeoMonitor::BoundingBox

Bounding Box

Attributes

east[R]
north[R]
south[R]
west[R]

Public Class Methods

new(north:, south:, east:, west:) click to toggle source
# 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

Public Instance Methods

tile_bounds() click to toggle source

Calculates the tilebounds for a tile within the existing bounds.

# 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_number() click to toggle source

See: wiki.openstreetmap.org/wiki/Slippy_map_tilenames#Lon..2Flat._to_tile_numbers_2

# 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_s() click to toggle source
# File lib/geo_monitor/bounding_box.rb, line 14
def to_s
  "#{west},#{south},#{east},#{north}"
end
zoom_level() click to toggle source

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

# 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