Skip to content

Commit

Permalink
Update H3 to 3.7.1 & add new functions (#70)
Browse files Browse the repository at this point in the history
  • Loading branch information
seanhandley authored Oct 13, 2020
1 parent b808586 commit 2201262
Show file tree
Hide file tree
Showing 7 changed files with 267 additions and 5 deletions.
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,25 @@ This project adheres to [Semantic Versioning](http://semver.org/).

We track the MAJOR and MINOR version levels of Uber's H3 project (https://github.com/uber/h3) but maintain independent patch levels so we can make small fixes and non breaking changes.

## [3.7.1] - 2020-10-7
### Added
- Area and haversine distance functions:
- `cellAreaRads2`
- `cellAreaKm2`
- `cellAreaM2`
- `pointDistRads`
- `pointDistKm`
- `pointDistM`
- `exactEdgeLengthRads`
- `exactEdgeLengthKm`
- `exactEdgeLengthM`

### Changed
- Speeds up `getH3UnidirectionalEdgeBoundary` by about 3x.

### Fixed
- Finding invalid edge boundaries should not crash.

## [3.6.4] - 2020-7-2
### Changed
- Reinstate new `polyfill` algorithm for up to 3x perf boost.
Expand Down
6 changes: 3 additions & 3 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
h3 (3.6.4)
h3 (3.7.1)
ffi (~> 1.9)
rgeo-geojson (~> 2.1)
zeitwerk (~> 2.1)
Expand Down Expand Up @@ -46,7 +46,7 @@ GEM
thor (0.19.4)
tins (1.20.2)
yard (0.9.20)
zeitwerk (2.3.1)
zeitwerk (2.4.0)

PLATFORMS
ruby
Expand All @@ -59,4 +59,4 @@ DEPENDENCIES
yard (~> 0.9)

BUNDLED WITH
1.17.3
2.1.4
2 changes: 1 addition & 1 deletion ext/h3/src
Submodule src updated 57 files
+118 −0 .github/workflows/test-linux.yml
+42 −0 .github/workflows/test-macos.yml
+32 −0 .github/workflows/test-website.yml
+44 −0 .github/workflows/test-windows.yml
+3 −0 .gitignore
+8 −52 .travis.yml
+0 −92 .ycm_extra_conf.py
+24 −0 CHANGELOG.md
+20 −8 CMakeLists.txt
+60 −10 README.md
+3 −1 RELEASE.md
+1 −1 VERSION
+0 −50 appveyor.yml
+21 −0 dev-docs/RFCs/rfc-template.md
+21 −0 dev-docs/RFCs/v4.0.0/error-handling-rfc.md
+11 −0 dev-docs/RFCs/v4.0.0/names_for_concepts_types_functions.md
+21 −0 dev-docs/RFCs/v4.0.0/polyfill-modes-rfc.md
+50 −0 dev-docs/RFCs/v4.0.0/vertex-mode-rfc.md
+6 −1 dev-docs/build_windows.md
+3 −3 dev-docs/creating_bindings.md
+76 −0 docs/api/misc.md
+1 −0 docs/community/applications.md
+8 −4 docs/community/tutorials.md
+12 −1 docs/core-library/h3indexing.md
+1 −1 scripts/binding_functions.sh
+1 −1 scripts/coverage.sh.in
+2 −2 scripts/update_version.sh
+4 −1 src/apps/applib/include/utility.h
+119 −3 src/apps/applib/lib/utility.c
+1 −1 src/apps/benchmarks/benchmarkH3Api.c
+34 −0 src/apps/benchmarks/benchmarkH3UniEdge.c
+67 −0 src/apps/miscapps/generatePentagonDirectionFaces.c
+15 −1 src/apps/testapps/testBaseCells.c
+39 −13 src/apps/testapps/testGeoCoord.c
+47 −0 src/apps/testapps/testH3CellArea.c
+180 −0 src/apps/testapps/testH3CellAreaExhaustive.c
+8 −5 src/apps/testapps/testH3ToLocalIj.c
+39 −16 src/apps/testapps/testH3UniEdge.c
+111 −0 src/apps/testapps/testH3UniEdgeExhaustive.c
+1 −1 src/apps/testapps/testPolyfill.c
+66 −0 src/apps/testapps/testVertex.c
+4 −0 src/h3lib/include/baseCells.h
+3 −2 src/h3lib/include/faceijk.h
+1 −3 src/h3lib/include/geoCoord.h
+9 −3 src/h3lib/include/h3Index.h
+46 −2 src/h3lib/include/h3api.h.in
+44 −0 src/h3lib/include/vertex.h
+5 −5 src/h3lib/lib/algos.c
+25 −4 src/h3lib/lib/baseCells.c
+4 −4 src/h3lib/lib/bbox.c
+30 −21 src/h3lib/lib/faceijk.c
+160 −44 src/h3lib/lib/geoCoord.c
+26 −19 src/h3lib/lib/h3Index.c
+41 −57 src/h3lib/lib/h3UniEdge.c
+134 −0 src/h3lib/lib/vertex.c
+1 −1 website/README.md
+1 −1 website/scripts/build-to-gh-pages.sh
3 changes: 3 additions & 0 deletions lib/h3/bindings/private.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ module Private
[GeoPolygon, Resolution],
:int
attach_function :max_uncompact_size, :maxUncompactSize, [H3IndexesIn, :size_t, Resolution], :int
attach_function :point_distance_rads, :pointDistRads, [GeoCoord, GeoCoord], :double
attach_function :point_distance_km, :pointDistKm, [GeoCoord, GeoCoord], :double
attach_function :point_distance_m, :pointDistM, [GeoCoord, GeoCoord], :double
attach_function :polyfill, [GeoPolygon, Resolution, H3IndexesOut], :void
attach_function :res_0_indexes, :getRes0Indexes, [H3IndexesOut], :void
attach_function :uncompact, [H3IndexesIn, :size_t, H3IndexesOut, :size_t, Resolution], :bool
Expand Down
123 changes: 123 additions & 0 deletions lib/h3/miscellaneous.rb
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,105 @@ module Miscellaneous
# @return [Integer] The number of pentagons per resolution.
attach_function :pentagon_count, :pentagonIndexCount, [], :int

# @!method cell_area_rads2
#
# Area of a given cell expressed in radians squared
#
# @example Return the area of the cell
# H3.cell_area_rads2(617700169958293503)
# 2.6952182709835757e-09
#
# @return [Double] Area of cell in rads2
attach_function :cell_area_rads2, :cellAreaRads2, %i[h3_index], :double

# @!method cell_area_km2
#
# Area of a given cell expressed in km squared
#
# @example Return the area of the cell
# H3.cell_area_km2(617700169958293503)
# 0.10939818864648902
#
# @return [Double] Area of cell in km2
attach_function :cell_area_km2, :cellAreaKm2, %i[h3_index], :double

# @!method cell_area_m2
#
# Area of a given cell expressed in metres squared
#
# @example Return the area of the cell
# H3.cell_area_m2(617700169958293503)
# 109398.18864648901
#
# @return [Double] Area of cell in metres squared
attach_function :cell_area_m2, :cellAreaM2, %i[h3_index], :double

# @!method exact_edge_length_rads
#
# Exact length of edge in rads
#
# @example Return the edge length
# H3.exact_edge_length_rads(1266218516299644927)
# 3.287684056071637e-05
#
# @return [Double] Edge length in rads
attach_function :exact_edge_length_rads, :exactEdgeLengthRads, %i[h3_index], :double

# @!method exact_edge_length_km
#
# Exact length of edge in kilometres
#
# @example Return the edge length
# H3.exact_edge_length_km(1266218516299644927)
# 3.287684056071637e-05
#
# @return [Double] Edge length in kilometres
attach_function :exact_edge_length_km, :exactEdgeLengthKm, %i[h3_index], :double

# @!method exact_edge_length_m
#
# Exact length of edge in metres
#
# @example Return the edge length
# H3.exact_edge_length_m(1266218516299644927)
# 3.287684056071637e-05
#
# @return [Double] Edge length in metres
attach_function :exact_edge_length_m, :exactEdgeLengthM, %i[h3_index], :double

# Returns the radians distance between two points.
#
# @example Return radians distance.
# H3.point_distance_rads([41.3964809, 2.160444], [41.3870609, 2.164917])
# 0.00017453024784008713
#
# @return [Double] Radians distance between two points.
def point_distance_rads(origin, destination)
Bindings::Private.point_distance_rads(*build_geocoords(origin, destination))
end

# Returns the kilometres distance between two points.
#
# @example Return km distance.
# H3.point_distance_km([41.3964809, 2.160444], [41.3870609, 2.164917])
# 1.1119334622766763
#
# @return [Double] KM distance between two points.
def point_distance_km(origin, destination)
Bindings::Private.point_distance_km(*build_geocoords(origin, destination))
end

# Returns the metre distance between two points.
#
# @example Return metre distance.
# H3.point_distance_m([41.3964809, 2.160444], [41.3870609, 2.164917])
# 1111.9334622766764
#
# @return [Double] Metre distance between two points.
def point_distance_m(origin, destination)
Bindings::Private.point_distance_m(*build_geocoords(origin, destination))
end

# Returns all resolution 0 hexagons (base cells).
#
# @example Return all base cells.
Expand All @@ -144,5 +243,29 @@ def pentagons(resolution)
Bindings::Private.get_pentagon_indexes(resolution, out)
out.read
end

private

def build_geocoords(origin, destination)
[origin, destination].inject([]) do |acc, coords|
validate_coordinate(coords)

geo_coord = GeoCoord.new
lat, lon = coords
geo_coord[:lat] = degs_to_rads(lat)
geo_coord[:lon] = degs_to_rads(lon)
acc << geo_coord
end
end

def validate_coordinate(coords)
raise ArgumentError unless coords.is_a?(Array) && coords.count == 2

lat, lon = coords

if lat > 90 || lat < -90 || lon > 180 || lon < -180
raise(ArgumentError, "Invalid coordinates")
end
end
end
end
2 changes: 1 addition & 1 deletion lib/h3/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module H3
VERSION = "3.6.4".freeze
VERSION = "3.7.1".freeze
end
117 changes: 117 additions & 0 deletions spec/miscellaneous_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -109,4 +109,121 @@
expect(pentagons).to eq(expected)
end
end

describe ".cell_area_rads2" do
let(:cell) { "8928308280fffff".to_i(16) }
let(:expected) { 2.6952182709835757e-09 }
subject(:cell_area_rads2) { H3.cell_area_rads2(cell) }

it "returns cell area in rads2" do
expect(cell_area_rads2).to be_within(0.0001).of(expected)
end
end

describe ".cell_area_km2" do
let(:cell) { "8928308280fffff".to_i(16) }
let(:expected) { 0.10939818864648902 }
subject(:cell_area_km2) { H3.cell_area_km2(cell) }

it "returns cell area in km2" do
expect(cell_area_km2).to be_within(0.0001).of(expected)
end
end

describe ".cell_area_m2" do
let(:cell) { "8928308280fffff".to_i(16) }
let(:expected) { 109398.18864648901 }
subject(:cell_area_m2) { H3.cell_area_m2(cell) }

it "returns cell area in m2" do
expect(cell_area_m2).to be_within(0.0001).of(expected)
end
end

describe ".exact_edge_length_rads" do
let(:cell) { "11928308280fffff".to_i(16) }
let(:expected) { 3.287684056071637e-05 }
subject(:exact_edge_length_rads) { H3.exact_edge_length_rads(cell) }

it "returns edge length in rads" do
expect(exact_edge_length_rads).to be_within(0.0001).of(expected)
end
end

describe ".exact_edge_length_km" do
let(:cell) { "11928308280fffff".to_i(16) }
let(:expected) { 0.20945858729823577 }
subject(:exact_edge_length_km) { H3.exact_edge_length_km(cell) }

it "returns edge length in km" do
expect(exact_edge_length_km).to be_within(0.0001).of(expected)
end
end

describe ".exact_edge_length_m" do
let(:cell) { "11928308280fffff".to_i(16) }
let(:expected) { 209.45858729823578 }
subject(:exact_edge_length_m) { H3.exact_edge_length_m(cell) }

it "returns edge length in m" do
expect(exact_edge_length_m).to be_within(0.0001).of(expected)
end
end

describe ".point_distance_rads" do
let(:a) { [41.3964809, 2.160444] }
let(:b) { [41.3870609, 2.164917] }
let(:expected) { 0.00017453024784008713 }
subject(:point_distance_rads) { H3.point_distance_rads(a, b) }

it "returns distance between points in rads" do
expect(point_distance_rads).to be_within(0.0001).of(expected)
end

context "when the coordinates are invalid" do
let(:a) { [91, -18] }

it "raises an argument error" do
expect { point_distance_rads }.to raise_error(ArgumentError)
end
end
end

describe ".point_distance_km" do
let(:a) { [41.3964809, 2.160444] }
let(:b) { [41.3870609, 2.164917] }
let(:expected) { 1.1119334622766763 }
subject(:point_distance_km) { H3.point_distance_km(a, b) }

it "returns distance between points in km" do
expect(point_distance_km).to be_within(0.0001).of(expected)
end

context "when the coordinates are invalid" do
let(:a) { [89, -181] }

it "raises an argument error" do
expect { point_distance_km }.to raise_error(ArgumentError)
end
end
end

describe ".point_distance_m" do
let(:a) { [41.3964809, 2.160444] }
let(:b) { [41.3870609, 2.164917] }
let(:expected) { 1111.9334622766764 }
subject(:point_distance_m) { H3.point_distance_m(a, b) }

it "returns distance between points in m" do
expect(point_distance_m).to be_within(0.0001).of(expected)
end

context "when the coordinates are invalid" do
let(:a) { "boom" }

it "raises an argument error" do
expect { point_distance_m }.to raise_error(ArgumentError)
end
end
end
end

0 comments on commit 2201262

Please sign in to comment.