h3 3.5.1 → 3.6.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 +5 -0
- data/Gemfile.lock +3 -3
- data/ext/h3/src/.travis.yml +15 -4
- data/ext/h3/src/CHANGELOG.md +7 -0
- data/ext/h3/src/CMakeLists.txt +15 -0
- data/ext/h3/src/README.md +5 -6
- data/ext/h3/src/VERSION +1 -1
- data/ext/h3/src/docs/api/hierarchy.md +8 -0
- data/ext/h3/src/docs/api/misc.md +18 -0
- data/ext/h3/src/scripts/coverage.sh.in +7 -3
- data/ext/h3/src/src/apps/miscapps/generateBaseCellNeighbors.c +2 -2
- data/ext/h3/src/src/apps/miscapps/generateNumHexagons.c +0 -2
- data/ext/h3/src/src/apps/testapps/testCompact.c +12 -0
- data/ext/h3/src/src/apps/testapps/testH3Distance.c +1 -50
- data/ext/h3/src/src/apps/testapps/testH3DistanceExhaustive.c +83 -0
- data/ext/h3/src/src/apps/testapps/testH3Line.c +1 -84
- data/ext/h3/src/src/apps/testapps/testH3LineExhaustive.c +114 -0
- data/ext/h3/src/src/apps/testapps/testH3ToCenterChild.c +67 -0
- data/ext/h3/src/src/apps/testapps/testH3ToChildren.c +14 -2
- data/ext/h3/src/src/apps/testapps/testH3ToLocalIj.c +12 -230
- data/ext/h3/src/src/apps/testapps/testH3ToLocalIjExhaustive.c +264 -0
- data/ext/h3/src/src/apps/testapps/testPentagonIndexes.c +57 -0
- data/ext/h3/src/src/h3lib/include/constants.h +2 -0
- data/ext/h3/src/src/h3lib/include/h3api.h.in +20 -0
- data/ext/h3/src/src/h3lib/lib/algos.c +5 -5
- data/ext/h3/src/src/h3lib/lib/faceijk.c +3 -3
- data/ext/h3/src/src/h3lib/lib/h3Index.c +69 -6
- data/ext/h3/src/src/h3lib/lib/localij.c +4 -4
- data/ext/h3/src/src/h3lib/lib/polygon.c +1 -2
- data/h3.gemspec +1 -1
- data/lib/h3/bindings/private.rb +1 -0
- data/lib/h3/hierarchy.rb +15 -0
- data/lib/h3/miscellaneous.rb +25 -0
- data/lib/h3/version.rb +1 -1
- data/spec/hierarchy_spec.rb +10 -0
- data/spec/miscellaneous_spec.rb +28 -0
- metadata +9 -4
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright 2018 Uber Technologies, Inc.
|
|
2
|
+
* Copyright 2018-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.
|
|
@@ -28,90 +28,7 @@
|
|
|
28
28
|
#include "test.h"
|
|
29
29
|
#include "utility.h"
|
|
30
30
|
|
|
31
|
-
static const int MAX_DISTANCES[] = {1, 2, 5, 12, 19, 26};
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Property-based testing of h3Line output
|
|
35
|
-
*/
|
|
36
|
-
static void h3Line_assertions(H3Index start, H3Index end) {
|
|
37
|
-
int sz = H3_EXPORT(h3LineSize)(start, end);
|
|
38
|
-
t_assert(sz > 0, "got valid size");
|
|
39
|
-
H3Index *line = calloc(sz, sizeof(H3Index));
|
|
40
|
-
|
|
41
|
-
int err = H3_EXPORT(h3Line)(start, end, line);
|
|
42
|
-
|
|
43
|
-
t_assert(err == 0, "no error on line");
|
|
44
|
-
t_assert(line[0] == start, "line starts with start index");
|
|
45
|
-
t_assert(line[sz - 1] == end, "line ends with end index");
|
|
46
|
-
|
|
47
|
-
for (int i = 1; i < sz; i++) {
|
|
48
|
-
t_assert(H3_EXPORT(h3IsValid)(line[i]), "index is valid");
|
|
49
|
-
t_assert(H3_EXPORT(h3IndexesAreNeighbors)(line[i], line[i - 1]),
|
|
50
|
-
"index is a neighbor of the previous index");
|
|
51
|
-
if (i > 1) {
|
|
52
|
-
t_assert(
|
|
53
|
-
!H3_EXPORT(h3IndexesAreNeighbors)(line[i], line[i - 2]),
|
|
54
|
-
"index is not a neighbor of the index before the previous");
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
free(line);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Tests for invalid h3Line input
|
|
63
|
-
*/
|
|
64
|
-
static void h3Line_invalid_assertions(H3Index start, H3Index end) {
|
|
65
|
-
int sz = H3_EXPORT(h3LineSize)(start, end);
|
|
66
|
-
t_assert(sz < 0, "line size marked as invalid");
|
|
67
|
-
|
|
68
|
-
H3Index *line = {0};
|
|
69
|
-
int err = H3_EXPORT(h3Line)(start, end, line);
|
|
70
|
-
t_assert(err != 0, "line marked as invalid");
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Test for lines from an index to all neighbors within a kRing
|
|
75
|
-
*/
|
|
76
|
-
static void h3Line_kRing_assertions(H3Index h3) {
|
|
77
|
-
int r = H3_GET_RESOLUTION(h3);
|
|
78
|
-
t_assert(r <= 5, "resolution supported by test function (kRing)");
|
|
79
|
-
int maxK = MAX_DISTANCES[r];
|
|
80
|
-
|
|
81
|
-
int sz = H3_EXPORT(maxKringSize)(maxK);
|
|
82
|
-
|
|
83
|
-
if (H3_EXPORT(h3IsPentagon)(h3)) {
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
H3Index *neighbors = calloc(sz, sizeof(H3Index));
|
|
88
|
-
H3_EXPORT(kRing)(h3, maxK, neighbors);
|
|
89
|
-
|
|
90
|
-
for (int i = 0; i < sz; i++) {
|
|
91
|
-
if (neighbors[i] == 0) {
|
|
92
|
-
continue;
|
|
93
|
-
}
|
|
94
|
-
int distance = H3_EXPORT(h3Distance)(h3, neighbors[i]);
|
|
95
|
-
if (distance >= 0) {
|
|
96
|
-
h3Line_assertions(h3, neighbors[i]);
|
|
97
|
-
} else {
|
|
98
|
-
h3Line_invalid_assertions(h3, neighbors[i]);
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
free(neighbors);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
31
|
SUITE(h3Line) {
|
|
106
|
-
TEST(h3Line_kRing) {
|
|
107
|
-
iterateAllIndexesAtRes(0, h3Line_kRing_assertions);
|
|
108
|
-
iterateAllIndexesAtRes(1, h3Line_kRing_assertions);
|
|
109
|
-
iterateAllIndexesAtRes(2, h3Line_kRing_assertions);
|
|
110
|
-
// Don't iterate all of res 3, to save time
|
|
111
|
-
iterateAllIndexesAtResPartial(3, h3Line_kRing_assertions, 6);
|
|
112
|
-
// Further resolutions aren't tested to save time.
|
|
113
|
-
}
|
|
114
|
-
|
|
115
32
|
TEST(h3Line_acrossMultipleFaces) {
|
|
116
33
|
H3Index start = 0x85285aa7fffffff;
|
|
117
34
|
H3Index end = 0x851d9b1bfffffff;
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2019 Uber Technologies, Inc.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
/** @file
|
|
17
|
+
* @brief tests H3 distance function using tests over a large number of indexes.
|
|
18
|
+
*
|
|
19
|
+
* usage: `testH3Distance`
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
#include <stdio.h>
|
|
23
|
+
#include <stdlib.h>
|
|
24
|
+
#include <string.h>
|
|
25
|
+
#include "h3Index.h"
|
|
26
|
+
#include "h3api.h"
|
|
27
|
+
#include "localij.h"
|
|
28
|
+
#include "test.h"
|
|
29
|
+
#include "utility.h"
|
|
30
|
+
|
|
31
|
+
static const int MAX_DISTANCES[] = {1, 2, 5, 12, 19, 26};
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Property-based testing of h3Line output
|
|
35
|
+
*/
|
|
36
|
+
static void h3Line_assertions(H3Index start, H3Index end) {
|
|
37
|
+
int sz = H3_EXPORT(h3LineSize)(start, end);
|
|
38
|
+
t_assert(sz > 0, "got valid size");
|
|
39
|
+
H3Index *line = calloc(sz, sizeof(H3Index));
|
|
40
|
+
|
|
41
|
+
int err = H3_EXPORT(h3Line)(start, end, line);
|
|
42
|
+
|
|
43
|
+
t_assert(err == 0, "no error on line");
|
|
44
|
+
t_assert(line[0] == start, "line starts with start index");
|
|
45
|
+
t_assert(line[sz - 1] == end, "line ends with end index");
|
|
46
|
+
|
|
47
|
+
for (int i = 1; i < sz; i++) {
|
|
48
|
+
t_assert(H3_EXPORT(h3IsValid)(line[i]), "index is valid");
|
|
49
|
+
t_assert(H3_EXPORT(h3IndexesAreNeighbors)(line[i], line[i - 1]),
|
|
50
|
+
"index is a neighbor of the previous index");
|
|
51
|
+
if (i > 1) {
|
|
52
|
+
t_assert(
|
|
53
|
+
!H3_EXPORT(h3IndexesAreNeighbors)(line[i], line[i - 2]),
|
|
54
|
+
"index is not a neighbor of the index before the previous");
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
free(line);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Tests for invalid h3Line input
|
|
63
|
+
*/
|
|
64
|
+
static void h3Line_invalid_assertions(H3Index start, H3Index end) {
|
|
65
|
+
int sz = H3_EXPORT(h3LineSize)(start, end);
|
|
66
|
+
t_assert(sz < 0, "line size marked as invalid");
|
|
67
|
+
|
|
68
|
+
H3Index *line = {0};
|
|
69
|
+
int err = H3_EXPORT(h3Line)(start, end, line);
|
|
70
|
+
t_assert(err != 0, "line marked as invalid");
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Test for lines from an index to all neighbors within a kRing
|
|
75
|
+
*/
|
|
76
|
+
static void h3Line_kRing_assertions(H3Index h3) {
|
|
77
|
+
int r = H3_GET_RESOLUTION(h3);
|
|
78
|
+
t_assert(r <= 5, "resolution supported by test function (kRing)");
|
|
79
|
+
int maxK = MAX_DISTANCES[r];
|
|
80
|
+
|
|
81
|
+
int sz = H3_EXPORT(maxKringSize)(maxK);
|
|
82
|
+
|
|
83
|
+
if (H3_EXPORT(h3IsPentagon)(h3)) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
H3Index *neighbors = calloc(sz, sizeof(H3Index));
|
|
88
|
+
H3_EXPORT(kRing)(h3, maxK, neighbors);
|
|
89
|
+
|
|
90
|
+
for (int i = 0; i < sz; i++) {
|
|
91
|
+
if (neighbors[i] == 0) {
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
int distance = H3_EXPORT(h3Distance)(h3, neighbors[i]);
|
|
95
|
+
if (distance >= 0) {
|
|
96
|
+
h3Line_assertions(h3, neighbors[i]);
|
|
97
|
+
} else {
|
|
98
|
+
h3Line_invalid_assertions(h3, neighbors[i]);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
free(neighbors);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
SUITE(h3Line) {
|
|
106
|
+
TEST(h3Line_kRing) {
|
|
107
|
+
iterateAllIndexesAtRes(0, h3Line_kRing_assertions);
|
|
108
|
+
iterateAllIndexesAtRes(1, h3Line_kRing_assertions);
|
|
109
|
+
iterateAllIndexesAtRes(2, h3Line_kRing_assertions);
|
|
110
|
+
// Don't iterate all of res 3, to save time
|
|
111
|
+
iterateAllIndexesAtResPartial(3, h3Line_kRing_assertions, 6);
|
|
112
|
+
// Further resolutions aren't tested to save time.
|
|
113
|
+
}
|
|
114
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2019 Uber Technologies, Inc.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
#include <inttypes.h>
|
|
18
|
+
#include <stdlib.h>
|
|
19
|
+
#include "h3Index.h"
|
|
20
|
+
#include "test.h"
|
|
21
|
+
|
|
22
|
+
SUITE(h3ToCenterChild) {
|
|
23
|
+
H3Index baseHex;
|
|
24
|
+
GeoCoord baseCentroid;
|
|
25
|
+
setH3Index(&baseHex, 8, 4, 2);
|
|
26
|
+
H3_EXPORT(h3ToGeo)(baseHex, &baseCentroid);
|
|
27
|
+
|
|
28
|
+
TEST(propertyTests) {
|
|
29
|
+
for (int res = 0; res <= MAX_H3_RES - 1; res++) {
|
|
30
|
+
for (int childRes = res + 1; childRes <= MAX_H3_RES; childRes++) {
|
|
31
|
+
GeoCoord centroid;
|
|
32
|
+
H3Index h3Index = H3_EXPORT(geoToH3)(&baseCentroid, res);
|
|
33
|
+
H3_EXPORT(h3ToGeo)(h3Index, ¢roid);
|
|
34
|
+
|
|
35
|
+
H3Index geoChild = H3_EXPORT(geoToH3)(¢roid, childRes);
|
|
36
|
+
H3Index centerChild =
|
|
37
|
+
H3_EXPORT(h3ToCenterChild)(h3Index, childRes);
|
|
38
|
+
|
|
39
|
+
t_assert(
|
|
40
|
+
centerChild == geoChild,
|
|
41
|
+
"center child should be same as indexed centroid at child "
|
|
42
|
+
"resolution");
|
|
43
|
+
t_assert(H3_EXPORT(h3GetResolution)(centerChild) == childRes,
|
|
44
|
+
"center child should have correct resolution");
|
|
45
|
+
t_assert(
|
|
46
|
+
H3_EXPORT(h3ToParent)(centerChild, res) == h3Index,
|
|
47
|
+
"parent at original resolution should be initial index");
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
TEST(sameRes) {
|
|
53
|
+
int res = H3_EXPORT(h3GetResolution)(baseHex);
|
|
54
|
+
t_assert(H3_EXPORT(h3ToCenterChild)(baseHex, res) == baseHex,
|
|
55
|
+
"center child at same resolution should return self");
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
TEST(invalidInputs) {
|
|
59
|
+
int res = H3_EXPORT(h3GetResolution)(baseHex);
|
|
60
|
+
t_assert(H3_EXPORT(h3ToCenterChild)(baseHex, res - 1) == 0,
|
|
61
|
+
"should fail at coarser resolution");
|
|
62
|
+
t_assert(H3_EXPORT(h3ToCenterChild)(baseHex, -1) == 0,
|
|
63
|
+
"should fail for negative resolution");
|
|
64
|
+
t_assert(H3_EXPORT(h3ToCenterChild)(baseHex, MAX_H3_RES + 1) == 0,
|
|
65
|
+
"should fail beyond finest resolution");
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright 2017-
|
|
2
|
+
* Copyright 2017-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.
|
|
@@ -109,7 +109,7 @@ SUITE(h3ToChildren) {
|
|
|
109
109
|
free(children);
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
-
TEST(
|
|
112
|
+
TEST(childResTooCoarse) {
|
|
113
113
|
const int expectedCount = 0;
|
|
114
114
|
const int paddedCount = 7;
|
|
115
115
|
|
|
@@ -120,6 +120,18 @@ SUITE(h3ToChildren) {
|
|
|
120
120
|
free(children);
|
|
121
121
|
}
|
|
122
122
|
|
|
123
|
+
TEST(childResTooFine) {
|
|
124
|
+
const int expectedCount = 0;
|
|
125
|
+
const int paddedCount = 7;
|
|
126
|
+
H3Index sfHexMax = H3_EXPORT(geoToH3)(&sf, MAX_H3_RES);
|
|
127
|
+
|
|
128
|
+
H3Index* children = calloc(paddedCount, sizeof(H3Index));
|
|
129
|
+
H3_EXPORT(h3ToChildren)(sfHexMax, MAX_H3_RES + 1, children);
|
|
130
|
+
|
|
131
|
+
verifyCountAndUniqueness(children, paddedCount, expectedCount);
|
|
132
|
+
free(children);
|
|
133
|
+
}
|
|
134
|
+
|
|
123
135
|
TEST(pentagonChildren) {
|
|
124
136
|
H3Index pentagon;
|
|
125
137
|
setH3Index(&pentagon, 1, 4, 0);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright 2018 Uber Technologies, Inc.
|
|
2
|
+
* Copyright 2018-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.
|
|
@@ -32,198 +32,6 @@
|
|
|
32
32
|
#include "test.h"
|
|
33
33
|
#include "utility.h"
|
|
34
34
|
|
|
35
|
-
static const int MAX_DISTANCES[] = {1, 2, 5, 12, 19, 26};
|
|
36
|
-
|
|
37
|
-
// The same traversal constants from algos.c (for hexRange) here reused as local
|
|
38
|
-
// IJ vectors.
|
|
39
|
-
static const CoordIJ DIRECTIONS[6] = {{0, 1}, {-1, 0}, {-1, -1},
|
|
40
|
-
{0, -1}, {1, 0}, {1, 1}};
|
|
41
|
-
|
|
42
|
-
static const CoordIJ NEXT_RING_DIRECTION = {1, 0};
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Test that the local coordinates for an index map to itself.
|
|
46
|
-
*/
|
|
47
|
-
void localIjToH3_identity_assertions(H3Index h3) {
|
|
48
|
-
CoordIJ ij;
|
|
49
|
-
t_assert(H3_EXPORT(experimentalH3ToLocalIj)(h3, h3, &ij) == 0,
|
|
50
|
-
"able to setup localIjToH3 test");
|
|
51
|
-
|
|
52
|
-
H3Index retrieved;
|
|
53
|
-
t_assert(H3_EXPORT(experimentalLocalIjToH3)(h3, &ij, &retrieved) == 0,
|
|
54
|
-
"got an index back from localIjTOh3");
|
|
55
|
-
t_assert(h3 == retrieved, "round trip through local IJ space works");
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Test that coordinates for an index match some simple rules about index
|
|
60
|
-
* digits, when using the index as its own origin. That is, that the IJ
|
|
61
|
-
* coordinates are in the coordinate space of the origin's base cell.
|
|
62
|
-
*/
|
|
63
|
-
void h3ToLocalIj_coordinates_assertions(H3Index h3) {
|
|
64
|
-
int r = H3_GET_RESOLUTION(h3);
|
|
65
|
-
|
|
66
|
-
CoordIJ ij;
|
|
67
|
-
t_assert(H3_EXPORT(experimentalH3ToLocalIj)(h3, h3, &ij) == 0,
|
|
68
|
-
"get ij for origin");
|
|
69
|
-
CoordIJK ijk;
|
|
70
|
-
ijToIjk(&ij, &ijk);
|
|
71
|
-
if (r == 0) {
|
|
72
|
-
t_assert(_ijkMatches(&ijk, &UNIT_VECS[0]) == 1, "res 0 cell at 0,0,0");
|
|
73
|
-
} else if (r == 1) {
|
|
74
|
-
t_assert(_ijkMatches(&ijk, &UNIT_VECS[H3_GET_INDEX_DIGIT(h3, 1)]) == 1,
|
|
75
|
-
"res 1 cell at expected coordinates");
|
|
76
|
-
} else if (r == 2) {
|
|
77
|
-
CoordIJK expected = UNIT_VECS[H3_GET_INDEX_DIGIT(h3, 1)];
|
|
78
|
-
_downAp7r(&expected);
|
|
79
|
-
_neighbor(&expected, H3_GET_INDEX_DIGIT(h3, 2));
|
|
80
|
-
t_assert(_ijkMatches(&ijk, &expected) == 1,
|
|
81
|
-
"res 2 cell at expected coordinates");
|
|
82
|
-
} else {
|
|
83
|
-
t_assert(0, "resolution supported by test function (coordinates)");
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Test the the immediate neighbors of an index are at the expected locations in
|
|
89
|
-
* the local IJ coordinate space.
|
|
90
|
-
*/
|
|
91
|
-
void h3ToLocalIj_neighbors_assertions(H3Index h3) {
|
|
92
|
-
CoordIJ origin = {0};
|
|
93
|
-
t_assert(H3_EXPORT(experimentalH3ToLocalIj)(h3, h3, &origin) == 0,
|
|
94
|
-
"got ij for origin");
|
|
95
|
-
CoordIJK originIjk;
|
|
96
|
-
ijToIjk(&origin, &originIjk);
|
|
97
|
-
|
|
98
|
-
for (Direction d = K_AXES_DIGIT; d < INVALID_DIGIT; d++) {
|
|
99
|
-
if (d == K_AXES_DIGIT && H3_EXPORT(h3IsPentagon)(h3)) {
|
|
100
|
-
continue;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
int rotations = 0;
|
|
104
|
-
H3Index offset = h3NeighborRotations(h3, d, &rotations);
|
|
105
|
-
|
|
106
|
-
CoordIJ ij = {0};
|
|
107
|
-
t_assert(H3_EXPORT(experimentalH3ToLocalIj)(h3, offset, &ij) == 0,
|
|
108
|
-
"got ij for destination");
|
|
109
|
-
CoordIJK ijk;
|
|
110
|
-
ijToIjk(&ij, &ijk);
|
|
111
|
-
CoordIJK invertedIjk = {0};
|
|
112
|
-
_neighbor(&invertedIjk, d);
|
|
113
|
-
for (int i = 0; i < 3; i++) {
|
|
114
|
-
_ijkRotate60ccw(&invertedIjk);
|
|
115
|
-
}
|
|
116
|
-
_ijkAdd(&invertedIjk, &ijk, &ijk);
|
|
117
|
-
_ijkNormalize(&ijk);
|
|
118
|
-
|
|
119
|
-
t_assert(_ijkMatches(&ijk, &originIjk), "back to origin");
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* Test that the neighbors (k-ring), if they can be found in the local IJ
|
|
125
|
-
* coordinate space, can be converted back to indexes.
|
|
126
|
-
*/
|
|
127
|
-
void localIjToH3_kRing_assertions(H3Index h3) {
|
|
128
|
-
int r = H3_GET_RESOLUTION(h3);
|
|
129
|
-
t_assert(r <= 5, "resolution supported by test function (kRing)");
|
|
130
|
-
int maxK = MAX_DISTANCES[r];
|
|
131
|
-
|
|
132
|
-
int sz = H3_EXPORT(maxKringSize)(maxK);
|
|
133
|
-
H3Index *neighbors = calloc(sz, sizeof(H3Index));
|
|
134
|
-
int *distances = calloc(sz, sizeof(int));
|
|
135
|
-
|
|
136
|
-
H3_EXPORT(kRingDistances)(h3, maxK, neighbors, distances);
|
|
137
|
-
|
|
138
|
-
for (int i = 0; i < sz; i++) {
|
|
139
|
-
if (neighbors[i] == 0) {
|
|
140
|
-
continue;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
CoordIJ ij;
|
|
144
|
-
// Don't consider indexes which we can't unfold in the first place
|
|
145
|
-
if (H3_EXPORT(experimentalH3ToLocalIj)(h3, neighbors[i], &ij) == 0) {
|
|
146
|
-
H3Index retrieved;
|
|
147
|
-
t_assert(
|
|
148
|
-
H3_EXPORT(experimentalLocalIjToH3)(h3, &ij, &retrieved) == 0,
|
|
149
|
-
"retrieved index for unfolded coordinates");
|
|
150
|
-
t_assert(retrieved == neighbors[i],
|
|
151
|
-
"round trip neighboring index matches expected");
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
free(distances);
|
|
156
|
-
free(neighbors);
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
void localIjToH3_traverse_assertions(H3Index h3) {
|
|
160
|
-
int r = H3_GET_RESOLUTION(h3);
|
|
161
|
-
t_assert(r <= 5, "resolution supported by test function (traverse)");
|
|
162
|
-
int k = MAX_DISTANCES[r];
|
|
163
|
-
|
|
164
|
-
CoordIJ ij;
|
|
165
|
-
t_assert(H3_EXPORT(experimentalH3ToLocalIj)(h3, h3, &ij) == 0,
|
|
166
|
-
"Got origin coordinates");
|
|
167
|
-
|
|
168
|
-
// This logic is from hexRangeDistances.
|
|
169
|
-
// 0 < ring <= k, current ring
|
|
170
|
-
int ring = 1;
|
|
171
|
-
// 0 <= direction < 6, current side of the ring
|
|
172
|
-
int direction = 0;
|
|
173
|
-
// 0 <= i < ring, current position on the side of the ring
|
|
174
|
-
int i = 0;
|
|
175
|
-
|
|
176
|
-
while (ring <= k) {
|
|
177
|
-
if (direction == 0 && i == 0) {
|
|
178
|
-
ij.i += NEXT_RING_DIRECTION.i;
|
|
179
|
-
ij.j += NEXT_RING_DIRECTION.j;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
ij.i += DIRECTIONS[direction].i;
|
|
183
|
-
ij.j += DIRECTIONS[direction].j;
|
|
184
|
-
|
|
185
|
-
H3Index testH3;
|
|
186
|
-
|
|
187
|
-
int failed = H3_EXPORT(experimentalLocalIjToH3)(h3, &ij, &testH3);
|
|
188
|
-
if (!failed) {
|
|
189
|
-
t_assert(H3_EXPORT(h3IsValid)(testH3),
|
|
190
|
-
"test coordinates result in valid index");
|
|
191
|
-
|
|
192
|
-
CoordIJ expectedIj;
|
|
193
|
-
int reverseFailed =
|
|
194
|
-
H3_EXPORT(experimentalH3ToLocalIj)(h3, testH3, &expectedIj);
|
|
195
|
-
// If it doesn't give a coordinate for this origin,index pair that's
|
|
196
|
-
// OK.
|
|
197
|
-
if (!reverseFailed) {
|
|
198
|
-
if (expectedIj.i != ij.i || expectedIj.j != ij.j) {
|
|
199
|
-
// Multiple coordinates for the same index can happen due to
|
|
200
|
-
// pentagon distortion. In that case, the other coordinates
|
|
201
|
-
// should also belong to the same index.
|
|
202
|
-
H3Index testTestH3;
|
|
203
|
-
t_assert(H3_EXPORT(experimentalLocalIjToH3)(
|
|
204
|
-
h3, &expectedIj, &testTestH3) == 0,
|
|
205
|
-
"converted coordinates again");
|
|
206
|
-
t_assert(testH3 == testTestH3,
|
|
207
|
-
"index has normalizable coordinates in "
|
|
208
|
-
"local IJ");
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
i++;
|
|
214
|
-
// Check if end of this side of the k-ring
|
|
215
|
-
if (i == ring) {
|
|
216
|
-
i = 0;
|
|
217
|
-
direction++;
|
|
218
|
-
// Check if end of this ring.
|
|
219
|
-
if (direction == 6) {
|
|
220
|
-
direction = 0;
|
|
221
|
-
ring++;
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
|
|
227
35
|
SUITE(h3ToLocalIj) {
|
|
228
36
|
// Some indexes that represent base cells. Base cells
|
|
229
37
|
// are hexagons except for `pent1`.
|
|
@@ -239,42 +47,6 @@ SUITE(h3ToLocalIj) {
|
|
|
239
47
|
H3Index pent1 = H3_INIT;
|
|
240
48
|
setH3Index(&pent1, 0, 4, 0);
|
|
241
49
|
|
|
242
|
-
TEST(localIjToH3_identity) {
|
|
243
|
-
iterateAllIndexesAtRes(0, localIjToH3_identity_assertions);
|
|
244
|
-
iterateAllIndexesAtRes(1, localIjToH3_identity_assertions);
|
|
245
|
-
iterateAllIndexesAtRes(2, localIjToH3_identity_assertions);
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
TEST(h3ToLocalIj_coordinates) {
|
|
249
|
-
iterateAllIndexesAtRes(0, h3ToLocalIj_coordinates_assertions);
|
|
250
|
-
iterateAllIndexesAtRes(1, h3ToLocalIj_coordinates_assertions);
|
|
251
|
-
iterateAllIndexesAtRes(2, h3ToLocalIj_coordinates_assertions);
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
TEST(h3ToLocalIj_neighbors) {
|
|
255
|
-
iterateAllIndexesAtRes(0, h3ToLocalIj_neighbors_assertions);
|
|
256
|
-
iterateAllIndexesAtRes(1, h3ToLocalIj_neighbors_assertions);
|
|
257
|
-
iterateAllIndexesAtRes(2, h3ToLocalIj_neighbors_assertions);
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
TEST(localIjToH3_kRing) {
|
|
261
|
-
iterateAllIndexesAtRes(0, localIjToH3_kRing_assertions);
|
|
262
|
-
iterateAllIndexesAtRes(1, localIjToH3_kRing_assertions);
|
|
263
|
-
iterateAllIndexesAtRes(2, localIjToH3_kRing_assertions);
|
|
264
|
-
// Don't iterate all of res 3, to save time
|
|
265
|
-
iterateAllIndexesAtResPartial(3, localIjToH3_kRing_assertions, 27);
|
|
266
|
-
// Further resolutions aren't tested to save time.
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
TEST(localIjToH3_traverse) {
|
|
270
|
-
iterateAllIndexesAtRes(0, localIjToH3_traverse_assertions);
|
|
271
|
-
iterateAllIndexesAtRes(1, localIjToH3_traverse_assertions);
|
|
272
|
-
iterateAllIndexesAtRes(2, localIjToH3_traverse_assertions);
|
|
273
|
-
// Don't iterate all of res 3, to save time
|
|
274
|
-
iterateAllIndexesAtResPartial(3, localIjToH3_traverse_assertions, 27);
|
|
275
|
-
// Further resolutions aren't tested to save time.
|
|
276
|
-
}
|
|
277
|
-
|
|
278
50
|
TEST(ijkBaseCells) {
|
|
279
51
|
CoordIJK ijk;
|
|
280
52
|
t_assert(h3ToLocalIjk(pent1, bc1, &ijk) == 0,
|
|
@@ -300,7 +72,17 @@ SUITE(h3ToLocalIj) {
|
|
|
300
72
|
ij.i = 2;
|
|
301
73
|
t_assert(
|
|
302
74
|
H3_EXPORT(experimentalLocalIjToH3)(origin, &ij, &retrieved) != 0,
|
|
303
|
-
"out of range base cell");
|
|
75
|
+
"out of range base cell (1)");
|
|
76
|
+
ij.i = 0;
|
|
77
|
+
ij.j = 2;
|
|
78
|
+
t_assert(
|
|
79
|
+
H3_EXPORT(experimentalLocalIjToH3)(origin, &ij, &retrieved) != 0,
|
|
80
|
+
"out of range base cell (2)");
|
|
81
|
+
ij.i = -2;
|
|
82
|
+
ij.j = -2;
|
|
83
|
+
t_assert(
|
|
84
|
+
H3_EXPORT(experimentalLocalIjToH3)(origin, &ij, &retrieved) != 0,
|
|
85
|
+
"out of range base cell (3)");
|
|
304
86
|
}
|
|
305
87
|
|
|
306
88
|
TEST(ijOutOfRange) {
|