Skip to content

Add geodesic coverage mode to polygonToCellsExperimental#1178

Open
holoskii wants to merge 6 commits into
uber:masterfrom
holoskii:geodesic_coverage
Open

Add geodesic coverage mode to polygonToCellsExperimental#1178
holoskii wants to merge 6 commits into
uber:masterfrom
holoskii:geodesic_coverage

Conversation

@holoskii

Copy link
Copy Markdown
Contributor

Introduce a geodesic flag for polygonToCellsExperimental that interprets
polygon edges as great-circle arcs instead of planar segments. This is
critical for accurate coverage of very large polygons spanning hundreds
or thousands of kilometers, where planar interpolation diverges
significantly from the true spherical geometry.

The implementation operates entirely on the unit sphere using 3D
Cartesian coordinates, with sphere-cap and AABB acceleration structures
for efficient cell pruning. Supports CONTAINMENT_CENTER, CONTAINMENT_FULL,
and CONTAINMENT_OVERLAPPING modes. This mode is slower than the planar
algorithm, so lower resolutions are recommended.

Note: geodesic mode rejects polygons that don't fit within a hemisphere

Key changes:

  • New FLAG_GEODESIC_MASK flag bit and FLAG_GET/SET/RESET_GEODESIC macros
  • GeodesicPolygon/GeodesicEdge/GeodesicLoop internal representations
  • Sphere-cap bounding with precomputed per-resolution cosine tables
  • 3D AABB and great-circle edge-crossing tests for containment
  • New cellToGeodesicBoundary + geodesic faceIjk boundary generators
  • Dedicated fuzzer, benchmarks, and comprehensive test suite

Developed at FloeDB and contributed upstream

holoskii added 5 commits June 23, 2026 15:14
Adds geodesic (great-circle) polygon-to-cells support to the
polygonToCellsExperimental API via a FLAG_GEODESIC_MASK flag bit.

Squashed from 39 commits on geodesic_coverage branch for clean rebase
onto upstream/master.
gcc -O2 inlines _ijkToHex2d and sees the uninitialized read. Initialize
to zero like the non-pentagon counterpart already does.
The docs stated that only FULL and OVERLAPPING are valid when the
geodesic flag is set. This contradicts the public API, which permits
CENTER as well: h3api.h.in documents it, validatePolygonFlags accepts
it (polygon.c), geodesicIteratorStep implements it (geodesicIterator.c),
and testGeodesicPolygonToCellsExperimental.c exercises it. Only
OVERLAPPING_BBOX is invalid in geodesic mode.

Update the umbrella statement and all per-binding sections (Java,
JavaScript, Python, Go, DuckDB) to list CENTER as valid.
@holoskii

Copy link
Copy Markdown
Contributor Author

Continuation of PR #1052
I rebased the old PR and fixed a few issues. First commit is PR 1052 squashed, next commits contain the fixes

@holoskii

Copy link
Copy Markdown
Contributor Author

@ajfriend this took some time, but here we are, should be good to merge

@coveralls

Copy link
Copy Markdown

Coverage Status

coverage: 98.662% (-0.5%) from 99.176% — holoskii:geodesic_coverage into uber:master

Comment thread src/apps/benchmarks/benchmarkPolygonToCellsExperimentalGeodesic.c Outdated
Comment thread src/apps/fuzzers/fuzzerPolygonToCellsExperimental.c Outdated
Comment thread src/apps/fuzzers/fuzzerPolygonToCellsExperimentalGeodesic.c Outdated
Comment thread src/h3lib/lib/bbox.c

// If the axis is nearly aligned with the normal, there's no unique
// extremum to find.
if (extremum_mag_sq < EPSILON * EPSILON) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is Epsilon squared a value above 0? I am wondering if this branch runs at all.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, far above minimum positive double value DBL_MIN = ~2.2e-308. So there can be a tiny arc exercising this branch. I created a small UT to verify it, but there is not enough value to commit it

Comment thread src/h3lib/lib/geodesicPolygon.c Outdated
- Fix copyright years on new files (benchmark + fuzzer geodesic)
- Clarify fuzzer duplicate-run skip comment
- Promote sideEps to file-scope SIDE_EPS constant in geodesicPolygon.c

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@holoskii

holoskii commented Jul 6, 2026

Copy link
Copy Markdown
Contributor Author

Addressed all of @dfellis commits

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants