Skip to content
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

Alternate polygonToCells algorithm #785

Merged
merged 47 commits into from
Oct 31, 2023
Merged
Show file tree
Hide file tree
Changes from 44 commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
f72cbc2
Add scaleBBox, with tests
Sep 25, 2023
8a27b2a
Add cellToChildBBox with tests
Sep 26, 2023
5bc92fc
Cleanup
Sep 26, 2023
0a856f2
Implement bboxIntersects, with tests
Sep 26, 2023
42a1ea6
Add lineIntersectsLine, with tests
Sep 26, 2023
ec1a6f6
Implement cellBoundaryInsidePolygon
Sep 27, 2023
34ba399
Tests and fixes for cellBoundaryCrossesGeoLoop
Sep 27, 2023
5f6ede9
First pass at polyfill algo, untested
Sep 29, 2023
cc6a060
Use const polygon
Sep 29, 2023
0ec7869
Fixed several issues, most tests passing
Sep 30, 2023
793f46e
Fix transmeridian handling
Oct 2, 2023
9eaee77
Comment fix
Oct 2, 2023
519b0b4
Working uncompact with wrapping iterator
Oct 3, 2023
37243fe
Small optimization: Normalize BBox outside loop
Oct 3, 2023
d720d3a
Small optimization, reference cell boundary instead of copy
Oct 3, 2023
10667cc
Small optimization: Update child iterator in place
Oct 3, 2023
0caf37d
Implement polygonToCellsCompact
Oct 3, 2023
9389945
Fix missing file in CMake
Oct 4, 2023
19aa9ca
free bboxes, come and get 'em
Oct 4, 2023
ed3b143
format
Oct 4, 2023
135e5a3
Copyright fix
nrabinowitz Oct 6, 2023
1380aeb
comment fix
nrabinowitz Oct 6, 2023
3cbcafc
copyright fix
nrabinowitz Oct 6, 2023
a1758fe
comment fix
nrabinowitz Oct 6, 2023
6dd99ad
Fix error declaration and division by zero
Oct 6, 2023
b9c4358
Micro-optimizations: faster cellToParent, bbox check on line intersec…
Oct 9, 2023
216500a
Fix transmeridian bbox checks
Oct 9, 2023
77a13fb
Intersects -> overlaps, cheap checks for poles and bbox containment
Oct 10, 2023
0866771
Simplify bboxOverlapsBBox
Oct 10, 2023
29fc0e9
Remove old polyfill algo, update tests
Oct 19, 2023
e15845e
Update CHANGELOG
Oct 19, 2023
8cef837
Add test coverage
Oct 20, 2023
eef2bc5
Restore old algo, rename new to polygonToCellsExperimental
Oct 20, 2023
aa2990b
First pass at faster cellToBBox
Oct 24, 2023
47e1d23
Update scale factor
Oct 24, 2023
b63921b
Use a lookup table for res0 bounding boxes
Oct 24, 2023
dad85b0
Add test coverage
Oct 24, 2023
3fe75a7
Copy tests for testPolygonToCellsReported
Oct 24, 2023
475d8f6
Re-add test for uncovered lines
Oct 25, 2023
c3c206d
Restore simpler NORMALIZE_LNG macro for point-in-poly
Oct 25, 2023
862dd86
Use switch-based function for normalizeLng
Oct 25, 2023
6c55f50
Move normalizeLng to latlng, fix tests
Oct 26, 2023
b774725
Add separate benchmark for new polyfill
Oct 26, 2023
5453092
Fix switch to always return
Oct 27, 2023
8652b4e
Update and tests for baseCellNumToCell
Oct 31, 2023
6b94307
Drop dupe tests, malloc -> calloc
Oct 31, 2023
6f0a122
Fix calloc
Oct 31, 2023
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ The public API of this library consists of the functions declared in file

