Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions src/apps/testapps/testH3CellArea.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,23 @@ SUITE(h3CellArea) {
}
}

TEST(cell_area_antimeridian) {
// Cells straddling the antimeridian at fine resolutions, paired with
// an adjacent cell that does not. Their areas must agree closely; a
// naive longitude difference across +-180 degrees loses precision
// and makes the straddling cell up to several percent off.
H3Index pairs[][2] = {{0x8d056898db628bfULL, 0x8d056898db62d7fULL},
{0x8e32b605c51e067ULL, 0x8e32b605c51e15fULL},
{0x8f7f809893b5b9dULL, 0x8f7f809893b5b9cULL}};
for (int i = 0; i < 3; i++) {
double a, b;
t_assertSuccess(H3_EXPORT(cellAreaRads2)(pairs[i][0], &a));
t_assertSuccess(H3_EXPORT(cellAreaRads2)(pairs[i][1], &b));
t_assert(fabs(a / b - 1.0) < 1e-5,
"antimeridian cell area should match neighbor");
}
}

TEST(cell_area_invalid) {
H3Index invalid = 0xFFFFFFFFFFFFFFFF;
double area;
Expand Down
8 changes: 8 additions & 0 deletions src/h3lib/lib/area.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,15 @@ static inline double cagnoli(LatLng x, LatLng y) {
double sa = sin(x.lat) * sin(y.lat);
double ca = cos(x.lat) * cos(y.lat);

// For an edge crossing the antimeridian, the raw difference is close to
// +-2*pi, and the true (tiny) longitude step is lost to the ulp of 2*pi.
// Shift both longitudes to the same side of the antimeridian first so
// that the subtraction is between two nearby values; sin and cos are
// 2*pi-periodic, so the result is mathematically unchanged.
double d = y.lng - x.lng;
if (d > M_PI || d < -M_PI) {
d = (y.lng - copysign(M_PI, y.lng)) - (x.lng - copysign(M_PI, x.lng));
}
double sd = sin(d);
double cd = cos(d);

Expand Down
Loading