@@ -516,4 +516,112 @@ SUITE(polygonToCells) {
516516 free (found );
517517 free (search );
518518 }
519+
520+ TEST (polygonToCellsBarbell ) {
521+ // Two lobes connected by a bridge thinner than a hexagon
522+ LatLng verts [] = {
523+ {0.010 , 0.000 }, {0.010 , 0.010 }, {0.000 , 0.010 }, // Lobe 1
524+ {0.0051 , 0.010 }, {0.0051 , 0.050 }, // Bridge top
525+ {0.000 , 0.050 }, {0.000 , 0.060 }, {0.010 , 0.060 }, // Lobe 2
526+ {0.010 , 0.050 }, // Lobe 2
527+ {0.0050 , 0.050 }, {0.0050 , 0.010 }, // Bridge bottom
528+ {0.000 , 0.000 } // Close
529+ };
530+ GeoLoop loop = {.numVerts = 12 , .verts = verts };
531+ GeoPolygon polygon = {.geoloop = loop , .numHoles = 0 , .holes = NULL };
532+
533+ int res = 9 ;
534+ int64_t numHexagons ;
535+ t_assertSuccess (
536+ H3_EXPORT (maxPolygonToCellsSize )(& polygon , res , 0 , & numHexagons ));
537+ H3Index * hexagons = calloc (numHexagons , sizeof (H3Index ));
538+
539+ t_assertSuccess (H3_EXPORT (polygonToCells )(& polygon , res , 0 , hexagons ));
540+ int64_t count = countNonNullIndexes (hexagons , numHexagons );
541+
542+ // Expect hexes in both lobes. If it was a flood-fill, it would only
543+ // find ~half.
544+ t_assert (count > 1000 , "Should find hexagons in both barbell lobes" );
545+ free (hexagons );
546+ }
547+
548+ TEST (polygonToCellsSplittingHole ) {
549+ // A square with a hole that almost cuts it in half
550+ LatLng outerVerts [] = {
551+ {0.0 , 0.0 }, {0.0 , 0.08 }, {0.08 , 0.08 }, {0.08 , 0.0 }};
552+ GeoLoop outerLoop = {.numVerts = 4 , .verts = outerVerts };
553+
554+ LatLng holeVerts [] = {
555+ {0.0001 , 0.03 }, {0.0799 , 0.03 }, {0.0799 , 0.05 }, {0.0001 , 0.05 }};
556+ GeoLoop holeLoop = {.numVerts = 4 , .verts = holeVerts };
557+
558+ GeoPolygon polygon = {
559+ .geoloop = outerLoop , .numHoles = 1 , .holes = & holeLoop };
560+
561+ int res = 9 ;
562+ int64_t numHexagons ;
563+ t_assertSuccess (
564+ H3_EXPORT (maxPolygonToCellsSize )(& polygon , res , 0 , & numHexagons ));
565+ H3Index * hexagons = calloc (numHexagons , sizeof (H3Index ));
566+
567+ t_assertSuccess (H3_EXPORT (polygonToCells )(& polygon , res , 0 , hexagons ));
568+ int64_t count = countNonNullIndexes (hexagons , numHexagons );
569+
570+ t_assert (count > 500 ,
571+ "Should find hexagons on both sides of a splitting hole" );
572+ free (hexagons );
573+ }
574+
575+ TEST (polygonToCellsMultiIslandSerpent ) {
576+ // A winding shape that results in 3+ disconnected cell clusters
577+ LatLng verts [] = {
578+ {0.00 , 0.00 }, {0.01 , 0.00 }, {0.01 , 0.01 }, // Island 1
579+ {0.0051 , 0.01 }, {0.0051 , 0.02 }, // Neck 1
580+ {0.00 , 0.02 }, {0.00 , 0.03 }, {0.01 , 0.03 }, // Island 2
581+ {0.0051 , 0.03 }, {0.0051 , 0.04 }, // Neck 2
582+ {0.00 , 0.04 }, {0.00 , 0.05 }, {0.01 , 0.05 }, // Island 3
583+ {0.01 , 0.06 }, {-0.01 , 0.06 }, // Back wall
584+ {-0.01 , 0.00 } // Close
585+ };
586+ GeoLoop loop = {.numVerts = 16 , .verts = verts };
587+ GeoPolygon polygon = {.geoloop = loop , .numHoles = 0 , .holes = NULL };
588+
589+ int res = 9 ;
590+ int64_t numHexagons ;
591+ t_assertSuccess (
592+ H3_EXPORT (maxPolygonToCellsSize )(& polygon , res , 0 , & numHexagons ));
593+ H3Index * hexagons = calloc (numHexagons , sizeof (H3Index ));
594+
595+ t_assertSuccess (H3_EXPORT (polygonToCells )(& polygon , res , 0 , hexagons ));
596+ int64_t count = countNonNullIndexes (hexagons , numHexagons );
597+
598+ t_assert (count > 1500 , "Should find hexagons in all 3 serpent islands" );
599+ free (hexagons );
600+ }
601+
602+ TEST (polygonToCellsTransmeridianBarbell ) {
603+ // Barbell shape crossing the 180/-180 meridian
604+ double east = M_PI - 0.001 ;
605+ double west = - M_PI + 0.001 ;
606+
607+ LatLng verts [] = {{0.01 , east }, {0.01 , M_PI }, {0.00 , M_PI },
608+ {0.0051 , M_PI }, {0.0051 , - M_PI }, {0.00 , - M_PI },
609+ {0.00 , west }, {0.01 , west }, {0.01 , - M_PI },
610+ {0.0050 , - M_PI }, {0.0050 , M_PI }, {0.00 , east }};
611+ GeoLoop loop = {.numVerts = 12 , .verts = verts };
612+ GeoPolygon polygon = {.geoloop = loop , .numHoles = 0 , .holes = NULL };
613+
614+ int res = 9 ;
615+ int64_t numHexagons ;
616+ t_assertSuccess (
617+ H3_EXPORT (maxPolygonToCellsSize )(& polygon , res , 0 , & numHexagons ));
618+ H3Index * hexagons = calloc (numHexagons , sizeof (H3Index ));
619+
620+ t_assertSuccess (H3_EXPORT (polygonToCells )(& polygon , res , 0 , hexagons ));
621+ int64_t count = countNonNullIndexes (hexagons , numHexagons );
622+
623+ t_assert (count > 10 ,
624+ "Should find hexagons on both sides of antimeridian" );
625+ free (hexagons );
626+ }
519627}
0 commit comments