Module: H3::GeoJson

Included in:
H3
Defined in:
lib/h3/geo_json.rb

Overview

GeoJSON helper methods.

This module allows conversions between GeoJSON polygon data and a nested set of coordinates.

It should be noted that H3 describes coordinates as number pairs in the form

[latitude, longitude]

whereas the GeoJSON standard uses

[longitude, latitude]

Both use degrees.

Coordinates Array

We use a nested array to hold coordinates describing a geographical region.

The first element in the array is an external geofence boundary, composed of an array of coordinates as 2-element arrays of the form [latitude, longitude].

Any further elements in the array are further geofence arrays of coordinates which describe holes that may be present in the polygon.

Specific examples are shown in the individual method details.

Instance Method Summary collapse

Instance Method Details

#coordinates_to_geo_json(coordinates) ⇒ String

Convert a nested array of coordinates to a GeoJSON document

Examples:

Convert a set of nested coordinates of Banbury to a GeoJSON document.

coordinates = [
  [
    [52.24630137198303, -1.7358398437499998], [52.05249047600099, -1.8923950195312498],
    [51.891749018068246, -1.56829833984375], [51.91208502557545, -1.27716064453125],
    [52.032218104145294, -1.19476318359375], [52.19413974159753, -1.24420166015625],
    [52.24125614966341, -1.5902709960937498], [52.24630137198303, -1.7358398437499998]
  ],
  [
    [52.12590076522272, -1.58203125], [52.12590076522272, -1.476287841796875],
    [52.075285904832334, -1.46392822265625], [52.06937709602395, -1.58203125],
    [52.12590076522272, -1.58203125]
  ],
  [
    [52.01531743663362, -1.4556884765625], [51.97642166216334, -1.483154296875],
    [51.96626938051444, -1.3677978515625], [52.0102459910103, -1.3568115234375],
    [52.01531743663362, -1.4556884765625]
  ]
]
H3.coordinates_to_geo_json(coordinates)
"{\"type\":\"Polygon\",\"coordinates\":[
  [
    [-1.7358398437499998,52.24630137198303], [-1.8923950195312498,52.05249047600099],
    [-1.56829833984375,51.891749018068246], [-1.27716064453125,51.91208502557545],
    [-1.19476318359375,52.032218104145294], [-1.24420166015625,52.19413974159753],
    [-1.5902709960937498,52.24125614966341], [-1.7358398437499998,52.24630137198303]
  ],
  [
    [-1.58203125,52.12590076522272], [-1.476287841796875,52.12590076522272],
    [-1.46392822265625,52.075285904832334], [-1.58203125,52.06937709602395],
    [-1.58203125,52.12590076522272]
  ],
  [
    [-1.4556884765625,52.01531743663362], [-1.483154296875,51.97642166216334],
    [-1.3677978515625,51.96626938051444], [-1.3568115234375,52.0102459910103],
    [-1.4556884765625,52.01531743663362]
  ]
]}"

Parameters:

  • coordinates (Array<Array<Array>>)

    Nested array of coordinates.

Returns:

  • (String)

    GeoJSON document.

Raises:

  • (ArgumentError)

    Failed to parse the given coordinates.



132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/h3/geo_json.rb', line 132

def coordinates_to_geo_json(coordinates)
  coordinates = swap_lat_lon(coordinates)
  outer_coords, *inner_coords = coordinates
  factory = RGeo::Cartesian.simple_factory
  exterior = factory.linear_ring(outer_coords.map { |lon, lat| factory.point(lon, lat) })
  interior_rings = inner_coords.map do |polygon|
    factory.linear_ring(polygon.map { |lon, lat| factory.point(lon, lat) })
  end
  polygon = factory.polygon(exterior, interior_rings)
  RGeo::GeoJSON.encode(polygon).to_json
rescue RGeo::Error::InvalidGeometry, NoMethodError
  invalid_coordinates!
end

#geo_json_to_coordinates(input) ⇒ Array<Array<Array>>

Convert a GeoJSON document to a nested array of coordinates.

Examples:

Convert a GeoJSON document of Banbury to a set of nested coordinates.

document = "{\"type\":\"Polygon\",\"coordinates\":[
  [
    [-1.7358398437499998,52.24630137198303], [-1.8923950195312498,52.05249047600099],
    [-1.56829833984375,51.891749018068246], [-1.27716064453125,51.91208502557545],
    [-1.19476318359375,52.032218104145294], [-1.24420166015625,52.19413974159753],
    [-1.5902709960937498,52.24125614966341], [-1.7358398437499998,52.24630137198303]
  ],
  [
    [-1.58203125,52.12590076522272], [-1.476287841796875,52.12590076522272],
    [-1.46392822265625,52.075285904832334], [-1.58203125,52.06937709602395],
    [-1.58203125,52.12590076522272]
  ],
  [
    [-1.4556884765625,52.01531743663362], [-1.483154296875,51.97642166216334],
    [-1.3677978515625,51.96626938051444], [-1.3568115234375,52.0102459910103],
    [-1.4556884765625,52.01531743663362]
  ]
]}"
H3.geo_json_to_coordinates(document)
[
  [
    [52.24630137198303, -1.7358398437499998], [52.05249047600099, -1.8923950195312498],
    [51.891749018068246, -1.56829833984375], [51.91208502557545, -1.27716064453125],
    [52.032218104145294, -1.19476318359375], [52.19413974159753, -1.24420166015625],
    [52.24125614966341, -1.5902709960937498], [52.24630137198303, -1.7358398437499998]
  ],
  [
    [52.12590076522272, -1.58203125], [52.12590076522272, -1.476287841796875],
    [52.075285904832334, -1.46392822265625], [52.06937709602395, -1.58203125],
    [52.12590076522272, -1.58203125]
  ],
  [
    [52.01531743663362, -1.4556884765625], [51.97642166216334, -1.483154296875],
    [51.96626938051444, -1.3677978515625], [52.0102459910103, -1.3568115234375],
    [52.01531743663362, -1.4556884765625]
  ]
]

Parameters:

  • input (String)

    The GeoJSON document. This can be a feature collection, feature, or polygon. If a feature collection is provided, the first feature is used.

Returns:

  • (Array<Array<Array>>)

    Nested array of coordinates.

Raises:

  • (ArgumentError)

    Failed to parse the GeoJSON document.



78
79
80
81
82
83
84
# File 'lib/h3/geo_json.rb', line 78

def geo_json_to_coordinates(input)
  geom = RGeo::GeoJSON.decode(input)
  coordinates = fetch_coordinates(geom)
  swap_lat_lon(coordinates) || failed_to_parse!
rescue JSON::ParserError
  failed_to_parse!
end