Class: CocinaDisplay::Geospatial::BoundingBox
- Inherits:
-
Coordinates
- Object
- Coordinates
- CocinaDisplay::Geospatial::BoundingBox
- Defined in:
- lib/cocina_display/geospatial.rb
Overview
A bounding box defined by its southwest and northeast corner points. The box can wrap east-west across the antimeridian, in which case its west edge is numerically east of its east edge. Both Solr's rectangle syntax and GeoJSON spell a crossing box that way, as do MARC 034 $d/$e, which are the westernmost and easternmost longitudes rather than the minimum and maximum.
Instance Attribute Summary collapse
-
#northeast ⇒ Object
readonly
Returns the value of attribute northeast.
-
#southwest ⇒ Object
readonly
Returns the value of attribute southwest.
Class Method Summary collapse
-
.from_coords(west:, east:, north:, south:) ⇒ BoundingBox?
Construct a BoundingBox from west, east, north, and south string values.
Instance Method Summary collapse
-
#as_bbox ⇒ Array<Array<Float>>
Format the bounding box as an array of two coordinate pairs [[S, W], [N, E]].
-
#as_envelope ⇒ String
Format using the CQL ENVELOPE representation.
-
#as_point ⇒ String
The box center point as a space-separated x y (longitude latitude) pair.
-
#as_wkt ⇒ String
Format using the Well-Known Text (WKT) representation.
-
#crosses_antimeridian? ⇒ Boolean
True if the box wraps east-west across the antimeridian.
-
#east ⇒ BigDecimal
The easternmost longitude of the box.
-
#initialize(southwest:, northeast:) ⇒ BoundingBox
constructor
Construct a BoundingBox from two corner Geo::Coord points.
-
#north ⇒ BigDecimal
The northernmost latitude of the box.
-
#south ⇒ BigDecimal
The southernmost latitude of the box.
-
#to_s ⇒ String
Format for display in DMS format, adapted from ISO 6709 standard.
-
#west ⇒ BigDecimal
The westernmost longitude of the box.
Methods inherited from Coordinates
from_cocina, from_structured_values, parse
Constructor Details
#initialize(southwest:, northeast:) ⇒ BoundingBox
Construct a BoundingBox from two corner Geo::Coord points.
214 215 216 217 |
# File 'lib/cocina_display/geospatial.rb', line 214 def initialize(southwest:, northeast:) @southwest = southwest @northeast = northeast end |
Instance Attribute Details
#northeast ⇒ Object (readonly)
Returns the value of attribute northeast.
188 189 190 |
# File 'lib/cocina_display/geospatial.rb', line 188 def northeast @northeast end |
#southwest ⇒ Object (readonly)
Returns the value of attribute southwest.
188 189 190 |
# File 'lib/cocina_display/geospatial.rb', line 188 def southwest @southwest end |
Class Method Details
.from_coords(west:, east:, north:, south:) ⇒ BoundingBox?
Construct a BoundingBox from west, east, north, and south string values. West and east are used as given, so a box that crosses the antimeridian is preserved instead of rejected.
198 199 200 201 202 203 204 205 206 207 208 209 |
# File 'lib/cocina_display/geospatial.rb', line 198 def self.from_coords(west:, east:, north:, south:) southwest = Geo::Coord.parse("#{south}, #{west}") northeast = Geo::Coord.parse("#{north}, #{east}") # Must be parsable return unless southwest && northeast # A box can wrap east-west, but never north-south return if southwest.lat > northeast.lat new(southwest: southwest, northeast: northeast) end |
Instance Method Details
#as_bbox ⇒ Array<Array<Float>>
Limits decimals to 6 places.
For a box crossing the antimeridian, east is carried past 180 so that the pair still reads southwest to northeast.
Format the bounding box as an array of two coordinate pairs [[S, W], [N, E]].
298 299 300 |
# File 'lib/cocina_display/geospatial.rb', line 298 def as_bbox [[south, west], [north, unwrapped_east]] end |
#as_envelope ⇒ String
Limits decimals to 6 places.
West is greater than east for a box crossing the antimeridian.
Format using the CQL ENVELOPE representation.
278 279 280 |
# File 'lib/cocina_display/geospatial.rb', line 278 def as_envelope "ENVELOPE(%.6f, %.6f, %.6f, %.6f)" % [west, east, north, south] end |
#as_point ⇒ String
Limits decimals to 6 places.
The box center point as a space-separated x y (longitude latitude) pair.
286 287 288 289 290 |
# File 'lib/cocina_display/geospatial.rb', line 286 def as_point center_lng = (west + unwrapped_east) / 2 center_lng -= 360 if center_lng > 180 "%.6f %.6f" % [center_lng, (south + north) / 2] end |
#as_wkt ⇒ String
Limits decimals to 6 places.
A box crossing the antimeridian is split into two polygons at the date line, so that every longitude stays within bounds.
Format using the Well-Known Text (WKT) representation.
267 268 269 270 271 |
# File 'lib/cocina_display/geospatial.rb', line 267 def as_wkt return "POLYGON(#{ring(west, east)})" unless crosses_antimeridian? "MULTIPOLYGON((#{ring(west, 180)}), (#{ring(-180, east)}))" end |
#crosses_antimeridian? ⇒ Boolean
True if the box wraps east-west across the antimeridian.
245 246 247 |
# File 'lib/cocina_display/geospatial.rb', line 245 def crosses_antimeridian? west > east end |
#east ⇒ BigDecimal
The easternmost longitude of the box.
227 228 229 |
# File 'lib/cocina_display/geospatial.rb', line 227 def east northeast.lng end |
#north ⇒ BigDecimal
The northernmost latitude of the box.
233 234 235 |
# File 'lib/cocina_display/geospatial.rb', line 233 def north northeast.lat end |
#south ⇒ BigDecimal
The southernmost latitude of the box.
239 240 241 |
# File 'lib/cocina_display/geospatial.rb', line 239 def south southwest.lat end |
#to_s ⇒ String
This format adapts the "Annex D" human representation style.
Format for display in DMS format, adapted from ISO 6709 standard.
254 255 256 257 258 |
# File 'lib/cocina_display/geospatial.rb', line 254 def to_s south_str, west_str = format_point(southwest) north_str, east_str = format_point(northeast) "#{west_str} -- #{east_str} / #{north_str} -- #{south_str}" end |
#west ⇒ BigDecimal
The westernmost longitude of the box.
221 222 223 |
# File 'lib/cocina_display/geospatial.rb', line 221 def west southwest.lng end |