-
Notifications
You must be signed in to change notification settings - Fork 468
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for full containment and overlapping modes in polygonToCellsExperimental #796
Conversation
scripts/make_countries.js
Outdated
|
||
BENCHMARK(polygonToCells_AllCountries4, 5, { | ||
for (int index = 0; index < ${polygons.length}; index++) { | ||
H3_EXPORT(polygonToCellsExperimental)(&COUNTRIES[index], res, OVERLAPPING, hexagons); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new modes are slower than center containment, unsurprisingly, but still manage to be faster than the old algo in some cases:
Res 0 -- polygonToCells_AllCountries1: 198222.000000 microseconds per iteration (5 iterations)
-- polygonToCells_AllCountries2: 42474.800000 microseconds per iteration (5 iterations)
-- polygonToCells_AllCountries3: 247580.600000 microseconds per iteration (5 iterations)
-- polygonToCells_AllCountries4: 282227.200000 microseconds per iteration (5 iterations)
Res 1 -- polygonToCells_AllCountries1: 324889.800000 microseconds per iteration (5 iterations)
-- polygonToCells_AllCountries2: 18640.000000 microseconds per iteration (5 iterations)
-- polygonToCells_AllCountries3: 72821.200000 microseconds per iteration (5 iterations)
-- polygonToCells_AllCountries4: 89494.400000 microseconds per iteration (5 iterations)
Res 2 -- polygonToCells_AllCountries1: 257009.400000 microseconds per iteration (5 iterations)
-- polygonToCells_AllCountries2: 66020.600000 microseconds per iteration (5 iterations)
-- polygonToCells_AllCountries3: 143866.400000 microseconds per iteration (5 iterations)
-- polygonToCells_AllCountries4: 181394.600000 microseconds per iteration (5 iterations)
Res 3 -- polygonToCells_AllCountries1: 424776.400000 microseconds per iteration (5 iterations)
-- polygonToCells_AllCountries2: 280514.200000 microseconds per iteration (5 iterations)
-- polygonToCells_AllCountries3: 442108.400000 microseconds per iteration (5 iterations)
-- polygonToCells_AllCountries4: 545078.600000 microseconds per iteration (5 iterations)
Res 4 -- polygonToCells_AllCountries1: 2035545.200000 microseconds per iteration (5 iterations)
-- polygonToCells_AllCountries2: 1462475.200000 microseconds per iteration (5 iterations)
-- polygonToCells_AllCountries3: 1969331.600000 microseconds per iteration (5 iterations)
-- polygonToCells_AllCountries4: 2559085.000000 microseconds per iteration (5 iterations)
src/h3lib/include/polygon.h
Outdated
typedef enum { | ||
CENTER_CONTAINMENT = 0, | ||
FULL_CONTAINMENT = 1, | ||
OVERLAPPING = 2, | ||
INVALID_CONTAINMENT = 3 | ||
} ContainmentMode; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we may want to prefix the enun names with something here (POLYGON_CENTER_CONTAINMENT
?) so that it is clear a valid enum is being fed into polygonToCells
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That makes sense - leaning towards CONTAINMENT_
as the prefix, so we'd have
CONTAINMENT_CENTER
CONTAINMENT_FULL
CONTAINMENT_OVERLAPPING
CONTAINMENT_INVALID
One thought here is that we might apply the same modes to circles or bounding boxes at some point, so I don't necessarily think we want to bake POLYGON
into the name.
src/h3lib/include/polygon.h
Outdated
CENTER_CONTAINMENT = 0, | ||
FULL_CONTAINMENT = 1, | ||
OVERLAPPING = 2, | ||
INVALID_CONTAINMENT = 3 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CENTER_CONTAINMENT = 0, | |
FULL_CONTAINMENT = 1, | |
OVERLAPPING = 2, | |
INVALID_CONTAINMENT = 3 | |
CENTER_CONTAINMENT = 0, ///< Cells are included if their center is in the polygon | |
FULL_CONTAINMENT = 1, ///< Cells are included if they are entirely contained in the polygon | |
OVERLAPPING = 2, ///< Cells are included if any part of them overlaps the polygon | |
INVALID_CONTAINMENT = 3 ///< This mode is invalid and should not be used. |
iterErrorPolygonCompact(iter, centerErr); | ||
return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This (and similar case below) are uncovered in test, but look like they should be testable by setting an invalid cell on the iterator and then calling this function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I'll try to add coverage here today or tomorrow.
src/h3lib/lib/polyfill.c
Outdated
if (bboxErr) { | ||
iterErrorPolygonCompact(iter, bboxErr); | ||
return; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This case may not be testable because presumably the boundary error above would not be E_SUCCESS? Perhaps there exists some index for which cellToBoundary returns 0 but cellToBbox returns non-0?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Related question, do we have fuzzer question of these functions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if this is coverable, will switch to NEVER
if I can't figure out an approach.
We don't have a fuzzer for polygonToCellsExperimental
, but I can add one - that's probably best in a separate PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would be happy to help getting a fuzzer added. Agreed doing that in a separate PR would make the most sense.
@isaacbrodsky I believe the latest commit should close the holes in coverage. |
Thanks for adding this functionality !! |
Well, you can see it was merged two weeks ago, so that's how mature it is :). But we've done a fair amount of testing against the older algo, and it seems to behave as expected. Overlapping mode seems to work as expected, we aren't aware of any issues, but it's hard to extensively test this. The main (expected) issue is that overlapping mode is slower than the other modes, as discussed in this PR. |
Ok, thanks for quick answer ! |
Look great! Has this been released yet? If not, is there a stable tag we could reference? We use the h3-py bindings and it looks like it’s been a bit since the last release. |
Hello H3 friends! 👋 I use H3 often and this PR would be tremendously helpful. Is there any timeline for when a new release might come out with the new polyfill modes? Thank you for all of the hard work that went into this! |
This adds new fuzzers for the `polygonToCellsExperimental` function, based on the existing functions. Since #796 (this PR is based on that branch) adds containment modes, this updates the existing fuzzers to exercise those options too. The estimation functions are adjusted so that the fuzzers pass. This may reduce performance of the new algorithms somewhat, but avoids potential buffer problems. This can be revisited to get them back to how they were intended to work. --------- Co-authored-by: Nick Rabinowitz <[email protected]>
Adds support for full containment mode and overlapping modes in
polygonToCellsExperimental
.iterStepPolygonCompact
. This was very straightforward as we already havecellBoundaryInsidePolygon
polygon available.iterStepPolygonCompact
. This checks center point inclusion first, then shares code with the full containment check, substituting a newcellBoundaryCrossesPolygon
check forcellBoundaryInsidePolygon
.0
forflags
.TODO:
CENTER_CONTAINMENT
instead of0
for the flag value in existing tests.