h3 3.6.1 → 3.6.2
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 +12 -0
- data/Gemfile.lock +4 -4
- data/ext/h3/src/.travis.yml +14 -6
- data/ext/h3/src/CHANGELOG.md +3 -0
- data/ext/h3/src/VERSION +1 -1
- data/ext/h3/src/src/apps/testapps/testPolyfill.c +3 -3
- data/ext/h3/src/src/h3lib/include/algos.h +0 -8
- data/ext/h3/src/src/h3lib/include/bbox.h +1 -3
- data/ext/h3/src/src/h3lib/lib/algos.c +38 -240
- data/ext/h3/src/src/h3lib/lib/bbox.c +29 -50
- data/lib/h3/bindings/base.rb +14 -4
- data/lib/h3/bindings/private.rb +9 -9
- data/lib/h3/hierarchy.rb +0 -18
- data/lib/h3/indexing.rb +0 -18
- data/lib/h3/inspection.rb +3 -59
- data/lib/h3/miscellaneous.rb +0 -18
- data/lib/h3/regions.rb +3 -0
- data/lib/h3/traversal.rb +0 -18
- data/lib/h3/unidirectional_edges.rb +5 -60
- data/lib/h3/version.rb +1 -1
- data/spec/geo_json_spec.rb +8 -0
- data/spec/{region_spec.rb → regions_spec.rb} +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c5f225736d5df411fd63eb2cad74c153ba96d6a659cf603ba781bab3497dfcc9
|
4
|
+
data.tar.gz: cc45bd99735019ae9d8442ca948df0ce64dd70aa82fa47eabfe2966ea0d76ea2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 84d534f96a5772628a642ac773224af9d907319a4a576cbb7c772773ba8b2ea3814c9118b90e69f617834484b7e10f117da9f9f4a98be99124238ba105532767
|
7
|
+
data.tar.gz: '098daf9d6a37dfe0a1a7b4458a2d9875ff9456c1f264b61328006f7bc45ac91031f6f24aebd508c1826e884b9f0cbf457daf75691026da83031bf0312d7dd422'
|
data/CHANGELOG.md
CHANGED
@@ -6,6 +6,18 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|
6
6
|
|
7
7
|
We track the MAJOR and MINOR version levels of Uber's H3 project (https://github.com/uber/h3) but maintain independent patch levels so we can make small fixes and non breaking changes.
|
8
8
|
|
9
|
+
## [3.6.2] - 2020-1-8
|
10
|
+
### Changed
|
11
|
+
- Revert new polyfill algorithm until reported issues are fixed.
|
12
|
+
- Remove deprecated methods: (#66)
|
13
|
+
|
14
|
+
## [3.6.1] - 2019-11-23
|
15
|
+
### Fixed
|
16
|
+
- `compact` handles zero length input correctly.
|
17
|
+
- `bboxHexRadius` scaling factor adjusted to guarantee containment for `polyfill`.
|
18
|
+
- `polyfill` new algorithm for up to 3x perf boost.
|
19
|
+
- Fix CMake targets for KML generation.
|
20
|
+
|
9
21
|
## [3.6.0] - 2019-8-14
|
10
22
|
### Added
|
11
23
|
- `center_child` method to find center child at given resolution (#62).
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
h3 (3.6.
|
4
|
+
h3 (3.6.2)
|
5
5
|
ffi (~> 1.9)
|
6
6
|
rgeo-geojson (~> 2.1)
|
7
7
|
zeitwerk (~> 2.1)
|
@@ -17,7 +17,7 @@ GEM
|
|
17
17
|
tins (~> 1.6)
|
18
18
|
diff-lcs (1.3)
|
19
19
|
docile (1.3.1)
|
20
|
-
ffi (1.11.
|
20
|
+
ffi (1.11.3)
|
21
21
|
json (2.1.0)
|
22
22
|
rake (12.3.2)
|
23
23
|
rgeo (2.1.1)
|
@@ -46,7 +46,7 @@ GEM
|
|
46
46
|
thor (0.19.4)
|
47
47
|
tins (1.20.2)
|
48
48
|
yard (0.9.20)
|
49
|
-
zeitwerk (2.2.
|
49
|
+
zeitwerk (2.2.2)
|
50
50
|
|
51
51
|
PLATFORMS
|
52
52
|
ruby
|
@@ -59,4 +59,4 @@ DEPENDENCIES
|
|
59
59
|
yard (~> 0.9)
|
60
60
|
|
61
61
|
BUNDLED WITH
|
62
|
-
1.17.
|
62
|
+
1.17.3
|
data/ext/h3/src/.travis.yml
CHANGED
@@ -31,7 +31,7 @@ addons:
|
|
31
31
|
matrix:
|
32
32
|
include:
|
33
33
|
# Check that clang-format doesn't detect some files are not formatted.
|
34
|
-
-
|
34
|
+
- name: "Formatting check"
|
35
35
|
compiler: clang
|
36
36
|
addons:
|
37
37
|
apt:
|
@@ -41,7 +41,7 @@ matrix:
|
|
41
41
|
- clang-format-5.0
|
42
42
|
script: make format && git diff --exit-code
|
43
43
|
# Submit coverage report to Coveralls.io, also test that prefixing works.
|
44
|
-
-
|
44
|
+
- name: "Coverage and FOSSA report"
|
45
45
|
compiler: gcc
|
46
46
|
addons:
|
47
47
|
apt:
|
@@ -50,12 +50,20 @@ matrix:
|
|
50
50
|
install:
|
51
51
|
- gem install coveralls-lcov
|
52
52
|
before_script:
|
53
|
+
- "curl -H 'Cache-Control: no-cache' https://raw.githubusercontent.com/fossas/fossa-cli/master/install.sh | sudo bash"
|
53
54
|
- cmake -DCMAKE_BUILD_TYPE=Debug -DWARNINGS_AS_ERRORS=ON -DH3_PREFIX=testprefix_ .
|
54
55
|
script:
|
55
|
-
- make
|
56
|
+
- make
|
57
|
+
- make coverage
|
58
|
+
# Test building the website also - needed for FOSSA to pick up dependencies
|
59
|
+
- cd website
|
60
|
+
- npm install
|
61
|
+
- npm run build
|
62
|
+
- cd ..
|
63
|
+
- 'if [ -n "$FOSSA_API_KEY" ]; then fossa; fi'
|
56
64
|
after_success:
|
57
65
|
- coveralls-lcov coverage.cleaned.info
|
58
|
-
-
|
66
|
+
- name: "Valgrind test"
|
59
67
|
compiler: gcc
|
60
68
|
addons:
|
61
69
|
apt:
|
@@ -66,9 +74,9 @@ matrix:
|
|
66
74
|
script:
|
67
75
|
- make
|
68
76
|
- CTEST_OUTPUT_ON_FAILURE=1 make test-fast
|
69
|
-
-
|
77
|
+
- name: "Mac OSX (Xcode 8)"
|
70
78
|
os: osx
|
71
|
-
-
|
79
|
+
- name: "binding-functions target"
|
72
80
|
script:
|
73
81
|
- make binding-functions
|
74
82
|
# Check that the file exists and has contents
|
data/ext/h3/src/CHANGELOG.md
CHANGED
@@ -7,6 +7,9 @@ The public API of this library consists of the functions declared in file
|
|
7
7
|
|
8
8
|
## [Unreleased]
|
9
9
|
|
10
|
+
## [3.6.2] - 2019-12-9
|
11
|
+
- Revert new `polyfill` algorithm until reported issues are fixed. (#293)
|
12
|
+
|
10
13
|
## [3.6.1] - 2019-11-11
|
11
14
|
### Fixed
|
12
15
|
- `compact` handles zero length input correctly. (#278)
|
data/ext/h3/src/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
3.6.
|
1
|
+
3.6.2
|
@@ -64,13 +64,13 @@ SUITE(polyfill) {
|
|
64
64
|
|
65
65
|
TEST(maxPolyfillSize) {
|
66
66
|
int numHexagons = H3_EXPORT(maxPolyfillSize)(&sfGeoPolygon, 9);
|
67
|
-
t_assert(numHexagons ==
|
67
|
+
t_assert(numHexagons == 7057, "got expected max polyfill size");
|
68
68
|
|
69
69
|
numHexagons = H3_EXPORT(maxPolyfillSize)(&holeGeoPolygon, 9);
|
70
|
-
t_assert(numHexagons ==
|
70
|
+
t_assert(numHexagons == 7057, "got expected max polyfill size (hole)");
|
71
71
|
|
72
72
|
numHexagons = H3_EXPORT(maxPolyfillSize)(&emptyGeoPolygon, 9);
|
73
|
-
t_assert(numHexagons ==
|
73
|
+
t_assert(numHexagons == 1, "got expected max polyfill size (empty)");
|
74
74
|
}
|
75
75
|
|
76
76
|
TEST(polyfill) {
|
@@ -40,12 +40,4 @@ void h3SetToVertexGraph(const H3Index* h3Set, const int numHexes,
|
|
40
40
|
// Create a LinkedGeoPolygon from a vertex graph
|
41
41
|
void _vertexGraphToLinkedGeo(VertexGraph* graph, LinkedGeoPolygon* out);
|
42
42
|
|
43
|
-
// Internal function for polyfill that traces a geofence with hexagons of a
|
44
|
-
// specific size
|
45
|
-
int _getEdgeHexagons(const Geofence* geofence, int numHexagons, int res,
|
46
|
-
int* numSearchHexes, H3Index* search, H3Index* found);
|
47
|
-
|
48
|
-
// The new polyfill algorithm. Separated out because it can theoretically fail
|
49
|
-
int _polyfillInternal(const GeoPolygon* geoPolygon, int res, H3Index* out);
|
50
|
-
|
51
43
|
#endif
|
@@ -37,8 +37,6 @@ bool bboxIsTransmeridian(const BBox* bbox);
|
|
37
37
|
void bboxCenter(const BBox* bbox, GeoCoord* center);
|
38
38
|
bool bboxContains(const BBox* bbox, const GeoCoord* point);
|
39
39
|
bool bboxEquals(const BBox* b1, const BBox* b2);
|
40
|
-
int
|
41
|
-
int lineHexEstimate(const GeoCoord* origin, const GeoCoord* destination,
|
42
|
-
int res);
|
40
|
+
int bboxHexRadius(const BBox* bbox, int res);
|
43
41
|
|
44
42
|
#endif
|
@@ -41,7 +41,6 @@
|
|
41
41
|
#define HEX_RANGE_SUCCESS 0
|
42
42
|
#define HEX_RANGE_PENTAGON 1
|
43
43
|
#define HEX_RANGE_K_SUBSEQUENCE 2
|
44
|
-
#define MAX_ONE_RING_SIZE 7
|
45
44
|
|
46
45
|
/**
|
47
46
|
* Directions used for traversing a hexagonal ring counterclockwise around
|
@@ -624,8 +623,9 @@ int H3_EXPORT(hexRing)(H3Index origin, int k, H3Index* out) {
|
|
624
623
|
* maxPolyfillSize returns the number of hexagons to allocate space for when
|
625
624
|
* performing a polyfill on the given GeoJSON-like data structure.
|
626
625
|
*
|
627
|
-
*
|
628
|
-
*
|
626
|
+
* Currently a laughably padded response, being a k-ring that wholly contains
|
627
|
+
* a bounding box of the GeoJSON, but still less wasted memory than initializing
|
628
|
+
* a Python application? ;)
|
629
629
|
*
|
630
630
|
* @param geoPolygon A GeoJSON-like data structure indicating the poly to fill
|
631
631
|
* @param res Hexagon resolution (0-15)
|
@@ -634,18 +634,12 @@ int H3_EXPORT(hexRing)(H3Index origin, int k, H3Index* out) {
|
|
634
634
|
int H3_EXPORT(maxPolyfillSize)(const GeoPolygon* geoPolygon, int res) {
|
635
635
|
// Get the bounding box for the GeoJSON-like struct
|
636
636
|
BBox bbox;
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
//
|
641
|
-
// the
|
642
|
-
|
643
|
-
int totalVerts = geofence.numVerts;
|
644
|
-
for (int i = 0; i < geoPolygon->numHoles; i++) {
|
645
|
-
totalVerts += geoPolygon->holes[i].numVerts;
|
646
|
-
}
|
647
|
-
if (numHexagons < totalVerts) numHexagons = totalVerts;
|
648
|
-
return numHexagons;
|
637
|
+
bboxFromGeofence(&geoPolygon->geofence, &bbox);
|
638
|
+
int minK = bboxHexRadius(&bbox, res);
|
639
|
+
|
640
|
+
// The total number of hexagons to allocate can now be determined by
|
641
|
+
// the k-ring hex allocation helper function.
|
642
|
+
return H3_EXPORT(maxKringSize)(minK);
|
649
643
|
}
|
650
644
|
|
651
645
|
/**
|
@@ -653,108 +647,15 @@ int H3_EXPORT(maxPolyfillSize)(const GeoPolygon* geoPolygon, int res) {
|
|
653
647
|
* zeroed memory, and fills it with the hexagons that are contained by
|
654
648
|
* the GeoJSON-like data structure.
|
655
649
|
*
|
656
|
-
*
|
657
|
-
*
|
658
|
-
*
|
659
|
-
* hexagons are found.
|
650
|
+
* The current implementation is very primitive and slow, but correct,
|
651
|
+
* performing a point-in-poly operation on every hexagon in a k-ring defined
|
652
|
+
* around the given geofence.
|
660
653
|
*
|
661
654
|
* @param geoPolygon The geofence and holes defining the relevant area
|
662
655
|
* @param res The Hexagon resolution (0-15)
|
663
656
|
* @param out The slab of zeroed memory to write to. Assumed to be big enough.
|
664
657
|
*/
|
665
658
|
void H3_EXPORT(polyfill)(const GeoPolygon* geoPolygon, int res, H3Index* out) {
|
666
|
-
// TODO: Eliminate this wrapper with the H3 4.0.0 release
|
667
|
-
int failure = _polyfillInternal(geoPolygon, res, out);
|
668
|
-
// The polyfill algorithm can theoretically fail if the allocated memory is
|
669
|
-
// not large enough for the polygon, but this should be impossible given the
|
670
|
-
// conservative overestimation of the number of hexagons possible.
|
671
|
-
// LCOV_EXCL_START
|
672
|
-
if (failure) {
|
673
|
-
int numHexagons = H3_EXPORT(maxPolyfillSize)(geoPolygon, res);
|
674
|
-
for (int i = 0; i < numHexagons; i++) out[i] = H3_INVALID_INDEX;
|
675
|
-
}
|
676
|
-
// LCOV_EXCL_STOP
|
677
|
-
}
|
678
|
-
|
679
|
-
/**
|
680
|
-
* _getEdgeHexagons takes a given geofence ring (either the main geofence or
|
681
|
-
* one of the holes) and traces it with hexagons and updates the search and
|
682
|
-
* found memory blocks. This is used for determining the initial hexagon set
|
683
|
-
* for the polyfill algorithm to execute on.
|
684
|
-
*
|
685
|
-
* @param geofence The geofence (or hole) to be traced
|
686
|
-
* @param numHexagons The maximum number of hexagons possible for the geofence
|
687
|
-
* (also the bounds of the search and found arrays)
|
688
|
-
* @param res The hexagon resolution (0-15)
|
689
|
-
* @param numSearchHexes The number of hexagons found so far to be searched
|
690
|
-
* @param search The block of memory containing the hexagons to search from
|
691
|
-
* @param found The block of memory containing the hexagons found from the
|
692
|
-
* search
|
693
|
-
*
|
694
|
-
* @return An error code if the hash function cannot insert a found hexagon
|
695
|
-
* into the found array.
|
696
|
-
*/
|
697
|
-
int _getEdgeHexagons(const Geofence* geofence, int numHexagons, int res,
|
698
|
-
int* numSearchHexes, H3Index* search, H3Index* found) {
|
699
|
-
for (int i = 0; i < geofence->numVerts; i++) {
|
700
|
-
GeoCoord origin = geofence->verts[i];
|
701
|
-
GeoCoord destination = i == geofence->numVerts - 1
|
702
|
-
? geofence->verts[0]
|
703
|
-
: geofence->verts[i + 1];
|
704
|
-
const int numHexesEstimate =
|
705
|
-
lineHexEstimate(&origin, &destination, res);
|
706
|
-
for (int j = 0; j < numHexesEstimate; j++) {
|
707
|
-
GeoCoord interpolate;
|
708
|
-
interpolate.lat =
|
709
|
-
(origin.lat * (numHexesEstimate - j) / numHexesEstimate) +
|
710
|
-
(destination.lat * j / numHexesEstimate);
|
711
|
-
interpolate.lon =
|
712
|
-
(origin.lon * (numHexesEstimate - j) / numHexesEstimate) +
|
713
|
-
(destination.lon * j / numHexesEstimate);
|
714
|
-
H3Index pointHex = H3_EXPORT(geoToH3)(&interpolate, res);
|
715
|
-
// A simple hash to store the hexagon, or move to another place if
|
716
|
-
// needed
|
717
|
-
int loc = (int)(pointHex % numHexagons);
|
718
|
-
int loopCount = 0;
|
719
|
-
while (found[loc] != 0) {
|
720
|
-
// If this conditional is reached, the `found` memory block is
|
721
|
-
// too small for the given polygon. This should not happen.
|
722
|
-
if (loopCount > numHexagons) return -1; // LCOV_EXCL_LINE
|
723
|
-
if (found[loc] == pointHex)
|
724
|
-
break; // At least two points of the geofence index to the
|
725
|
-
// same cell
|
726
|
-
loc = (loc + 1) % numHexagons;
|
727
|
-
loopCount++;
|
728
|
-
}
|
729
|
-
if (found[loc] == pointHex)
|
730
|
-
continue; // Skip this hex, already exists in the found hash
|
731
|
-
// Otherwise, set it in the found hash for now
|
732
|
-
found[loc] = pointHex;
|
733
|
-
|
734
|
-
search[*numSearchHexes] = pointHex;
|
735
|
-
(*numSearchHexes)++;
|
736
|
-
}
|
737
|
-
}
|
738
|
-
return 0;
|
739
|
-
}
|
740
|
-
|
741
|
-
/**
|
742
|
-
* _polyfillInternal traces the provided geoPolygon data structure with hexagons
|
743
|
-
* and then iteratively searches through these hexagons and their immediate
|
744
|
-
* neighbors to see if they are contained within the polygon or not. Those that
|
745
|
-
* are found are added to the out array as well as the found array. Once all
|
746
|
-
* hexagons to search are checked, the found hexagons become the new search
|
747
|
-
* array and the found array is wiped and the process repeats until no new
|
748
|
-
* hexagons can be found.
|
749
|
-
*
|
750
|
-
* @param geoPolygon The geofence and holes defining the relevant area
|
751
|
-
* @param res The Hexagon resolution (0-15)
|
752
|
-
* @param out The slab of zeroed memory to write to. Assumed to be big enough.
|
753
|
-
*
|
754
|
-
* @return An error code if any of the hash operations fails to insert a hexagon
|
755
|
-
* into an array of memory.
|
756
|
-
*/
|
757
|
-
int _polyfillInternal(const GeoPolygon* geoPolygon, int res, H3Index* out) {
|
758
659
|
// One of the goals of the polyfill algorithm is that two adjacent polygons
|
759
660
|
// with zero overlap have zero overlapping hexagons. That the hexagons are
|
760
661
|
// uniquely assigned. There are a few approaches to take here, such as
|
@@ -776,139 +677,36 @@ int _polyfillInternal(const GeoPolygon* geoPolygon, int res, H3Index* out) {
|
|
776
677
|
BBox* bboxes = malloc((geoPolygon->numHoles + 1) * sizeof(BBox));
|
777
678
|
assert(bboxes != NULL);
|
778
679
|
bboxesFromGeoPolygon(geoPolygon, bboxes);
|
779
|
-
|
780
|
-
|
781
|
-
|
782
|
-
|
783
|
-
|
784
|
-
|
785
|
-
|
786
|
-
|
787
|
-
//
|
788
|
-
|
789
|
-
|
790
|
-
|
791
|
-
//
|
792
|
-
//
|
793
|
-
|
794
|
-
|
795
|
-
|
796
|
-
|
797
|
-
search, found);
|
798
|
-
// If this branch is reached, we have exceeded the maximum number of
|
799
|
-
// hexagons possible and need to clean up the allocated memory.
|
800
|
-
// LCOV_EXCL_START
|
801
|
-
if (failure) {
|
802
|
-
free(search);
|
803
|
-
free(found);
|
804
|
-
free(bboxes);
|
805
|
-
return failure;
|
806
|
-
}
|
807
|
-
// LCOV_EXCL_STOP
|
808
|
-
|
809
|
-
// 2. Iterate over all holes, trace the polygons defining the holes with
|
810
|
-
// hexagons and add to only the search hash. We're going to temporarily use
|
811
|
-
// the `found` hash to use for dedupe purposes and then re-zero it once
|
812
|
-
// we're done here, otherwise we'd have to scan the whole set on each insert
|
813
|
-
// to make sure there's no duplicates, which is very inefficient.
|
814
|
-
for (int i = 0; i < geoPolygon->numHoles; i++) {
|
815
|
-
Geofence* hole = &(geoPolygon->holes[i]);
|
816
|
-
failure = _getEdgeHexagons(hole, numHexagons, res, &numSearchHexes,
|
817
|
-
search, found);
|
818
|
-
// If this branch is reached, we have exceeded the maximum number of
|
819
|
-
// hexagons possible and need to clean up the allocated memory.
|
820
|
-
// LCOV_EXCL_START
|
821
|
-
if (failure) {
|
822
|
-
free(search);
|
823
|
-
free(found);
|
824
|
-
free(bboxes);
|
825
|
-
return failure;
|
680
|
+
int minK = bboxHexRadius(&bboxes[0], res);
|
681
|
+
int numHexagons = H3_EXPORT(maxKringSize)(minK);
|
682
|
+
|
683
|
+
// Get the center hex
|
684
|
+
GeoCoord center;
|
685
|
+
bboxCenter(&bboxes[0], ¢er);
|
686
|
+
H3Index centerH3 = H3_EXPORT(geoToH3)(¢er, res);
|
687
|
+
|
688
|
+
// From here on it works differently, first we get all potential
|
689
|
+
// hexagons inserted into the available memory
|
690
|
+
H3_EXPORT(kRing)(centerH3, minK, out);
|
691
|
+
|
692
|
+
// Next we iterate through each hexagon, and test its center point to see if
|
693
|
+
// it's contained in the GeoJSON-like struct
|
694
|
+
for (int i = 0; i < numHexagons; i++) {
|
695
|
+
// Skip records that are already zeroed
|
696
|
+
if (out[i] == 0) {
|
697
|
+
continue;
|
826
698
|
}
|
827
|
-
//
|
828
|
-
|
829
|
-
|
830
|
-
|
831
|
-
|
832
|
-
|
833
|
-
|
834
|
-
|
835
|
-
// Iterate through all hexagons in the current search hash, then loop
|
836
|
-
// through all neighbors and test Point-in-Poly, if point-in-poly
|
837
|
-
// succeeds, add to out and found hashes if not already there.
|
838
|
-
int currentSearchNum = 0;
|
839
|
-
int i = 0;
|
840
|
-
while (currentSearchNum < numSearchHexes) {
|
841
|
-
H3Index ring[MAX_ONE_RING_SIZE] = {0};
|
842
|
-
H3Index searchHex = search[i];
|
843
|
-
H3_EXPORT(kRing)(searchHex, 1, ring);
|
844
|
-
for (int j = 0; j < MAX_ONE_RING_SIZE; j++) {
|
845
|
-
if (ring[j] == H3_INVALID_INDEX) {
|
846
|
-
continue; // Skip if this was a pentagon and only had 5
|
847
|
-
// neighbors
|
848
|
-
}
|
849
|
-
|
850
|
-
H3Index hex = ring[j];
|
851
|
-
|
852
|
-
// A simple hash to store the hexagon, or move to another place
|
853
|
-
// if needed. This MUST be done before the point-in-poly check
|
854
|
-
// since that's far more expensive
|
855
|
-
int loc = (int)(hex % numHexagons);
|
856
|
-
int loopCount = 0;
|
857
|
-
while (out[loc] != 0) {
|
858
|
-
// If this branch is reached, we have exceeded the maximum
|
859
|
-
// number of hexagons possible and need to clean up the
|
860
|
-
// allocated memory.
|
861
|
-
// LCOV_EXCL_START
|
862
|
-
if (loopCount > numHexagons) {
|
863
|
-
free(search);
|
864
|
-
free(found);
|
865
|
-
free(bboxes);
|
866
|
-
return -1;
|
867
|
-
}
|
868
|
-
// LCOV_EXCL_STOP
|
869
|
-
if (out[loc] == hex) break; // Skip duplicates found
|
870
|
-
loc = (loc + 1) % numHexagons;
|
871
|
-
loopCount++;
|
872
|
-
}
|
873
|
-
if (out[loc] == hex) {
|
874
|
-
continue; // Skip this hex, already exists in the out hash
|
875
|
-
}
|
876
|
-
|
877
|
-
// Check if the hexagon is in the polygon or not
|
878
|
-
GeoCoord hexCenter;
|
879
|
-
H3_EXPORT(h3ToGeo)(hex, &hexCenter);
|
880
|
-
|
881
|
-
// If not, skip
|
882
|
-
if (!pointInsidePolygon(geoPolygon, bboxes, &hexCenter)) {
|
883
|
-
continue;
|
884
|
-
}
|
885
|
-
|
886
|
-
// Otherwise set it in the output array
|
887
|
-
out[loc] = hex;
|
888
|
-
|
889
|
-
// Set the hexagon in the found hash
|
890
|
-
found[numFoundHexes] = hex;
|
891
|
-
numFoundHexes++;
|
892
|
-
}
|
893
|
-
currentSearchNum++;
|
894
|
-
i++;
|
699
|
+
// Check if hexagon is inside of polygon
|
700
|
+
GeoCoord hexCenter;
|
701
|
+
H3_EXPORT(h3ToGeo)(out[i], &hexCenter);
|
702
|
+
hexCenter.lat = constrainLat(hexCenter.lat);
|
703
|
+
hexCenter.lon = constrainLng(hexCenter.lon);
|
704
|
+
// And remove from list if not
|
705
|
+
if (!pointInsidePolygon(geoPolygon, bboxes, &hexCenter)) {
|
706
|
+
out[i] = H3_INVALID_INDEX;
|
895
707
|
}
|
896
|
-
|
897
|
-
// Swap the search and found pointers, copy the found hex count to the
|
898
|
-
// search hex count, and zero everything related to the found memory.
|
899
|
-
H3Index* temp = search;
|
900
|
-
search = found;
|
901
|
-
found = temp;
|
902
|
-
for (int j = 0; j < numSearchHexes; j++) found[j] = 0;
|
903
|
-
numSearchHexes = numFoundHexes;
|
904
|
-
numFoundHexes = 0;
|
905
|
-
// Repeat until no new hexagons are found
|
906
708
|
}
|
907
|
-
// The out memory structure should be complete, end it here
|
908
709
|
free(bboxes);
|
909
|
-
free(search);
|
910
|
-
free(found);
|
911
|
-
return 0;
|
912
710
|
}
|
913
711
|
|
914
712
|
/**
|
@@ -88,59 +88,38 @@ double _hexRadiusKm(H3Index h3Index) {
|
|
88
88
|
}
|
89
89
|
|
90
90
|
/**
|
91
|
-
*
|
92
|
-
*
|
93
|
-
*
|
94
|
-
* @param
|
95
|
-
* @
|
96
|
-
* @return the estimated number of hexagons to fill the bounding box
|
91
|
+
* Get the radius of the bbox in hexagons - i.e. the radius of a k-ring centered
|
92
|
+
* on the bbox center and covering the entire bbox.
|
93
|
+
* @param bbox Bounding box to measure
|
94
|
+
* @param res Resolution of hexagons to use in measurement
|
95
|
+
* @return Radius in hexagons
|
97
96
|
*/
|
98
|
-
int
|
99
|
-
//
|
100
|
-
|
101
|
-
|
102
|
-
double pentagonRadiusKm = _hexRadiusKm(pentagons[0]);
|
103
|
-
// Area of a regular hexagon is 3/2*sqrt(3) * r * r
|
104
|
-
// The pentagon has the most distortion (smallest edges) and shares its
|
105
|
-
// edges with hexagons, so the most-distorted hexagons have this area
|
106
|
-
double pentagonAreaKm2 =
|
107
|
-
2.59807621135 * pentagonRadiusKm * pentagonRadiusKm;
|
97
|
+
int bboxHexRadius(const BBox* bbox, int res) {
|
98
|
+
// Determine the center of the bounding box
|
99
|
+
GeoCoord center;
|
100
|
+
bboxCenter(bbox, ¢er);
|
108
101
|
|
109
|
-
//
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
p2.lon = bbox->east;
|
115
|
-
double h = _geoDistKm(&p1, &p2);
|
116
|
-
p2.lat = bbox->north;
|
117
|
-
p2.lon = bbox->west;
|
118
|
-
double w = _geoDistKm(&p1, &p2);
|
102
|
+
// Use a vertex on the side closest to the equator, to ensure the longest
|
103
|
+
// radius in cases with significant distortion. East/west is arbitrary.
|
104
|
+
double lat =
|
105
|
+
fabs(bbox->north) > fabs(bbox->south) ? bbox->south : bbox->north;
|
106
|
+
GeoCoord vertex = {lat, bbox->east};
|
119
107
|
|
120
|
-
//
|
121
|
-
|
122
|
-
|
123
|
-
return estimate;
|
124
|
-
}
|
108
|
+
// Determine the length of the bounding box "radius" to then use
|
109
|
+
// as a circle on the earth that the k-rings must be greater than
|
110
|
+
double bboxRadiusKm = _geoDistKm(¢er, &vertex);
|
125
111
|
|
126
|
-
|
127
|
-
|
128
|
-
* the cartesian-projected line
|
129
|
-
*
|
130
|
-
* @param origin the origin coordinates
|
131
|
-
* @param destination the destination coordinates
|
132
|
-
* @param res the resolution of the H3 hexagons to trace the line
|
133
|
-
* @return the estimated number of hexagons required to trace the line
|
134
|
-
*/
|
135
|
-
int lineHexEstimate(const GeoCoord* origin, const GeoCoord* destination,
|
136
|
-
int res) {
|
137
|
-
// Get the area of the pentagon as the maximally-distorted area possible
|
138
|
-
H3Index pentagons[12] = {0};
|
139
|
-
H3_EXPORT(getPentagonIndexes)(res, pentagons);
|
140
|
-
double pentagonRadiusKm = _hexRadiusKm(pentagons[0]);
|
112
|
+
// Determine the radius of the center hexagon
|
113
|
+
double centerHexRadiusKm = _hexRadiusKm(H3_EXPORT(geoToH3)(¢er, res));
|
141
114
|
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
115
|
+
// We use centerHexRadiusKm un-scaled and rounded *up* to guarantee
|
116
|
+
// containment ot the bbox. Ideal, undistorted hexagons could scale
|
117
|
+
// centerHexRadiusKm by a factor of up to 1.5, reducing bboxHexRadius.
|
118
|
+
// This is because the closest point along an undistorted hexagon drawn
|
119
|
+
// through the center points of a k-ring aggregation is exactly 1.5 radii
|
120
|
+
// of the hexagon. But there is distortion near pentagons, and for those
|
121
|
+
// cases, the scaling needs to be less than 1.5. Using the un-scaled value
|
122
|
+
// conservatively guarantees containment for all cases, at the expense of a
|
123
|
+
// larger bboxHexRadius.
|
124
|
+
return (int)ceil(bboxRadiusKm / centerHexRadiusKm);
|
146
125
|
}
|
data/lib/h3/bindings/base.rb
CHANGED
@@ -12,11 +12,21 @@ module H3
|
|
12
12
|
base.include Types
|
13
13
|
base.ffi_lib ["#{lib_path}/libh3.dylib", "#{lib_path}/libh3.so"]
|
14
14
|
base.typedef :ulong_long, :h3_index
|
15
|
-
base.typedef :int, :size
|
16
15
|
base.typedef :int, :k_distance
|
17
|
-
|
18
|
-
|
19
|
-
|
16
|
+
end
|
17
|
+
|
18
|
+
def attach_predicate_function(name, *args)
|
19
|
+
stripped_name = name.to_s.gsub("?", "")
|
20
|
+
attach_function(stripped_name, *args).tap do
|
21
|
+
rename_function stripped_name, name
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def rename_function(from, to)
|
28
|
+
alias_method to, from
|
29
|
+
undef_method from
|
20
30
|
end
|
21
31
|
end
|
22
32
|
end
|
data/lib/h3/bindings/private.rb
CHANGED
@@ -7,11 +7,11 @@ module H3
|
|
7
7
|
module Private
|
8
8
|
extend H3::Bindings::Base
|
9
9
|
|
10
|
-
attach_function :compact, [H3IndexesIn, H3IndexesOut, :
|
10
|
+
attach_function :compact, [H3IndexesIn, H3IndexesOut, :size_t], :bool
|
11
11
|
attach_function :destroy_linked_polygon, :destroyLinkedPolygon, [LinkedGeoPolygon], :void
|
12
12
|
attach_function :geo_to_h3, :geoToH3, [GeoCoord, Resolution], :h3_index
|
13
13
|
attach_function :get_pentagon_indexes, :getPentagonIndexes, [:int, H3IndexesOut], :void
|
14
|
-
attach_function :h3_faces, :h3GetFaces, %i[h3_index
|
14
|
+
attach_function :h3_faces, :h3GetFaces, %i[h3_index buffer_out], :void
|
15
15
|
attach_function :h3_indexes_from_unidirectional_edge,
|
16
16
|
:getH3IndexesFromUnidirectionalEdge,
|
17
17
|
[:h3_index, H3IndexesOut], :void
|
@@ -21,11 +21,11 @@ module H3
|
|
21
21
|
[:h3_index, H3IndexesOut], :void
|
22
22
|
attach_function :h3_set_to_linked_geo,
|
23
23
|
:h3SetToLinkedGeo,
|
24
|
-
[H3IndexesIn, :
|
24
|
+
[H3IndexesIn, :size_t, LinkedGeoPolygon],
|
25
25
|
:void
|
26
26
|
attach_function :h3_to_children, :h3ToChildren, [:h3_index, Resolution, H3IndexesOut], :void
|
27
27
|
attach_function :h3_to_geo, :h3ToGeo, [:h3_index, GeoCoord], :void
|
28
|
-
attach_function :h3_to_string, :h3ToString, %i[h3_index
|
28
|
+
attach_function :h3_to_string, :h3ToString, %i[h3_index buffer_out size_t], :void
|
29
29
|
attach_function :h3_to_geo_boundary,
|
30
30
|
:h3ToGeoBoundary,
|
31
31
|
[:h3_index, GeoBoundary],
|
@@ -36,25 +36,25 @@ module H3
|
|
36
36
|
attach_function :hex_range, :hexRange, [:h3_index, :k_distance, H3IndexesOut], :bool
|
37
37
|
attach_function :hex_range_distances,
|
38
38
|
:hexRangeDistances,
|
39
|
-
[:h3_index, :k_distance, H3IndexesOut, :
|
39
|
+
[:h3_index, :k_distance, H3IndexesOut, :buffer_out], :bool
|
40
40
|
attach_function :hex_ranges,
|
41
41
|
:hexRanges,
|
42
|
-
[H3IndexesIn, :
|
42
|
+
[H3IndexesIn, :size_t, :k_distance, H3IndexesOut],
|
43
43
|
:bool
|
44
44
|
attach_function :hex_ring, :hexRing, [:h3_index, :k_distance, H3IndexesOut], :bool
|
45
45
|
attach_function :k_ring, :kRing, [:h3_index, :k_distance, H3IndexesOut], :void
|
46
46
|
attach_function :k_ring_distances,
|
47
47
|
:kRingDistances,
|
48
|
-
[:h3_index, :k_distance, H3IndexesOut, :
|
48
|
+
[:h3_index, :k_distance, H3IndexesOut, :buffer_out],
|
49
49
|
:bool
|
50
50
|
attach_function :max_polyfill_size,
|
51
51
|
:maxPolyfillSize,
|
52
52
|
[GeoPolygon, Resolution],
|
53
53
|
:int
|
54
|
-
attach_function :max_uncompact_size, :maxUncompactSize, [H3IndexesIn, :
|
54
|
+
attach_function :max_uncompact_size, :maxUncompactSize, [H3IndexesIn, :size_t, Resolution], :int
|
55
55
|
attach_function :polyfill, [GeoPolygon, Resolution, H3IndexesOut], :void
|
56
56
|
attach_function :res_0_indexes, :getRes0Indexes, [H3IndexesOut], :void
|
57
|
-
attach_function :uncompact, [H3IndexesIn, :
|
57
|
+
attach_function :uncompact, [H3IndexesIn, :size_t, H3IndexesOut, :size_t, Resolution], :bool
|
58
58
|
end
|
59
59
|
end
|
60
60
|
end
|
data/lib/h3/hierarchy.rb
CHANGED
@@ -19,12 +19,6 @@ module H3
|
|
19
19
|
# @return [Integer] H3 index of parent hexagon.
|
20
20
|
attach_function :parent, :h3ToParent, [:h3_index, Resolution], :h3_index
|
21
21
|
|
22
|
-
# @deprecated Please use {#parent} instead.
|
23
|
-
def h3_to_parent(h3_index, resolution)
|
24
|
-
parent(h3_index, resolution)
|
25
|
-
end
|
26
|
-
deprecate :h3_to_parent, :parent, 2020, 1
|
27
|
-
|
28
22
|
# @!method max_children(h3_index, child_resolution)
|
29
23
|
#
|
30
24
|
# Derive maximum number of child hexagons possible at given resolution.
|
@@ -54,12 +48,6 @@ module H3
|
|
54
48
|
# @return [Integer] H3 index of center child hexagon.
|
55
49
|
attach_function :center_child, :h3ToCenterChild, [:h3_index, Resolution], :h3_index
|
56
50
|
|
57
|
-
# @deprecated Please use {#max_children} instead.
|
58
|
-
def max_h3_to_children_size(h3_index, resolution)
|
59
|
-
max_children(h3_index, resolution)
|
60
|
-
end
|
61
|
-
deprecate :max_h3_to_children_size, :max_children, 2020, 1
|
62
|
-
|
63
51
|
# Derive child hexagons contained within the hexagon at the given H3 index.
|
64
52
|
#
|
65
53
|
# @param [Integer] h3_index A valid H3 index.
|
@@ -80,12 +68,6 @@ module H3
|
|
80
68
|
out.read
|
81
69
|
end
|
82
70
|
|
83
|
-
# @deprecated Please use {#children} instead.
|
84
|
-
def h3_to_children(h3_index, resolution)
|
85
|
-
children(h3_index, resolution)
|
86
|
-
end
|
87
|
-
deprecate :h3_to_children, :children, 2020, 1
|
88
|
-
|
89
71
|
# Find the maximum uncompacted size of the given set of H3 indexes.
|
90
72
|
#
|
91
73
|
# @param [Array<Integer>] compacted_set An array of valid H3 indexes.
|
data/lib/h3/indexing.rb
CHANGED
@@ -35,12 +35,6 @@ module H3
|
|
35
35
|
Bindings::Private.geo_to_h3(coords, resolution)
|
36
36
|
end
|
37
37
|
|
38
|
-
# @deprecated Please use {#from_geo_coordinates} instead.
|
39
|
-
def geo_to_h3(coords, resolution)
|
40
|
-
from_geo_coordinates(coords, resolution)
|
41
|
-
end
|
42
|
-
deprecate :geo_to_h3, :from_geo_coordinates, 2020, 1
|
43
|
-
|
44
38
|
# Derive coordinates for a given H3 index.
|
45
39
|
#
|
46
40
|
# The coordinates map to the centre of the hexagon at the given index.
|
@@ -58,12 +52,6 @@ module H3
|
|
58
52
|
[rads_to_degs(coords[:lat]), rads_to_degs(coords[:lon])]
|
59
53
|
end
|
60
54
|
|
61
|
-
# @deprecated Please use {#to_geo_coordinates} instead.
|
62
|
-
def h3_to_geo(h3_index)
|
63
|
-
to_geo_coordinates(h3_index)
|
64
|
-
end
|
65
|
-
deprecate :h3_to_geo, :to_geo_coordinates, 2020, 1
|
66
|
-
|
67
55
|
# Derive the geographical boundary as coordinates for a given H3 index.
|
68
56
|
#
|
69
57
|
# This will be a set of 6 coordinate pairs matching the vertexes of the
|
@@ -89,11 +77,5 @@ module H3
|
|
89
77
|
[rads_to_degs(d[:lat]), rads_to_degs(d[:lon])]
|
90
78
|
end
|
91
79
|
end
|
92
|
-
|
93
|
-
# @deprecated Please use {#to_boundary} instead.
|
94
|
-
def h3_to_geo_boundary(h3_index)
|
95
|
-
to_boundary(h3_index)
|
96
|
-
end
|
97
|
-
deprecate :h3_to_geo_boundary, :to_boundary, 2020, 1
|
98
80
|
end
|
99
81
|
end
|
data/lib/h3/inspection.rb
CHANGED
@@ -21,12 +21,6 @@ module H3
|
|
21
21
|
# @return [Integer] Resolution of H3 index
|
22
22
|
attach_function :resolution, :h3GetResolution, %i[h3_index], Resolution
|
23
23
|
|
24
|
-
# @deprecated Please use {#resolution} instead.
|
25
|
-
def h3_resolution(h3_index)
|
26
|
-
resolution(h3_index)
|
27
|
-
end
|
28
|
-
deprecate :h3_resolution, :resolution, 2020, 1
|
29
|
-
|
30
24
|
# @!method base_cell(h3_index)
|
31
25
|
#
|
32
26
|
# Derives the base cell number of the given H3 index
|
@@ -40,12 +34,6 @@ module H3
|
|
40
34
|
# @return [Integer] Base cell number
|
41
35
|
attach_function :base_cell, :h3GetBaseCell, %i[h3_index], :int
|
42
36
|
|
43
|
-
# @deprecated Please use {#base_cell} instead.
|
44
|
-
def h3_base_cell(h3_index)
|
45
|
-
base_cell(h3_index)
|
46
|
-
end
|
47
|
-
deprecate :h3_base_cell, :base_cell, 2020, 1
|
48
|
-
|
49
37
|
# @!method from_string(h3_string)
|
50
38
|
#
|
51
39
|
# Derives the H3 index for a given hexadecimal string representation.
|
@@ -59,12 +47,6 @@ module H3
|
|
59
47
|
# @return [Integer] H3 index
|
60
48
|
attach_function :from_string, :stringToH3, %i[string], :h3_index
|
61
49
|
|
62
|
-
# @deprecated Please use {#from_string} instead.
|
63
|
-
def string_to_h3(string)
|
64
|
-
from_string(string)
|
65
|
-
end
|
66
|
-
deprecate :string_to_h3, :from_string, 2020, 1
|
67
|
-
|
68
50
|
# @!method pentagon?(h3_index)
|
69
51
|
#
|
70
52
|
# Determine whether the given H3 index is a pentagon.
|
@@ -76,15 +58,7 @@ module H3
|
|
76
58
|
# true
|
77
59
|
#
|
78
60
|
# @return [Boolean] True if the H3 index is a pentagon.
|
79
|
-
|
80
|
-
alias_method :pentagon?, :pentagon
|
81
|
-
undef_method :pentagon
|
82
|
-
|
83
|
-
# @deprecated Please use {#pentagon?} instead.
|
84
|
-
def h3_pentagon?(h3_index)
|
85
|
-
pentagon?(h3_index)
|
86
|
-
end
|
87
|
-
deprecate :h3_pentagon?, :pentagon?, 2020, 1
|
61
|
+
attach_predicate_function :pentagon?, :h3IsPentagon, %i[h3_index], :bool
|
88
62
|
|
89
63
|
# @!method class_3_resolution?(h3_index)
|
90
64
|
#
|
@@ -98,15 +72,7 @@ module H3
|
|
98
72
|
# true
|
99
73
|
#
|
100
74
|
# @return [Boolean] True if the H3 index has a class III resolution.
|
101
|
-
|
102
|
-
alias_method :class_3_resolution?, :class_3_resolution
|
103
|
-
undef_method :class_3_resolution
|
104
|
-
|
105
|
-
# @deprecated Please use {#class_3_resolution?} instead.
|
106
|
-
def h3_res_class_3?(h3_index)
|
107
|
-
class_3_resolution?(h3_index)
|
108
|
-
end
|
109
|
-
deprecate :h3_res_class_3?, :class_3_resolution?, 2020, 1
|
75
|
+
attach_predicate_function :class_3_resolution?, :h3IsResClassIII, %i[h3_index], :bool
|
110
76
|
|
111
77
|
# @!method valid?(h3_index)
|
112
78
|
#
|
@@ -119,15 +85,7 @@ module H3
|
|
119
85
|
# true
|
120
86
|
#
|
121
87
|
# @return [Boolean] True if the H3 index is valid.
|
122
|
-
|
123
|
-
alias_method :valid?, :valid
|
124
|
-
undef_method :valid
|
125
|
-
|
126
|
-
# @deprecated Please use {#valid?} instead.
|
127
|
-
def h3_valid?(h3_index)
|
128
|
-
valid?(h3_index)
|
129
|
-
end
|
130
|
-
deprecate :h3_valid?, :valid?, 2020, 1
|
88
|
+
attach_predicate_function :valid?, :h3IsValid, %i[h3_index], :bool
|
131
89
|
|
132
90
|
# Derives the hexadecimal string representation for a given H3 index.
|
133
91
|
#
|
@@ -144,12 +102,6 @@ module H3
|
|
144
102
|
h3_str.read_string
|
145
103
|
end
|
146
104
|
|
147
|
-
# @deprecated Please use {#to_string} instead.
|
148
|
-
def h3_to_string(h3_index)
|
149
|
-
to_string(h3_index)
|
150
|
-
end
|
151
|
-
deprecate :h3_to_string, :to_strings, 2020, 1
|
152
|
-
|
153
105
|
# @!method max_face_count(h3_index)
|
154
106
|
#
|
155
107
|
# Returns the maximum number of icosahedron faces the given H3 index may intersect.
|
@@ -163,8 +115,6 @@ module H3
|
|
163
115
|
# @return [Integer] Maximum possible number of faces
|
164
116
|
attach_function :max_face_count, :maxFaceCount, %i[h3_index], :int
|
165
117
|
|
166
|
-
# @!method faces(h3_index)
|
167
|
-
#
|
168
118
|
# Find all icosahedron faces intersected by a given H3 index.
|
169
119
|
#
|
170
120
|
# @param [Integer] h3_index A H3 index.
|
@@ -181,11 +131,5 @@ module H3
|
|
181
131
|
# The C function returns a sparse array whose holes are represented by -1.
|
182
132
|
out.read_array_of_int(max_faces).reject(&:negative?).sort
|
183
133
|
end
|
184
|
-
|
185
|
-
# @deprecated Please use {#faces} instead.
|
186
|
-
def h3_faces(h3_index)
|
187
|
-
faces(h3_index)
|
188
|
-
end
|
189
|
-
deprecate :h3_faces, :faces, 2020, 1
|
190
134
|
end
|
191
135
|
end
|
data/lib/h3/miscellaneous.rb
CHANGED
@@ -83,12 +83,6 @@ module H3
|
|
83
83
|
# @return [Integer] Number of unique hexagons
|
84
84
|
attach_function :hexagon_count, :numHexagons, [Resolution], :ulong_long
|
85
85
|
|
86
|
-
# @deprecated Please use {#hexagon_count} instead.
|
87
|
-
def num_hexagons(resolution)
|
88
|
-
hexagon_count(resolution)
|
89
|
-
end
|
90
|
-
deprecate :num_hexagons, :hexagon_count, 2020, 1
|
91
|
-
|
92
86
|
# @!method rads_to_degs(rads)
|
93
87
|
#
|
94
88
|
# Convert a number expressed in radians to its equivalent in degrees.
|
@@ -125,12 +119,6 @@ module H3
|
|
125
119
|
# @return [Integer] The number of pentagons per resolution.
|
126
120
|
attach_function :pentagon_count, :pentagonIndexCount, [], :int
|
127
121
|
|
128
|
-
# @deprecated Please use {#base_cell_count} instead.
|
129
|
-
def res_0_index_count
|
130
|
-
base_cell_count
|
131
|
-
end
|
132
|
-
deprecate :res_0_index_count, :base_cell_count, 2020, 1
|
133
|
-
|
134
122
|
# Returns all resolution 0 hexagons (base cells).
|
135
123
|
#
|
136
124
|
# @example Return all base cells.
|
@@ -156,11 +144,5 @@ module H3
|
|
156
144
|
Bindings::Private.get_pentagon_indexes(resolution, out)
|
157
145
|
out.read
|
158
146
|
end
|
159
|
-
|
160
|
-
# @deprecated Please use {#base_cells} instead.
|
161
|
-
def res_0_indexes
|
162
|
-
base_cells
|
163
|
-
end
|
164
|
-
deprecate :res_0_indexes, :base_cells, 2020, 1
|
165
147
|
end
|
166
148
|
end
|
data/lib/h3/regions.rb
CHANGED
@@ -141,6 +141,7 @@ module H3
|
|
141
141
|
linked_geo_polygon = LinkedGeoPolygon.new
|
142
142
|
Bindings::Private.h3_set_to_linked_geo(h3_set, h3_indexes.size, linked_geo_polygon)
|
143
143
|
|
144
|
+
# The algorithm in h3 currently only handles 1 polygon
|
144
145
|
extract_linked_geo_polygon(linked_geo_polygon).first
|
145
146
|
ensure
|
146
147
|
Bindings::Private.destroy_linked_polygon(linked_geo_polygon)
|
@@ -154,6 +155,8 @@ module H3
|
|
154
155
|
geo_polygons = [linked_geo_polygon]
|
155
156
|
|
156
157
|
until linked_geo_polygon[:next].null?
|
158
|
+
# Until the h3 algorithm is updated to handle multiple polygons,
|
159
|
+
# this block will never run.
|
157
160
|
geo_polygons << linked_geo_polygon[:next]
|
158
161
|
linked_geo_polygon = linked_geo_polygon[:next]
|
159
162
|
end
|
data/lib/h3/traversal.rb
CHANGED
@@ -32,12 +32,6 @@ module H3
|
|
32
32
|
# @return [Integer] Distance between indexes.
|
33
33
|
attach_function :distance, :h3Distance, %i[h3_index h3_index], :k_distance
|
34
34
|
|
35
|
-
# @deprecated Please use {#distance} instead.
|
36
|
-
def h3_distance(origin, destination)
|
37
|
-
distance(origin, destination)
|
38
|
-
end
|
39
|
-
deprecate :h3_distance, :distance, 2020, 1
|
40
|
-
|
41
35
|
# @!method line_size(origin, destination)
|
42
36
|
#
|
43
37
|
# Derive the number of hexagons present in a line between two H3 indexes.
|
@@ -57,12 +51,6 @@ module H3
|
|
57
51
|
# @return [Integer] Number of hexagons found between indexes.
|
58
52
|
attach_function :line_size, :h3LineSize, %i[h3_index h3_index], :int
|
59
53
|
|
60
|
-
# @deprecated Please use {#line_size} instead.
|
61
|
-
def h3_line_size(origin, destination)
|
62
|
-
line_size(origin, destination)
|
63
|
-
end
|
64
|
-
deprecate :h3_line_size, :line_size, 2020, 1
|
65
|
-
|
66
54
|
# Derives H3 indexes within k distance of the origin H3 index.
|
67
55
|
#
|
68
56
|
# Similar to {k_ring}, except that an error is raised when one of the indexes
|
@@ -317,12 +305,6 @@ module H3
|
|
317
305
|
hexagons.read
|
318
306
|
end
|
319
307
|
|
320
|
-
# @deprecated Please use {#line} instead.
|
321
|
-
def h3_line(origin, destination)
|
322
|
-
line(origin, destination)
|
323
|
-
end
|
324
|
-
deprecate :h3_line, :line, 2020, 1
|
325
|
-
|
326
308
|
private
|
327
309
|
|
328
310
|
def k_rings_for_hex_range(indexes, k)
|
@@ -17,16 +17,7 @@ module H3
|
|
17
17
|
# true
|
18
18
|
#
|
19
19
|
# @return [Boolean] True if indexes are neighbors
|
20
|
-
|
21
|
-
alias_method :neighbors?, :neighbors
|
22
|
-
undef_method :neighbors
|
23
|
-
|
24
|
-
# @deprecated Please use {#neighbors?} instead.
|
25
|
-
def h3_indexes_neighbors?(origin, destination)
|
26
|
-
neighbors?(origin, destination)
|
27
|
-
end
|
28
|
-
|
29
|
-
deprecate :h3_indexes_neighbors?, :neighbors?, 2020, 1
|
20
|
+
attach_predicate_function :neighbors?, :h3IndexesAreNeighbors, %i[h3_index h3_index], :bool
|
30
21
|
|
31
22
|
# @!method unidirectional_edge_valid?(h3_index)
|
32
23
|
#
|
@@ -39,19 +30,10 @@ module H3
|
|
39
30
|
# true
|
40
31
|
#
|
41
32
|
# @return [Boolean] True if H3 index is a valid unidirectional edge
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
alias_method :unidirectional_edge_valid?, :unidirectional_edge_valid
|
47
|
-
undef_method :unidirectional_edge_valid
|
48
|
-
|
49
|
-
# @deprecated Please use {#unidirectional_edge_valid?} instead.
|
50
|
-
def h3_unidirectional_edge_valid?(h3_index)
|
51
|
-
unidirectional_edge_valid?(h3_index)
|
52
|
-
end
|
53
|
-
|
54
|
-
deprecate :h3_unidirectional_edge_valid?, :unidirectional_edge_valid?, 2020, 1
|
33
|
+
attach_predicate_function :unidirectional_edge_valid?,
|
34
|
+
:h3UnidirectionalEdgeIsValid,
|
35
|
+
%i[h3_index],
|
36
|
+
:bool
|
55
37
|
|
56
38
|
# @!method unidirectional_edge(origin, destination)
|
57
39
|
#
|
@@ -70,13 +52,6 @@ module H3
|
|
70
52
|
%i[h3_index h3_index],
|
71
53
|
:h3_index
|
72
54
|
|
73
|
-
# @deprecated Please use {#unidirectional_edge} instead.
|
74
|
-
def h3_unidirectional_edge(origin, destination)
|
75
|
-
unidirectional_edge(origin, destination)
|
76
|
-
end
|
77
|
-
|
78
|
-
deprecate :h3_unidirectional_edge, :unidirectional_edge, 2020, 1
|
79
|
-
|
80
55
|
# @!method destination_from_unidirectional_edge(edge)
|
81
56
|
#
|
82
57
|
# Derive destination H3 index from edge.
|
@@ -129,16 +104,6 @@ module H3
|
|
129
104
|
out.read
|
130
105
|
end
|
131
106
|
|
132
|
-
# @deprecated Please use {#origin_and_destination_from_unidirectional_edge} instead.
|
133
|
-
def h3_indexes_from_unidirectional_edge(edge)
|
134
|
-
origin_and_destination_from_unidirectional_edge(edge)
|
135
|
-
end
|
136
|
-
|
137
|
-
deprecate :h3_indexes_from_unidirectional_edge,
|
138
|
-
:origin_and_destination_from_unidirectional_edge,
|
139
|
-
2020,
|
140
|
-
1
|
141
|
-
|
142
107
|
# Derive unidirectional edges for a H3 index.
|
143
108
|
#
|
144
109
|
# @param [Integer] origin H3 index
|
@@ -158,16 +123,6 @@ module H3
|
|
158
123
|
out.read
|
159
124
|
end
|
160
125
|
|
161
|
-
# @deprecated Please use {#unidirectional_edges_from_hexagon} instead.
|
162
|
-
def h3_unidirectional_edges_from_hexagon(origin)
|
163
|
-
unidirectional_edges_from_hexagon(origin)
|
164
|
-
end
|
165
|
-
|
166
|
-
deprecate :h3_unidirectional_edges_from_hexagon,
|
167
|
-
:unidirectional_edges_from_hexagon,
|
168
|
-
2020,
|
169
|
-
1
|
170
|
-
|
171
126
|
# Derive coordinates for edge boundary.
|
172
127
|
#
|
173
128
|
# @param [Integer] edge H3 edge index
|
@@ -188,15 +143,5 @@ module H3
|
|
188
143
|
[rads_to_degs(d[:lat]), rads_to_degs(d[:lon])]
|
189
144
|
end
|
190
145
|
end
|
191
|
-
|
192
|
-
# @deprecated Please use {#unidirectional_edge_boundary} instead.
|
193
|
-
def h3_unidirectional_edge_boundary(edge)
|
194
|
-
unidirectional_edge_boundary(edge)
|
195
|
-
end
|
196
|
-
|
197
|
-
deprecate :h3_unidirectional_edge_boundary,
|
198
|
-
:unidirectional_edge_boundary,
|
199
|
-
2020,
|
200
|
-
1
|
201
146
|
end
|
202
147
|
end
|
data/lib/h3/version.rb
CHANGED
data/spec/geo_json_spec.rb
CHANGED
@@ -60,6 +60,14 @@ RSpec.describe H3 do
|
|
60
60
|
expect { geo_json_to_coordinates }.to raise_error(ArgumentError)
|
61
61
|
end
|
62
62
|
end
|
63
|
+
|
64
|
+
context "when given JSON with the wrong structure" do
|
65
|
+
let(:input) { { blah: "blah" }.to_json }
|
66
|
+
|
67
|
+
it "raises an error" do
|
68
|
+
expect { geo_json_to_coordinates }.to raise_error(ArgumentError)
|
69
|
+
end
|
70
|
+
end
|
63
71
|
end
|
64
72
|
|
65
73
|
describe ".coordinates_to_geo_json" do
|
@@ -42,7 +42,7 @@ RSpec.describe H3 do
|
|
42
42
|
File.read(File.join(File.dirname(__FILE__), "support/fixtures/banbury.json"))
|
43
43
|
end
|
44
44
|
let(:resolution) { 9 }
|
45
|
-
let(:expected_count) {
|
45
|
+
let(:expected_count) { 75_367 }
|
46
46
|
|
47
47
|
subject(:max_polyfill_size) { H3.max_polyfill_size(geojson, resolution) }
|
48
48
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: h3
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.6.
|
4
|
+
version: 3.6.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lachlan Laycock
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2020-01-08 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: ffi
|
@@ -412,7 +412,7 @@ files:
|
|
412
412
|
- spec/indexing_spec.rb
|
413
413
|
- spec/inspection_spec.rb
|
414
414
|
- spec/miscellaneous_spec.rb
|
415
|
-
- spec/
|
415
|
+
- spec/regions_spec.rb
|
416
416
|
- spec/spec_helper.rb
|
417
417
|
- spec/support/fixtures/australia.json
|
418
418
|
- spec/support/fixtures/banbury.json
|