## [Unreleased]
### Changed
- Replace internal algorithm for `polygonToCells` with a new version that is more memory-efficient (#785)
- Reorganize tests into public / internal. (#762)
- Performance enhancement for aarch64, should not affect other platforms (#790, #792)

Expand Down
8 changes: 8 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ set(LIB_SOURCE_FILES
src/h3lib/include/bbox.h
src/h3lib/include/polygon.h
src/h3lib/include/polygonAlgos.h
src/h3lib/include/polyfill.h
src/h3lib/include/h3Index.h
src/h3lib/include/directedEdge.h
src/h3lib/include/latLng.h
Expand All @@ -146,6 +147,7 @@ set(LIB_SOURCE_FILES
src/h3lib/lib/coordijk.c
src/h3lib/lib/bbox.c
src/h3lib/lib/polygon.c
src/h3lib/lib/polyfill.c
src/h3lib/lib/h3Index.c
src/h3lib/lib/vec2d.c
src/h3lib/lib/vec3d.c
Expand Down Expand Up @@ -192,7 +194,9 @@ set(OTHER_SOURCE_FILES
src/apps/testapps/testVertexGraphInternal.c
src/apps/testapps/testCompactCells.c
src/apps/testapps/testPolygonToCells.c
src/apps/testapps/testPolygonToCellsExperimental.c
src/apps/testapps/testPolygonToCellsReported.c
src/apps/testapps/testPolygonToCellsReportedExperimental.c
src/apps/testapps/testPentagonIndexes.c
src/apps/testapps/testGridDisk.c
src/apps/testapps/testGridDiskInternal.c
Expand All @@ -209,6 +213,7 @@ set(OTHER_SOURCE_FILES
src/apps/testapps/testCellToLatLng.c
src/apps/testapps/testCellToCenterChild.c
src/apps/testapps/testCellToChildren.c
src/apps/testapps/testCellToBBoxExhaustive.c
src/apps/testapps/testCellToChildPos.c
src/apps/testapps/testGetIcosahedronFaces.c
src/apps/testapps/testLatLng.c
Expand All @@ -220,6 +225,7 @@ set(OTHER_SOURCE_FILES
src/apps/testapps/testVertexInternal.c
src/apps/testapps/testVertexExhaustive.c
src/apps/testapps/testPolygonInternal.c
src/apps/testapps/testPolyfillInternal.c
src/apps/testapps/testVec2dInternal.c
src/apps/testapps/testVec3dInternal.c
src/apps/testapps/testDirectedEdge.c
Expand Down Expand Up @@ -270,6 +276,7 @@ set(OTHER_SOURCE_FILES
src/apps/fuzzers/fuzzerInternalAlgos.c
src/apps/fuzzers/fuzzerInternalCoordIjk.c
src/apps/benchmarks/benchmarkPolygonToCells.c
src/apps/benchmarks/benchmarkPolygonToCellsExperimental.c
src/apps/benchmarks/benchmarkPolygon.c
src/apps/benchmarks/benchmarkCellsToLinkedMultiPolygon.c
src/apps/benchmarks/benchmarkCellToChildren.c
Expand Down Expand Up @@ -566,6 +573,7 @@ if(BUILD_BENCHMARKS)
add_h3_benchmark(benchmarkCellsToLinkedMultiPolygon src/apps/benchmarks/benchmarkCellsToLinkedMultiPolygon.c)
add_h3_benchmark(benchmarkCellToChildren src/apps/benchmarks/benchmarkCellToChildren.c)
add_h3_benchmark(benchmarkPolygonToCells src/apps/benchmarks/benchmarkPolygonToCells.c)
add_h3_benchmark(benchmarkPolygonToCellsExperimental src/apps/benchmarks/benchmarkPolygonToCellsExperimental.c)
if(ENABLE_REQUIRES_ALL_SYMBOLS)
add_h3_benchmark(benchmarkPolygon src/apps/benchmarks/benchmarkPolygon.c)
endif()
Expand Down
4 changes: 4 additions & 0 deletions CMakeTests.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,9 @@ add_h3_test(testCellsToLinkedMultiPolygon src/apps/testapps/testCellsToLinkedMul
add_h3_test(testH3SetToVertexGraphInternal src/apps/testapps/testH3SetToVertexGraphInternal.c)
add_h3_test(testLinkedGeoInternal src/apps/testapps/testLinkedGeoInternal.c)
add_h3_test(testPolygonToCells src/apps/testapps/testPolygonToCells.c)
add_h3_test(testPolygonToCellsExperimental src/apps/testapps/testPolygonToCellsExperimental.c)
add_h3_test(testPolygonToCellsReported src/apps/testapps/testPolygonToCellsReported.c)
add_h3_test(testPolygonToCellsReportedExperimental src/apps/testapps/testPolygonToCellsReportedExperimental.c)
add_h3_test(testVertexGraphInternal src/apps/testapps/testVertexGraphInternal.c)
add_h3_test(testDirectedEdge src/apps/testapps/testDirectedEdge.c)
add_h3_test(testLatLng src/apps/testapps/testLatLng.c)
Expand All @@ -195,6 +197,7 @@ add_h3_test(testBBoxInternal src/apps/testapps/testBBoxInternal.c)
add_h3_test(testVertex src/apps/testapps/testVertex.c)
add_h3_test(testVertexInternal src/apps/testapps/testVertexInternal.c)
add_h3_test(testPolygonInternal src/apps/testapps/testPolygonInternal.c)
add_h3_test(testPolyfillInternal src/apps/testapps/testPolyfillInternal.c)
add_h3_test(testVec2dInternal src/apps/testapps/testVec2dInternal.c)
add_h3_test(testVec3dInternal src/apps/testapps/testVec3dInternal.c)
add_h3_test(testCellToLocalIj src/apps/testapps/testCellToLocalIj.c)
Expand Down Expand Up @@ -223,6 +226,7 @@ add_h3_test(testCellToLocalIjExhaustive src/apps/testapps/testCellToLocalIjExhau
add_h3_test(testGridPathCellsExhaustive src/apps/testapps/testGridPathCellsExhaustive.c)
add_h3_test(testGridDistanceExhaustive src/apps/testapps/testGridDistanceExhaustive.c)
add_h3_test(testH3CellAreaExhaustive src/apps/testapps/testH3CellAreaExhaustive.c)
add_h3_test(testCellToBBoxExhaustive src/apps/testapps/testCellToBBoxExhaustive.c)

add_h3_cli_test(testCliCellToLatLng "cellToLatLng -c 8928342e20fffff" "37.5012466151, -122.5003039349")
add_h3_cli_test(testCliLatLngToCell "latLngToCell --lat 20 --lng 123 -r 2" "824b9ffffffffff")
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,13 +112,13 @@ You can run a faster test suite that excludes the most expensive tests with `mak

#### Coverage

You can generate a code coverage report if `lcov` is installed, and if the project was built with the `CMAKE_BUILD_TYPE=Debug` option.
You can generate a code coverage report if `lcov` is installed, and if the project was built with the `CMAKE_BUILD_TYPE=Debug` and `ENABLE_COVERAGE=ON` options.
For example, from a clean repository, you could run:

```
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Debug ..
cmake -DCMAKE_BUILD_TYPE=Debug -DENABLE_COVERAGE=ON ..
make
make coverage
```
Expand Down
3 changes: 3 additions & 0 deletions src/apps/applib/include/utility.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

#include <stdio.h>

#include "bbox.h"
#include "coordijk.h"
#include "h3api.h"

Expand All @@ -46,6 +47,8 @@ void geoPrintNoFmt(const LatLng *p);
void geoPrintlnNoFmt(const LatLng *p);
void cellBoundaryPrint(const CellBoundary *b);
void cellBoundaryPrintln(const CellBoundary *b);
void bboxPrint(const BBox *bbox);
void bboxPrintln(const BBox *bbox);

void randomGeo(LatLng *p);

Expand Down
12 changes: 12 additions & 0 deletions src/apps/applib/lib/utility.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,18 @@ void cellBoundaryPrintln(const CellBoundary *b) {
printf("}\n");
}

void bboxPrint(const BBox *bbox) {
printf(
"bbox {%.9lf, %.9lf, %.9lf, %.9lf}", H3_EXPORT(radsToDegs)(bbox->north),
H3_EXPORT(radsToDegs)(bbox->south), H3_EXPORT(radsToDegs)(bbox->east),
H3_EXPORT(radsToDegs)(bbox->west));
}

void bboxPrintln(const BBox *bbox) {
bboxPrint(bbox);
printf("\n");
}

/**
* Apply callback for every unidirectional edge at the given resolution.
*/
Expand Down
146 changes: 146 additions & 0 deletions src/apps/benchmarks/benchmarkPolygonToCellsExperimental.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
/*
* Copyright 2017, 2020-2021 Uber Technologies, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "algos.h"
#include "benchmark.h"
#include "h3api.h"
#include "polyfill.h"

// Fixtures
LatLng sfVerts[] = {
{0.659966917655, -2.1364398519396}, {0.6595011102219, -2.1359434279405},
{0.6583348114025, -2.1354884206045}, {0.6581220034068, -2.1382437718946},
{0.6594479998527, -2.1384597563896}, {0.6599990002976, -2.1376771158464}};
GeoLoop sfGeoLoop;
GeoPolygon sfGeoPolygon;

LatLng alamedaVerts[] = {{0.6597959342671712, -2.133241848488897},
{0.6597959348850178, -2.133241848495878},
{0.6598352639563587, -2.1331688423977755},
{0.6601346536539207, -2.13270417124178},
{0.6601594763880223, -2.1326680320633344},
{0.6601512007732382, -2.1326594176574534},
{0.6598535076212304, -2.1323049630593562},
{0.6596565748646488, -2.132069889917591},
{0.6594645035394391, -2.131843148468039},
{0.6593438094209757, -2.1316994860539844},
{0.6591174422311021, -2.131429776816562},
{0.658849344286881, -2.1311111485483867},
{0.6588348862079956, -2.1310988536794455},
{0.6586273138317915, -2.131668420800747},
{0.6583729538174264, -2.132370426573979},
{0.6582479206289285, -2.132718691911663},
{0.6582322393220743, -2.1327614200082317},
{0.6583003647098981, -2.132837478687196},
{0.6584457274847966, -2.132827956758973},
{0.6585526679060995, -2.1330231566043203},
{0.6587379099516777, -2.1331602726234538},
{0.6587273684736642, -2.1332676321559063},
{0.6584638025857692, -2.133305719954319},
{0.6583545950288919, -2.1334323622944993},
{0.6584427148370682, -2.1335885223323947},
{0.6584715236640714, -2.133649780409862},
{0.6584715242505019, -2.133649780481421},
{0.658474662092443, -2.1336459234695804},
{0.6591666596433436, -2.1348354004882926},
{0.6591809355063646, -2.1348424115474565},
{0.6593477498700266, -2.1351460576998926},
{0.6597155087395117, -2.1351049454274},
{0.6597337410387994, -2.135113899444683},
{0.6598277083823935, -2.1351065432309517},
{0.659837290351688, -2.1350919904836627},
{0.6598391300107502, -2.1350911731005957},
{0.6598335712627461, -2.1350732321630828},
{0.6597162034032434, -2.134664026354221},
{0.6596785831942451, -2.134651647657116},
{0.6596627824684727, -2.13458880305965},
{0.6596785832500957, -2.134530719130462},
{0.6596093592822273, -2.13428052987356},
{0.6596116166352313, -2.134221493755564},
{0.6595973199434513, -2.134146270344056},
{0.6595536764042369, -2.1340805688066653},
{0.6594611172376618, -2.133753252031165},
{0.6594829406269346, -2.1337342082305697},
{0.6594897134102581, -2.1337104032834757},
{0.6597920983773051, -2.1332343063312775},
{0.6597959342671712, -2.133241848488897}};
GeoLoop alamedaGeoLoop;
GeoPolygon alamedaGeoPolygon;

LatLng southernVerts[] = {{0.6367481147484843, -2.1290865397798906},
{0.6367481152301953, -2.129086539469222},
{0.6367550754426818, -2.128887436716856},
{0.6367816002113981, -2.1273204058681094},
{0.6380814125349741, -2.127201274803692},
{0.6388614350074809, -2.12552061082428},
{0.6393520289210095, -2.124274316938293},
{0.639524834205869, -2.122168447308359},
{0.6405714857447717, -2.122083222593005},
{0.640769478635285, -2.120979885974894},
{0.6418936996869471, -2.1147667448862255},
{0.6419094141707652, -2.1146521242709584},
{0.6269997808948107, -2.1038647304637257},
{0.6252080524974937, -2.1195521728170457},
{0.626379700264057, -2.1203708632511162},
{0.6282200029232767, -2.1210412050690723},
{0.6283657301211779, -2.1219496416754393},
{0.6305651783819565, -2.123628532238016},
{0.6308259852882764, -2.124225549648211},
{0.6317049665784865, -2.124887756638367},
{0.6323403882676475, -2.1266205835454053},
{0.6334397909415498, -2.1277211741619553},
{0.6367481147484843, -2.1290865397798906}};
GeoLoop southernGeoLoop;
GeoPolygon southernGeoPolygon;

BEGIN_BENCHMARKS();

sfGeoLoop.numVerts = 6;
sfGeoLoop.verts = sfVerts;
sfGeoPolygon.geoloop = sfGeoLoop;

alamedaGeoLoop.numVerts = 50;
alamedaGeoLoop.verts = alamedaVerts;
alamedaGeoPolygon.geoloop = alamedaGeoLoop;

southernGeoLoop.numVerts = 23;
southernGeoLoop.verts = southernVerts;
southernGeoPolygon.geoloop = southernGeoLoop;

int64_t numHexagons;
H3Index *hexagons;

BENCHMARK(polygonToCellsSF, 500, {
H3_EXPORT(maxPolygonToCellsSize)(&sfGeoPolygon, 9, 0, &numHexagons);
hexagons = calloc(numHexagons, sizeof(H3Index));
H3_EXPORT(polygonToCellsExperimental)(&sfGeoPolygon, 9, 0, hexagons);
free(hexagons);
});

BENCHMARK(polygonToCellsAlameda, 500, {
H3_EXPORT(maxPolygonToCellsSize)(&alamedaGeoPolygon, 9, 0, &numHexagons);
hexagons = calloc(numHexagons, sizeof(H3Index));
H3_EXPORT(polygonToCellsExperimental)(&alamedaGeoPolygon, 9, 0, hexagons);
free(hexagons);
});

BENCHMARK(polygonToCellsSouthernExpansion, 10, {
H3_EXPORT(maxPolygonToCellsSize)(&southernGeoPolygon, 9, 0, &numHexagons);
hexagons = calloc(numHexagons, sizeof(H3Index));
H3_EXPORT(polygonToCellsExperimental)(&southernGeoPolygon, 9, 0, hexagons);
free(hexagons);
});

END_BENCHMARKS();
Loading
Loading