h3 3.6.1 → 3.6.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|