h3 3.4.4 → 3.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -0
- data/Gemfile.lock +1 -1
- data/README.md +2 -1
- data/ext/h3/Makefile +1 -1
- data/ext/h3/src/.gitignore +2 -1
- data/ext/h3/src/CHANGELOG.md +9 -0
- data/ext/h3/src/CMakeLists.txt +72 -45
- data/ext/h3/src/RELEASE.md +2 -1
- data/ext/h3/src/VERSION +1 -1
- data/ext/h3/src/docs/api/hierarchy.md +2 -0
- data/ext/h3/src/docs/api/indexing.md +3 -1
- data/ext/h3/src/docs/api/inspection.md +20 -0
- data/ext/h3/src/docs/api/misc.md +2 -0
- data/ext/h3/src/docs/api/regions.md +2 -0
- data/ext/h3/src/docs/api/traversal.md +2 -0
- data/ext/h3/src/docs/api/uniedge.md +2 -0
- data/ext/h3/src/docs/community/bindings.md +4 -0
- data/ext/h3/src/docs/community/tutorials.md +12 -0
- data/ext/h3/src/scripts/update_version.sh +50 -0
- data/ext/h3/src/src/apps/applib/include/args.h +122 -0
- data/ext/h3/src/src/apps/applib/include/utility.h +5 -62
- data/ext/h3/src/src/apps/applib/lib/args.c +216 -0
- data/ext/h3/src/src/apps/applib/lib/utility.c +40 -206
- data/ext/h3/src/src/apps/filters/geoToH3.c +7 -9
- data/ext/h3/src/src/apps/filters/h3ToComponents.c +50 -47
- data/ext/h3/src/src/apps/filters/h3ToGeo.c +7 -30
- data/ext/h3/src/src/apps/filters/h3ToGeoBoundary.c +7 -27
- data/ext/h3/src/src/apps/filters/h3ToLocalIj.c +42 -25
- data/ext/h3/src/src/apps/filters/hexRange.c +43 -24
- data/ext/h3/src/src/apps/filters/kRing.c +4 -4
- data/ext/h3/src/src/apps/filters/localIjToH3.c +63 -21
- data/ext/h3/src/src/apps/miscapps/h3ToGeoBoundaryHier.c +68 -44
- data/ext/h3/src/src/apps/miscapps/h3ToGeoHier.c +68 -43
- data/ext/h3/src/src/apps/miscapps/h3ToHier.c +48 -37
- data/ext/h3/src/src/apps/testapps/mkRandGeo.c +32 -27
- data/ext/h3/src/src/apps/testapps/mkRandGeoBoundary.c +33 -28
- data/ext/h3/src/src/apps/testapps/testH3GetFaces.c +136 -0
- data/ext/h3/src/src/h3lib/include/faceijk.h +19 -7
- data/ext/h3/src/src/h3lib/include/h3api.h.in +12 -1
- data/ext/h3/src/src/h3lib/lib/algos.c +7 -2
- data/ext/h3/src/src/h3lib/lib/faceijk.c +135 -103
- data/ext/h3/src/src/h3lib/lib/h3Index.c +86 -5
- data/lib/h3/bindings/private.rb +1 -0
- data/lib/h3/inspection.rb +34 -0
- data/lib/h3/version.rb +1 -1
- data/spec/inspection_spec.rb +33 -1
- metadata +6 -2
@@ -1,5 +1,5 @@
|
|
1
1
|
/*
|
2
|
-
* Copyright 2016-
|
2
|
+
* Copyright 2016-2019 Uber Technologies, Inc.
|
3
3
|
*
|
4
4
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
5
5
|
* you may not use this file except in compliance with the License.
|
@@ -394,6 +394,17 @@ int H3_EXPORT(h3IsResClassIII)(H3Index h);
|
|
394
394
|
int H3_EXPORT(h3IsPentagon)(H3Index h);
|
395
395
|
/** @} */
|
396
396
|
|
397
|
+
/** @defgroup h3GetFaces h3GetFaces
|
398
|
+
* Functions for h3GetFaces
|
399
|
+
* @{
|
400
|
+
*/
|
401
|
+
/** @brief Max number of icosahedron faces intersected by an index */
|
402
|
+
int H3_EXPORT(maxFaceCount)(H3Index h3);
|
403
|
+
|
404
|
+
/** @brief Find all icosahedron faces intersected by a given H3 index */
|
405
|
+
void H3_EXPORT(h3GetFaces)(H3Index h3, int *out);
|
406
|
+
/** @} */
|
407
|
+
|
397
408
|
/** @defgroup h3IndexesAreNeighbors h3IndexesAreNeighbors
|
398
409
|
* Functions for h3IndexesAreNeighbors
|
399
410
|
* @{
|
@@ -539,12 +539,17 @@ int H3_EXPORT(hexRanges)(H3Index* h3Set, int length, int k, H3Index* out) {
|
|
539
539
|
}
|
540
540
|
|
541
541
|
/**
|
542
|
-
* Returns the hollow
|
542
|
+
* Returns the "hollow" ring of hexagons at exactly grid distance k from
|
543
|
+
* the origin hexagon. In particular, k=0 returns just the origin hexagon.
|
544
|
+
*
|
545
|
+
* A nonzero failure code may be returned in some cases, for example,
|
546
|
+
* if a pentagon is encountered.
|
547
|
+
* Failure cases may be fixed in future versions.
|
543
548
|
*
|
544
549
|
* @param origin Origin location.
|
545
550
|
* @param k k >= 0
|
546
551
|
* @param out Array which must be of size 6 * k (or 1 if k == 0)
|
547
|
-
* @return 0 if
|
552
|
+
* @return 0 if successful; nonzero otherwise.
|
548
553
|
*/
|
549
554
|
int H3_EXPORT(hexRing)(H3Index origin, int k, H3Index* out) {
|
550
555
|
// Short-circuit on 'identity' ring
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/*
|
2
|
-
* Copyright 2016-
|
2
|
+
* Copyright 2016-2019 Uber Technologies, Inc.
|
3
3
|
*
|
4
4
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
5
5
|
* you may not use this file except in compliance with the License.
|
@@ -502,60 +502,10 @@ void _faceIjkToGeo(const FaceIJK* h, int res, GeoCoord* g) {
|
|
502
502
|
* @param g The spherical coordinates of the cell boundary.
|
503
503
|
*/
|
504
504
|
void _faceIjkPentToGeoBoundary(const FaceIJK* h, int res, GeoBoundary* g) {
|
505
|
-
// the vertexes of an origin-centered pentagon in a Class II resolution on a
|
506
|
-
// substrate grid with aperture sequence 33r. The aperture 3 gets us the
|
507
|
-
// vertices, and the 3r gets us back to Class II.
|
508
|
-
// vertices listed ccw from the i-axes
|
509
|
-
CoordIJK vertsCII[NUM_PENT_VERTS] = {
|
510
|
-
{2, 1, 0}, // 0
|
511
|
-
{1, 2, 0}, // 1
|
512
|
-
{0, 2, 1}, // 2
|
513
|
-
{0, 1, 2}, // 3
|
514
|
-
{1, 0, 2}, // 4
|
515
|
-
};
|
516
|
-
|
517
|
-
// the vertexes of an origin-centered pentagon in a Class III resolution on
|
518
|
-
// a substrate grid with aperture sequence 33r7r. The aperture 3 gets us the
|
519
|
-
// vertices, and the 3r7r gets us to Class II. vertices listed ccw from the
|
520
|
-
// i-axes
|
521
|
-
CoordIJK vertsCIII[NUM_PENT_VERTS] = {
|
522
|
-
{5, 4, 0}, // 0
|
523
|
-
{1, 5, 0}, // 1
|
524
|
-
{0, 5, 4}, // 2
|
525
|
-
{0, 1, 5}, // 3
|
526
|
-
{4, 0, 5}, // 4
|
527
|
-
};
|
528
|
-
|
529
|
-
// get the correct set of substrate vertices for this resolution
|
530
|
-
CoordIJK* verts;
|
531
|
-
if (isResClassIII(res))
|
532
|
-
verts = vertsCIII;
|
533
|
-
else
|
534
|
-
verts = vertsCII;
|
535
|
-
|
536
|
-
// adjust the center point to be in an aperture 33r substrate grid
|
537
|
-
// these should be composed for speed
|
538
|
-
FaceIJK centerIJK = *h;
|
539
|
-
_downAp3(¢erIJK.coord);
|
540
|
-
_downAp3r(¢erIJK.coord);
|
541
|
-
|
542
|
-
// if res is Class III we need to add a cw aperture 7 to get to
|
543
|
-
// icosahedral Class II
|
544
505
|
int adjRes = res;
|
545
|
-
|
546
|
-
_downAp7r(¢erIJK.coord);
|
547
|
-
adjRes++;
|
548
|
-
}
|
549
|
-
|
550
|
-
// The center point is now in the same substrate grid as the origin
|
551
|
-
// cell vertices. Add the center point substate coordinates
|
552
|
-
// to each vertex to translate the vertices to that cell.
|
506
|
+
FaceIJK centerIJK = *h;
|
553
507
|
FaceIJK fijkVerts[NUM_PENT_VERTS];
|
554
|
-
|
555
|
-
fijkVerts[v].face = centerIJK.face;
|
556
|
-
_ijkAdd(¢erIJK.coord, &verts[v], &fijkVerts[v].coord);
|
557
|
-
_ijkNormalize(&fijkVerts[v].coord);
|
558
|
-
}
|
508
|
+
_faceIjkPentToVerts(¢erIJK, &adjRes, fijkVerts);
|
559
509
|
|
560
510
|
// convert each vertex to lat/lon
|
561
511
|
// adjust the face of each vertex as appropriate and introduce
|
@@ -567,16 +517,7 @@ void _faceIjkPentToGeoBoundary(const FaceIJK* h, int res, GeoBoundary* g) {
|
|
567
517
|
|
568
518
|
FaceIJK fijk = fijkVerts[v];
|
569
519
|
|
570
|
-
|
571
|
-
int overage = _adjustOverageClassII(&fijk, adjRes, pentLeading4, 1);
|
572
|
-
if (overage == 2) // in a different triangle
|
573
|
-
{
|
574
|
-
while (1) {
|
575
|
-
overage = _adjustOverageClassII(&fijk, adjRes, pentLeading4, 1);
|
576
|
-
if (overage != 2) // not in a different triangle
|
577
|
-
break;
|
578
|
-
}
|
579
|
-
}
|
520
|
+
_adjustPentVertOverage(&fijk, adjRes);
|
580
521
|
|
581
522
|
// all Class III pentagon edges cross icosa edges
|
582
523
|
// note that Class II pentagons have vertices on the edge,
|
@@ -656,77 +597,87 @@ void _faceIjkPentToGeoBoundary(const FaceIJK* h, int res, GeoBoundary* g) {
|
|
656
597
|
}
|
657
598
|
|
658
599
|
/**
|
659
|
-
*
|
660
|
-
* FaceIJK address at a specified resolution.
|
600
|
+
* Get the vertices of a pentagon cell as substrate FaceIJK addresses
|
661
601
|
*
|
662
|
-
* @param
|
663
|
-
* @param res The H3 resolution of the cell.
|
664
|
-
*
|
665
|
-
* @param
|
602
|
+
* @param fijk The FaceIJK address of the cell.
|
603
|
+
* @param res The H3 resolution of the cell. This may be adjusted if
|
604
|
+
* necessary for the substrate grid resolution.
|
605
|
+
* @param fijkVerts Output array for the vertices
|
666
606
|
*/
|
667
|
-
void
|
668
|
-
|
669
|
-
if (isPentagon) {
|
670
|
-
_faceIjkPentToGeoBoundary(h, res, g);
|
671
|
-
return;
|
672
|
-
}
|
673
|
-
|
674
|
-
// the vertexes of an origin-centered cell in a Class II resolution on a
|
607
|
+
void _faceIjkPentToVerts(FaceIJK* fijk, int* res, FaceIJK* fijkVerts) {
|
608
|
+
// the vertexes of an origin-centered pentagon in a Class II resolution on a
|
675
609
|
// substrate grid with aperture sequence 33r. The aperture 3 gets us the
|
676
610
|
// vertices, and the 3r gets us back to Class II.
|
677
611
|
// vertices listed ccw from the i-axes
|
678
|
-
CoordIJK vertsCII[
|
612
|
+
CoordIJK vertsCII[NUM_PENT_VERTS] = {
|
679
613
|
{2, 1, 0}, // 0
|
680
614
|
{1, 2, 0}, // 1
|
681
615
|
{0, 2, 1}, // 2
|
682
616
|
{0, 1, 2}, // 3
|
683
617
|
{1, 0, 2}, // 4
|
684
|
-
{2, 0, 1} // 5
|
685
618
|
};
|
686
619
|
|
687
|
-
// the vertexes of an origin-centered
|
688
|
-
// substrate grid with aperture sequence 33r7r. The aperture 3 gets us the
|
689
|
-
// vertices, and the 3r7r gets us to Class II.
|
690
|
-
//
|
691
|
-
CoordIJK vertsCIII[
|
620
|
+
// the vertexes of an origin-centered pentagon in a Class III resolution on
|
621
|
+
// a substrate grid with aperture sequence 33r7r. The aperture 3 gets us the
|
622
|
+
// vertices, and the 3r7r gets us to Class II. vertices listed ccw from the
|
623
|
+
// i-axes
|
624
|
+
CoordIJK vertsCIII[NUM_PENT_VERTS] = {
|
692
625
|
{5, 4, 0}, // 0
|
693
626
|
{1, 5, 0}, // 1
|
694
627
|
{0, 5, 4}, // 2
|
695
628
|
{0, 1, 5}, // 3
|
696
629
|
{4, 0, 5}, // 4
|
697
|
-
{5, 0, 1} // 5
|
698
630
|
};
|
699
631
|
|
700
632
|
// get the correct set of substrate vertices for this resolution
|
701
633
|
CoordIJK* verts;
|
702
|
-
if (isResClassIII(res))
|
634
|
+
if (isResClassIII(*res))
|
703
635
|
verts = vertsCIII;
|
704
636
|
else
|
705
637
|
verts = vertsCII;
|
706
638
|
|
707
639
|
// adjust the center point to be in an aperture 33r substrate grid
|
708
640
|
// these should be composed for speed
|
709
|
-
|
710
|
-
|
711
|
-
_downAp3r(¢erIJK.coord);
|
641
|
+
_downAp3(&fijk->coord);
|
642
|
+
_downAp3r(&fijk->coord);
|
712
643
|
|
713
644
|
// if res is Class III we need to add a cw aperture 7 to get to
|
714
645
|
// icosahedral Class II
|
715
|
-
|
716
|
-
|
717
|
-
|
718
|
-
adjRes++;
|
646
|
+
if (isResClassIII(*res)) {
|
647
|
+
_downAp7r(&fijk->coord);
|
648
|
+
*res += 1;
|
719
649
|
}
|
720
650
|
|
721
651
|
// The center point is now in the same substrate grid as the origin
|
722
652
|
// cell vertices. Add the center point substate coordinates
|
723
653
|
// to each vertex to translate the vertices to that cell.
|
724
|
-
|
725
|
-
|
726
|
-
fijkVerts[v].
|
727
|
-
_ijkAdd(¢erIJK.coord, &verts[v], &fijkVerts[v].coord);
|
654
|
+
for (int v = 0; v < NUM_PENT_VERTS; v++) {
|
655
|
+
fijkVerts[v].face = fijk->face;
|
656
|
+
_ijkAdd(&fijk->coord, &verts[v], &fijkVerts[v].coord);
|
728
657
|
_ijkNormalize(&fijkVerts[v].coord);
|
729
658
|
}
|
659
|
+
}
|
660
|
+
|
661
|
+
/**
|
662
|
+
* Generates the cell boundary in spherical coordinates for a cell given by a
|
663
|
+
* FaceIJK address at a specified resolution.
|
664
|
+
*
|
665
|
+
* @param h The FaceIJK address of the cell.
|
666
|
+
* @param res The H3 resolution of the cell.
|
667
|
+
* @param isPentagon Whether or not the cell is a pentagon.
|
668
|
+
* @param g The spherical coordinates of the cell boundary.
|
669
|
+
*/
|
670
|
+
void _faceIjkToGeoBoundary(const FaceIJK* h, int res, int isPentagon,
|
671
|
+
GeoBoundary* g) {
|
672
|
+
if (isPentagon) {
|
673
|
+
_faceIjkPentToGeoBoundary(h, res, g);
|
674
|
+
return;
|
675
|
+
}
|
676
|
+
|
677
|
+
int adjRes = res;
|
678
|
+
FaceIJK centerIJK = *h;
|
679
|
+
FaceIJK fijkVerts[NUM_HEX_VERTS];
|
680
|
+
_faceIjkToVerts(¢erIJK, &adjRes, fijkVerts);
|
730
681
|
|
731
682
|
// convert each vertex to lat/lon
|
732
683
|
// adjust the face of each vertex as appropriate and introduce
|
@@ -819,6 +770,70 @@ void _faceIjkToGeoBoundary(const FaceIJK* h, int res, int isPentagon,
|
|
819
770
|
}
|
820
771
|
}
|
821
772
|
|
773
|
+
/**
|
774
|
+
* Get the vertices of a cell as substrate FaceIJK addresses
|
775
|
+
*
|
776
|
+
* @param fijk The FaceIJK address of the cell.
|
777
|
+
* @param res The H3 resolution of the cell. This may be adjusted if
|
778
|
+
* necessary for the substrate grid resolution.
|
779
|
+
* @param fijkVerts Output array for the vertices
|
780
|
+
*/
|
781
|
+
void _faceIjkToVerts(FaceIJK* fijk, int* res, FaceIJK* fijkVerts) {
|
782
|
+
// the vertexes of an origin-centered cell in a Class II resolution on a
|
783
|
+
// substrate grid with aperture sequence 33r. The aperture 3 gets us the
|
784
|
+
// vertices, and the 3r gets us back to Class II.
|
785
|
+
// vertices listed ccw from the i-axes
|
786
|
+
CoordIJK vertsCII[NUM_HEX_VERTS] = {
|
787
|
+
{2, 1, 0}, // 0
|
788
|
+
{1, 2, 0}, // 1
|
789
|
+
{0, 2, 1}, // 2
|
790
|
+
{0, 1, 2}, // 3
|
791
|
+
{1, 0, 2}, // 4
|
792
|
+
{2, 0, 1} // 5
|
793
|
+
};
|
794
|
+
|
795
|
+
// the vertexes of an origin-centered cell in a Class III resolution on a
|
796
|
+
// substrate grid with aperture sequence 33r7r. The aperture 3 gets us the
|
797
|
+
// vertices, and the 3r7r gets us to Class II.
|
798
|
+
// vertices listed ccw from the i-axes
|
799
|
+
CoordIJK vertsCIII[NUM_HEX_VERTS] = {
|
800
|
+
{5, 4, 0}, // 0
|
801
|
+
{1, 5, 0}, // 1
|
802
|
+
{0, 5, 4}, // 2
|
803
|
+
{0, 1, 5}, // 3
|
804
|
+
{4, 0, 5}, // 4
|
805
|
+
{5, 0, 1} // 5
|
806
|
+
};
|
807
|
+
|
808
|
+
// get the correct set of substrate vertices for this resolution
|
809
|
+
CoordIJK* verts;
|
810
|
+
if (isResClassIII(*res))
|
811
|
+
verts = vertsCIII;
|
812
|
+
else
|
813
|
+
verts = vertsCII;
|
814
|
+
|
815
|
+
// adjust the center point to be in an aperture 33r substrate grid
|
816
|
+
// these should be composed for speed
|
817
|
+
_downAp3(&fijk->coord);
|
818
|
+
_downAp3r(&fijk->coord);
|
819
|
+
|
820
|
+
// if res is Class III we need to add a cw aperture 7 to get to
|
821
|
+
// icosahedral Class II
|
822
|
+
if (isResClassIII(*res)) {
|
823
|
+
_downAp7r(&fijk->coord);
|
824
|
+
*res += 1;
|
825
|
+
}
|
826
|
+
|
827
|
+
// The center point is now in the same substrate grid as the origin
|
828
|
+
// cell vertices. Add the center point substate coordinates
|
829
|
+
// to each vertex to translate the vertices to that cell.
|
830
|
+
for (int v = 0; v < NUM_HEX_VERTS; v++) {
|
831
|
+
fijkVerts[v].face = fijk->face;
|
832
|
+
_ijkAdd(&fijk->coord, &verts[v], &fijkVerts[v].coord);
|
833
|
+
_ijkNormalize(&fijkVerts[v].coord);
|
834
|
+
}
|
835
|
+
}
|
836
|
+
|
822
837
|
/**
|
823
838
|
* Adjusts a FaceIJK address in place so that the resulting cell address is
|
824
839
|
* relative to the correct icosahedral face.
|
@@ -831,9 +846,9 @@ void _faceIjkToGeoBoundary(const FaceIJK* h, int res, int isPentagon,
|
|
831
846
|
* @return 0 if on original face (no overage); 1 if on face edge (only occurs
|
832
847
|
* on substrate grids); 2 if overage on new face interior
|
833
848
|
*/
|
834
|
-
|
835
|
-
|
836
|
-
|
849
|
+
Overage _adjustOverageClassII(FaceIJK* fijk, int res, int pentLeading4,
|
850
|
+
int substrate) {
|
851
|
+
Overage overage = NO_OVERAGE;
|
837
852
|
|
838
853
|
CoordIJK* ijk = &fijk->coord;
|
839
854
|
|
@@ -843,10 +858,10 @@ int _adjustOverageClassII(FaceIJK* fijk, int res, int pentLeading4,
|
|
843
858
|
|
844
859
|
// check for overage
|
845
860
|
if (substrate && ijk->i + ijk->j + ijk->k == maxDim) // on edge
|
846
|
-
overage =
|
861
|
+
overage = FACE_EDGE;
|
847
862
|
else if (ijk->i + ijk->j + ijk->k > maxDim) // overage
|
848
863
|
{
|
849
|
-
overage =
|
864
|
+
overage = NEW_FACE;
|
850
865
|
|
851
866
|
const FaceOrientIJK* fijkOrient;
|
852
867
|
if (ijk->k > 0) {
|
@@ -886,8 +901,25 @@ int _adjustOverageClassII(FaceIJK* fijk, int res, int pentLeading4,
|
|
886
901
|
|
887
902
|
// overage points on pentagon boundaries can end up on edges
|
888
903
|
if (substrate && ijk->i + ijk->j + ijk->k == maxDim) // on edge
|
889
|
-
overage =
|
904
|
+
overage = FACE_EDGE;
|
890
905
|
}
|
891
906
|
|
892
907
|
return overage;
|
893
908
|
}
|
909
|
+
|
910
|
+
/**
|
911
|
+
* Adjusts a FaceIJK address for a pentagon vertex in a substrate grid in
|
912
|
+
* place so that the resulting cell address is relative to the correct
|
913
|
+
* icosahedral face.
|
914
|
+
*
|
915
|
+
* @param fijk The FaceIJK address of the cell.
|
916
|
+
* @param res The H3 resolution of the cell.
|
917
|
+
*/
|
918
|
+
Overage _adjustPentVertOverage(FaceIJK* fijk, int res) {
|
919
|
+
int pentLeading4 = 0;
|
920
|
+
Overage overage;
|
921
|
+
do {
|
922
|
+
overage = _adjustOverageClassII(fijk, res, pentLeading4, 1);
|
923
|
+
} while (overage == NEW_FACE);
|
924
|
+
return overage;
|
925
|
+
}
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/*
|
2
|
-
* Copyright 2016-
|
2
|
+
* Copyright 2016-2019 Uber Technologies, Inc.
|
3
3
|
*
|
4
4
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
5
5
|
* you may not use this file except in compliance with the License.
|
@@ -739,13 +739,12 @@ void _h3ToFaceIjk(H3Index h, FaceIJK* fijk) {
|
|
739
739
|
// a pentagon base cell with a leading 4 digit requires special handling
|
740
740
|
int pentLeading4 =
|
741
741
|
(_isBaseCellPentagon(baseCell) && _h3LeadingNonZeroDigit(h) == 4);
|
742
|
-
if (_adjustOverageClassII(fijk, res, pentLeading4, 0)) {
|
742
|
+
if (_adjustOverageClassII(fijk, res, pentLeading4, 0) != NO_OVERAGE) {
|
743
743
|
// if the base cell is a pentagon we have the potential for secondary
|
744
744
|
// overages
|
745
745
|
if (_isBaseCellPentagon(baseCell)) {
|
746
|
-
while (
|
747
|
-
|
748
|
-
}
|
746
|
+
while (_adjustOverageClassII(fijk, res, 0, 0) != NO_OVERAGE)
|
747
|
+
continue;
|
749
748
|
}
|
750
749
|
|
751
750
|
if (res != H3_GET_RESOLUTION(h)) _upAp7r(&fijk->coord);
|
@@ -779,6 +778,88 @@ void H3_EXPORT(h3ToGeoBoundary)(H3Index h3, GeoBoundary* gb) {
|
|
779
778
|
H3_EXPORT(h3IsPentagon)(h3), gb);
|
780
779
|
}
|
781
780
|
|
781
|
+
/**
|
782
|
+
* Returns the max number of possible icosahedron faces an H3 index
|
783
|
+
* may intersect.
|
784
|
+
*
|
785
|
+
* @return int count of faces
|
786
|
+
*/
|
787
|
+
int H3_EXPORT(maxFaceCount)(H3Index h3) {
|
788
|
+
// a pentagon always intersects 5 faces, a hexagon never intersects more
|
789
|
+
// than 2 (but may only intersect 1)
|
790
|
+
return H3_EXPORT(h3IsPentagon)(h3) ? 5 : 2;
|
791
|
+
}
|
792
|
+
|
793
|
+
/**
|
794
|
+
* Find all icosahedron faces intersected by a given H3 index, represented
|
795
|
+
* as integers from 0-19. The array is sparse; since 0 is a valid value,
|
796
|
+
* invalid array values are represented as -1. It is the responsibility of
|
797
|
+
* the caller to filter out invalid values.
|
798
|
+
*
|
799
|
+
* @param h3 The H3 index
|
800
|
+
* @param out Output array. Must be of size maxFaceCount(h3).
|
801
|
+
*/
|
802
|
+
void H3_EXPORT(h3GetFaces)(H3Index h3, int* out) {
|
803
|
+
int res = H3_GET_RESOLUTION(h3);
|
804
|
+
int isPentagon = H3_EXPORT(h3IsPentagon)(h3);
|
805
|
+
|
806
|
+
// We can't use the vertex-based approach here for class II pentagons,
|
807
|
+
// because all their vertices are on the icosahedron edges. Their
|
808
|
+
// direct child pentagons cross the same faces, so use those instead.
|
809
|
+
if (isPentagon && !isResClassIII(res)) {
|
810
|
+
// Note that this would not work for res 15, but this is only run on
|
811
|
+
// Class II pentagons, it should never be invoked for a res 15 index.
|
812
|
+
H3Index childPentagon = makeDirectChild(h3, 0);
|
813
|
+
H3_EXPORT(h3GetFaces)(childPentagon, out);
|
814
|
+
return;
|
815
|
+
}
|
816
|
+
|
817
|
+
// convert to FaceIJK
|
818
|
+
FaceIJK fijk;
|
819
|
+
_h3ToFaceIjk(h3, &fijk);
|
820
|
+
|
821
|
+
// Get all vertices as FaceIJK addresses. For simplicity, always
|
822
|
+
// initialize the array with 6 verts, ignoring the last one for pentagons
|
823
|
+
FaceIJK fijkVerts[NUM_HEX_VERTS];
|
824
|
+
int vertexCount;
|
825
|
+
|
826
|
+
if (isPentagon) {
|
827
|
+
vertexCount = NUM_PENT_VERTS;
|
828
|
+
_faceIjkPentToVerts(&fijk, &res, fijkVerts);
|
829
|
+
} else {
|
830
|
+
vertexCount = NUM_HEX_VERTS;
|
831
|
+
_faceIjkToVerts(&fijk, &res, fijkVerts);
|
832
|
+
}
|
833
|
+
|
834
|
+
// We may not use all of the slots in the output array,
|
835
|
+
// so fill with invalid values to indicate unused slots
|
836
|
+
int faceCount = H3_EXPORT(maxFaceCount)(h3);
|
837
|
+
for (int i = 0; i < faceCount; i++) {
|
838
|
+
out[i] = INVALID_FACE;
|
839
|
+
}
|
840
|
+
|
841
|
+
// add each vertex face, using the output array as a hash set
|
842
|
+
for (int i = 0; i < vertexCount; i++) {
|
843
|
+
FaceIJK* vert = &fijkVerts[i];
|
844
|
+
|
845
|
+
// Adjust overage, determining whether this vertex is
|
846
|
+
// on another face
|
847
|
+
if (isPentagon) {
|
848
|
+
_adjustPentVertOverage(vert, res);
|
849
|
+
} else {
|
850
|
+
_adjustOverageClassII(vert, res, 0, 1);
|
851
|
+
}
|
852
|
+
|
853
|
+
// Save the face to the output array
|
854
|
+
int face = vert->face;
|
855
|
+
int pos = 0;
|
856
|
+
// Find the first empty output position, or the first position
|
857
|
+
// matching the current face
|
858
|
+
while (out[pos] != INVALID_FACE && out[pos] != face) pos++;
|
859
|
+
out[pos] = face;
|
860
|
+
}
|
861
|
+
}
|
862
|
+
|
782
863
|
/**
|
783
864
|
* Returns whether or not a resolution is a Class III grid. Note that odd
|
784
865
|
* resolutions are Class III and even resolutions are Class II.
|