ext/h3/src/src/apps/testapps/testPolyfill.c in h3-3.6.2 vs ext/h3/src/src/apps/testapps/testPolyfill.c in h3-3.7.1
- old
+ new
@@ -13,15 +13,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdlib.h>
+
#include "algos.h"
#include "constants.h"
#include "geoCoord.h"
#include "h3Index.h"
#include "test.h"
+#include "utility.h"
// Fixtures
static GeoCoord sfVerts[] = {
{0.659966917655, -2.1364398519396}, {0.6595011102219, -2.1359434279405},
{0.6583348114025, -2.1354884206045}, {0.6581220034068, -2.1382437718946},
@@ -39,18 +41,73 @@
{0.659966917655, -2.1364398519395},
{0.659966917655, -2.1364398519396}};
static Geofence emptyGeofence = {.numVerts = 3, .verts = emptyVerts};
static GeoPolygon emptyGeoPolygon;
-static int countActualHexagons(H3Index* hexagons, int numHexagons) {
- int actualNumHexagons = 0;
- for (int i = 0; i < numHexagons; i++) {
- if (hexagons[i] != 0) {
- actualNumHexagons++;
+/**
+ * Return true if the cell crosses the meridian.
+ */
+static bool isTransmeridianCell(H3Index h) {
+ GeoBoundary bndry;
+ H3_EXPORT(h3ToGeoBoundary)(h, &bndry);
+
+ double minLon = M_PI, maxLon = -M_PI;
+ for (int i = 0; i < bndry.numVerts; i++) {
+ if (bndry.verts[i].lon < minLon) minLon = bndry.verts[i].lon;
+ if (bndry.verts[i].lon > maxLon) maxLon = bndry.verts[i].lon;
+ }
+
+ return maxLon - minLon > M_PI - (M_PI / 4);
+}
+
+static void fillIndex_assertions(H3Index h) {
+ if (isTransmeridianCell(h)) {
+ // TODO: these do not work correctly
+ return;
+ }
+
+ int currentRes = H3_EXPORT(h3GetResolution)(h);
+ // TODO: Not testing more than one depth because the assertions fail.
+ for (int nextRes = currentRes; nextRes <= currentRes + 1; nextRes++) {
+ GeoBoundary bndry;
+ H3_EXPORT(h3ToGeoBoundary)(h, &bndry);
+ GeoPolygon polygon = {
+ .geofence = {.numVerts = bndry.numVerts, .verts = bndry.verts},
+ .numHoles = 0,
+ .holes = 0};
+
+ int polyfillSize = H3_EXPORT(maxPolyfillSize)(&polygon, nextRes);
+ H3Index* polyfillOut = calloc(polyfillSize, sizeof(H3Index));
+ H3_EXPORT(polyfill)(&polygon, nextRes, polyfillOut);
+
+ int polyfillCount = countActualHexagons(polyfillOut, polyfillSize);
+
+ int childrenSize = H3_EXPORT(maxH3ToChildrenSize)(h, nextRes);
+ H3Index* children = calloc(childrenSize, sizeof(H3Index));
+ H3_EXPORT(h3ToChildren)(h, nextRes, children);
+
+ int h3ToChildrenCount = countActualHexagons(children, childrenSize);
+
+ t_assert(polyfillCount == h3ToChildrenCount,
+ "Polyfill count matches h3ToChildren count");
+
+ for (int i = 0; i < childrenSize; i++) {
+ bool found = false;
+ if (children[i] == H3_NULL) continue;
+ for (int j = 0; j < polyfillSize; j++) {
+ if (polyfillOut[j] == children[i]) {
+ found = true;
+ break;
+ }
+ }
+ t_assert(found,
+ "All indexes match between polyfill and h3ToChildren");
}
+
+ free(polyfillOut);
+ free(children);
}
- return actualNumHexagons;
}
SUITE(polyfill) {
sfGeoPolygon.geofence = sfGeofence;
sfGeoPolygon.numHoles = 0;
@@ -62,17 +119,17 @@
emptyGeoPolygon.geofence = emptyGeofence;
emptyGeoPolygon.numHoles = 0;
TEST(maxPolyfillSize) {
int numHexagons = H3_EXPORT(maxPolyfillSize)(&sfGeoPolygon, 9);
- t_assert(numHexagons == 7057, "got expected max polyfill size");
+ t_assert(numHexagons == 5613, "got expected max polyfill size");
numHexagons = H3_EXPORT(maxPolyfillSize)(&holeGeoPolygon, 9);
- t_assert(numHexagons == 7057, "got expected max polyfill size (hole)");
+ t_assert(numHexagons == 5613, "got expected max polyfill size (hole)");
numHexagons = H3_EXPORT(maxPolyfillSize)(&emptyGeoPolygon, 9);
- t_assert(numHexagons == 1, "got expected max polyfill size (empty)");
+ t_assert(numHexagons == 15, "got expected max polyfill size (empty)");
}
TEST(polyfill) {
int numHexagons = H3_EXPORT(maxPolyfillSize)(&sfGeoPolygon, 9);
H3Index* hexagons = calloc(numHexagons, sizeof(H3Index));
@@ -297,7 +354,13 @@
}
}
t_assert(found == 1, "one index found");
t_assert(numPentagons == 1, "one pentagon found");
free(hexagons);
+ }
+
+ TEST(fillIndex) {
+ iterateAllIndexesAtRes(0, fillIndex_assertions);
+ iterateAllIndexesAtRes(1, fillIndex_assertions);
+ iterateAllIndexesAtRes(2, fillIndex_assertions);
}
}