Class: OvertureMaps::BoundingBox

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

Overview

A WGS84 bounding box. The single place that parses user-supplied coordinate strings, so import and download entry points cannot drift apart.

Constant Summary collapse

NUMBER =
/-?\d+(?:\.\d+)?/
COORDS =

Four numbers separated by commas, whitespace, or underscores, with an optional "|display name" suffix: "47.6,-122.3,47.7,-122.2" or "47.6_-122.3_47.7_-122.2|seattle"

/\A(#{NUMBER})[,\s_]+(#{NUMBER})[,\s_]+(#{NUMBER})[,\s_]+(#{NUMBER})(?:\|(.+))?\z/

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(lat1:, lng1:, lat2:, lng2:, display_name: nil) ⇒ BoundingBox

Returns a new instance of BoundingBox.



15
16
17
18
19
20
21
22
23
24
# File 'lib/overture_maps/bounding_box.rb', line 15

def initialize(lat1:, lng1:, lat2:, lng2:, display_name: nil)
  @min_lat, @max_lat = [Float(lat1), Float(lat2)].minmax
  @min_lng, @max_lng = [Float(lng1), Float(lng2)].minmax
  @display_name = display_name

  unless (-90..90).cover?(@min_lat) && (-90..90).cover?(@max_lat) &&
         (-180..180).cover?(@min_lng) && (-180..180).cover?(@max_lng)
    raise ArgumentError, "coordinates out of range: #{self}"
  end
end

Instance Attribute Details

#display_nameObject (readonly)

Returns the value of attribute display_name.



13
14
15
# File 'lib/overture_maps/bounding_box.rb', line 13

def display_name
  @display_name
end

#max_latObject (readonly)

Returns the value of attribute max_lat.



13
14
15
# File 'lib/overture_maps/bounding_box.rb', line 13

def max_lat
  @max_lat
end

#max_lngObject (readonly)

Returns the value of attribute max_lng.



13
14
15
# File 'lib/overture_maps/bounding_box.rb', line 13

def max_lng
  @max_lng
end

#min_latObject (readonly)

Returns the value of attribute min_lat.



13
14
15
# File 'lib/overture_maps/bounding_box.rb', line 13

def min_lat
  @min_lat
end

#min_lngObject (readonly)

Returns the value of attribute min_lng.



13
14
15
# File 'lib/overture_maps/bounding_box.rb', line 13

def min_lng
  @min_lng
end

Class Method Details

.around(lat:, lng:, radius_meters:) ⇒ Object



48
49
50
51
52
53
54
55
56
57
58
# File 'lib/overture_maps/bounding_box.rb', line 48

def self.around(lat:, lng:, radius_meters:)
  lat = Float(lat)
  lng = Float(lng)
  lat_delta = radius_meters.to_f / 111_000
  lng_delta = radius_meters.to_f / (111_000 * Math.cos(lat * Math::PI / 180))

  new(
    lat1: [lat - lat_delta, -90].max, lng1: [lng - lng_delta, -180].max,
    lat2: [lat + lat_delta, 90].min, lng2: [lng + lng_delta, 180].min
  )
end

.coordinates?(string) ⇒ Boolean

Returns:

  • (Boolean)


34
35
36
# File 'lib/overture_maps/bounding_box.rb', line 34

def self.coordinates?(string)
  COORDS.match?(string.to_s.strip)
end

.from_overture(bbox, display_name: nil) ⇒ Object

Overture bbox structs come back from division searches as => ..., "xmax" => ..., "ymin" => ..., "ymax" => ...



40
41
42
43
44
45
46
# File 'lib/overture_maps/bounding_box.rb', line 40

def self.from_overture(bbox, display_name: nil)
  new(
    lat1: bbox["ymin"], lng1: bbox["xmin"],
    lat2: bbox["ymax"], lng2: bbox["xmax"],
    display_name: display_name
  )
end

.parse(string) ⇒ Object

Returns a BoundingBox if the string looks like coordinates, else nil.



27
28
29
30
31
32
# File 'lib/overture_maps/bounding_box.rb', line 27

def self.parse(string)
  match = COORDS.match(string.to_s.strip)
  return nil unless match

  new(lat1: match[1], lng1: match[2], lat2: match[3], lng2: match[4], display_name: match[5])
end

Instance Method Details

#slugObject

Filename-safe label for cache files.



65
66
67
68
69
# File 'lib/overture_maps/bounding_box.rb', line 65

def slug
  return sanitized_display_name if display_name

  format("%.4f_%.4f_%.4f_%.4f", min_lat, min_lng, max_lat, max_lng)
end

#to_sObject



60
61
62
# File 'lib/overture_maps/bounding_box.rb', line 60

def to_s
  "#{min_lat},#{min_lng},#{max_lat},#{max_lng}"
end