h3 3.6.0 → 3.7.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/.github/workflows/ruby_ci.yml +30 -0
- data/.rubocop.yml +1 -1
- data/.ruby-version +1 -0
- data/CHANGELOG.md +39 -0
- data/Gemfile.lock +6 -24
- data/LICENSE.md +1 -1
- data/README.md +2 -3
- data/ext/h3/src/.github/workflows/test-linux.yml +118 -0
- data/ext/h3/src/.github/workflows/test-macos.yml +42 -0
- data/ext/h3/src/.github/workflows/test-website.yml +32 -0
- data/ext/h3/src/.github/workflows/test-windows.yml +44 -0
- data/ext/h3/src/.gitignore +5 -0
- data/ext/h3/src/.travis.yml +20 -42
- data/ext/h3/src/CHANGELOG.md +57 -0
- data/ext/h3/src/CMakeLists.txt +135 -33
- data/ext/h3/src/CONTRIBUTING.md +1 -1
- data/ext/h3/src/README.md +61 -11
- data/ext/h3/src/RELEASE.md +3 -1
- data/ext/h3/src/VERSION +1 -1
- data/ext/h3/src/dev-docs/RFCs/rfc-template.md +21 -0
- data/ext/h3/src/dev-docs/RFCs/v4.0.0/error-handling-rfc.md +21 -0
- data/ext/h3/src/dev-docs/RFCs/v4.0.0/names_for_concepts_types_functions.md +276 -0
- data/ext/h3/src/dev-docs/RFCs/v4.0.0/overrideable-allocators-rfc.md +141 -0
- data/ext/h3/src/dev-docs/RFCs/v4.0.0/polyfill-modes-rfc.md +21 -0
- data/ext/h3/src/dev-docs/RFCs/v4.0.0/vertex-mode-rfc.md +50 -0
- data/ext/h3/src/dev-docs/build_windows.md +6 -1
- data/ext/h3/src/dev-docs/creating_bindings.md +3 -3
- data/ext/h3/src/dev-docs/custom_alloc.md +27 -0
- data/ext/h3/src/docs/{overview/mainpage.md → README.md} +2 -3
- data/ext/h3/src/docs/api/misc.md +76 -0
- data/ext/h3/src/docs/community/applications.md +1 -0
- data/ext/h3/src/docs/community/bindings.md +10 -0
- data/ext/h3/src/docs/community/tutorials.md +8 -3
- data/ext/h3/src/docs/core-library/coordsystems.md +5 -4
- data/ext/h3/src/docs/core-library/filters.md +8 -9
- data/ext/h3/src/docs/core-library/geoToH3desc.md +2 -3
- data/ext/h3/src/docs/core-library/h3ToGeoBoundaryDesc.md +4 -5
- data/ext/h3/src/docs/core-library/h3ToGeoDesc.md +3 -4
- data/ext/h3/src/docs/core-library/h3indexing.md +26 -17
- data/ext/h3/src/docs/core-library/overview.md +2 -3
- data/ext/h3/src/docs/core-library/restable.md +1 -2
- data/ext/h3/src/docs/core-library/usage.md +1 -2
- data/ext/h3/src/docs/table-of-contents.json +47 -0
- data/ext/h3/src/docs/{overview/usecases.md → usecases.md} +6 -11
- data/ext/h3/src/scripts/binding_functions.sh +1 -1
- data/ext/h3/src/scripts/coverage.sh.in +1 -1
- data/ext/h3/src/scripts/update_version.sh +2 -2
- data/ext/h3/src/src/apps/applib/include/args.h +1 -0
- data/ext/h3/src/src/apps/applib/include/test.h +1 -0
- data/ext/h3/src/src/apps/applib/include/utility.h +7 -1
- data/ext/h3/src/src/apps/applib/lib/args.c +2 -0
- data/ext/h3/src/src/apps/applib/lib/kml.c +2 -0
- data/ext/h3/src/src/apps/applib/lib/test.c +1 -0
- data/ext/h3/src/src/apps/applib/lib/utility.c +133 -2
- data/ext/h3/src/src/apps/benchmarks/benchmarkH3Api.c +1 -1
- data/ext/h3/src/{website/html.config.js → src/apps/benchmarks/benchmarkH3UniEdge.c} +15 -12
- data/ext/h3/src/src/apps/filters/h3ToComponents.c +1 -0
- data/ext/h3/src/src/apps/filters/h3ToGeo.c +1 -0
- data/ext/h3/src/src/apps/filters/h3ToGeoBoundary.c +1 -0
- data/ext/h3/src/src/apps/filters/h3ToLocalIj.c +1 -0
- data/ext/h3/src/src/apps/filters/hexRange.c +1 -0
- data/ext/h3/src/src/apps/filters/kRing.c +1 -0
- data/ext/h3/src/src/apps/filters/localIjToH3.c +1 -0
- data/ext/h3/src/src/apps/miscapps/generateFaceCenterPoint.c +1 -0
- data/ext/h3/src/src/apps/miscapps/generateNumHexagons.c +1 -0
- data/ext/h3/src/src/apps/miscapps/generatePentagonDirectionFaces.c +67 -0
- data/ext/h3/src/src/apps/miscapps/h3ToGeoBoundaryHier.c +1 -0
- data/ext/h3/src/src/apps/miscapps/h3ToGeoHier.c +1 -0
- data/ext/h3/src/src/apps/miscapps/h3ToHier.c +1 -0
- data/ext/h3/src/src/apps/testapps/mkRandGeo.c +1 -0
- data/ext/h3/src/src/apps/testapps/mkRandGeoBoundary.c +1 -0
- data/ext/h3/src/src/apps/testapps/testBBox.c +1 -0
- data/ext/h3/src/src/apps/testapps/testBaseCells.c +15 -1
- data/ext/h3/src/src/apps/testapps/testCompact.c +109 -2
- data/ext/h3/src/src/apps/testapps/testCoordIj.c +1 -0
- data/ext/h3/src/src/apps/testapps/testGeoCoord.c +47 -8
- data/ext/h3/src/src/apps/testapps/testGeoToH3.c +1 -0
- data/ext/h3/src/src/apps/testapps/testH3Api.c +1 -0
- data/ext/h3/src/src/apps/testapps/testH3CellArea.c +47 -0
- data/ext/h3/src/src/apps/testapps/testH3CellAreaExhaustive.c +180 -0
- data/ext/h3/src/src/apps/testapps/testH3Distance.c +1 -0
- data/ext/h3/src/src/apps/testapps/testH3DistanceExhaustive.c +1 -0
- data/ext/h3/src/src/apps/testapps/testH3GetFaces.c +1 -0
- data/ext/h3/src/src/apps/testapps/testH3Index.c +33 -3
- data/ext/h3/src/src/apps/testapps/testH3Line.c +1 -0
- data/ext/h3/src/src/apps/testapps/testH3LineExhaustive.c +1 -0
- data/ext/h3/src/src/apps/testapps/testH3Memory.c +175 -0
- data/ext/h3/src/src/apps/testapps/testH3NeighborRotations.c +1 -0
- data/ext/h3/src/src/apps/testapps/testH3SetToLinkedGeo.c +1 -0
- data/ext/h3/src/src/apps/testapps/testH3SetToVertexGraph.c +1 -0
- data/ext/h3/src/src/apps/testapps/testH3ToCenterChild.c +1 -0
- data/ext/h3/src/src/apps/testapps/testH3ToChildren.c +1 -0
- data/ext/h3/src/src/apps/testapps/testH3ToGeo.c +1 -0
- data/ext/h3/src/src/apps/testapps/testH3ToGeoBoundary.c +1 -0
- data/ext/h3/src/src/apps/testapps/testH3ToLocalIj.c +12 -6
- data/ext/h3/src/src/apps/testapps/testH3ToLocalIjExhaustive.c +1 -0
- data/ext/h3/src/src/apps/testapps/testH3ToParent.c +1 -0
- data/ext/h3/src/src/apps/testapps/testH3UniEdge.c +45 -16
- data/ext/h3/src/src/apps/testapps/testH3UniEdgeExhaustive.c +111 -0
- data/ext/h3/src/src/apps/testapps/testHexRanges.c +1 -0
- data/ext/h3/src/src/apps/testapps/testHexRing.c +1 -0
- data/ext/h3/src/src/apps/testapps/testKRing.c +19 -0
- data/ext/h3/src/src/apps/testapps/testLinkedGeo.c +1 -0
- data/ext/h3/src/src/apps/testapps/testMaxH3ToChildrenSize.c +1 -0
- data/ext/h3/src/src/apps/testapps/testPentagonIndexes.c +1 -0
- data/ext/h3/src/src/apps/testapps/testPolyfill.c +72 -9
- data/ext/h3/src/src/apps/testapps/testPolyfillReported.c +157 -0
- data/ext/h3/src/src/apps/testapps/testPolygon.c +27 -1
- data/ext/h3/src/src/apps/testapps/testVec2d.c +1 -0
- data/ext/h3/src/src/apps/testapps/testVec3d.c +1 -0
- data/ext/h3/src/src/apps/testapps/testVertex.c +66 -0
- data/ext/h3/src/src/apps/testapps/testVertexGraph.c +1 -0
- data/ext/h3/src/src/h3lib/include/algos.h +8 -0
- data/ext/h3/src/src/h3lib/include/alloc.h +40 -0
- data/ext/h3/src/src/h3lib/include/baseCells.h +4 -0
- data/ext/h3/src/src/h3lib/include/bbox.h +4 -1
- data/ext/h3/src/src/h3lib/include/faceijk.h +3 -2
- data/ext/h3/src/src/h3lib/include/geoCoord.h +2 -3
- data/ext/h3/src/src/h3lib/include/h3Index.h +37 -4
- data/ext/h3/src/src/h3lib/include/h3api.h.in +65 -17
- data/ext/h3/src/src/h3lib/include/linkedGeo.h +1 -0
- data/ext/h3/src/src/h3lib/include/polygon.h +1 -0
- data/ext/h3/src/src/h3lib/include/polygonAlgos.h +1 -0
- data/ext/h3/src/src/h3lib/include/vertex.h +44 -0
- data/ext/h3/src/src/h3lib/include/vertexGraph.h +1 -0
- data/ext/h3/src/src/h3lib/lib/algos.c +304 -76
- data/ext/h3/src/src/h3lib/lib/baseCells.c +26 -4
- data/ext/h3/src/src/h3lib/lib/bbox.c +56 -27
- data/ext/h3/src/src/h3lib/lib/coordijk.c +2 -0
- data/ext/h3/src/src/h3lib/lib/faceijk.c +32 -21
- data/ext/h3/src/src/h3lib/lib/geoCoord.c +162 -44
- data/ext/h3/src/src/h3lib/lib/h3Index.c +83 -42
- data/ext/h3/src/src/h3lib/lib/h3UniEdge.c +42 -57
- data/ext/h3/src/src/h3lib/lib/linkedGeo.c +20 -15
- data/ext/h3/src/src/h3lib/lib/localij.c +1 -1
- data/ext/h3/src/src/h3lib/lib/polygon.c +2 -0
- data/ext/h3/src/src/h3lib/lib/vec2d.c +1 -0
- data/ext/h3/src/src/h3lib/lib/vec3d.c +1 -0
- data/ext/h3/src/src/h3lib/lib/vertex.c +134 -0
- data/ext/h3/src/src/h3lib/lib/vertexGraph.c +8 -5
- data/ext/h3/src/website/.eslintignore +2 -0
- data/ext/h3/src/website/.gitignore +57 -0
- data/ext/h3/src/website/.nvmrc +1 -0
- data/ext/h3/src/website/README.md +8 -6
- data/ext/h3/src/website/gatsby-config.js +83 -0
- data/ext/h3/src/website/package.json +20 -12
- data/ext/h3/src/website/scripts/build-to-gh-pages.sh +7 -5
- data/ext/h3/src/website/src/.gitkeep +0 -0
- data/ext/h3/src/website/templates/documentation.jsx +129 -0
- data/ext/h3/src/website/yarn.lock +13723 -0
- data/h3.gemspec +2 -2
- data/lib/h3/bindings/base.rb +14 -4
- data/lib/h3/bindings/private.rb +12 -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 +119 -14
- 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/miscellaneous_spec.rb +117 -0
- data/spec/{region_spec.rb → regions_spec.rb} +1 -1
- data/spec/spec_helper.rb +2 -2
- metadata +44 -36
- data/.travis.yml +0 -11
- data/ext/h3/src/.ycm_extra_conf.py +0 -92
- data/ext/h3/src/appveyor.yml +0 -50
- data/ext/h3/src/website/src/config.js +0 -46
- data/ext/h3/src/website/src/mdRoutes.js +0 -151
- data/ext/h3/src/website/src/styles/_variables.scss +0 -16
- data/ext/h3/src/website/src/styles/index.scss +0 -3
- data/ext/h3/src/website/static/index.html +0 -15
|
@@ -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.
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
17
|
#include <stdlib.h>
|
|
18
|
+
|
|
18
19
|
#include "constants.h"
|
|
19
20
|
#include "h3Index.h"
|
|
20
21
|
#include "test.h"
|
|
@@ -152,6 +153,105 @@ SUITE(compact) {
|
|
|
152
153
|
"compact fails on duplicate input");
|
|
153
154
|
}
|
|
154
155
|
|
|
156
|
+
TEST(compact_duplicateMinimum) {
|
|
157
|
+
// Test that the minimum number of duplicate hexagons causes failure
|
|
158
|
+
H3Index h3;
|
|
159
|
+
int res = 10;
|
|
160
|
+
// Arbitrary index
|
|
161
|
+
setH3Index(&h3, res, 0, 2);
|
|
162
|
+
|
|
163
|
+
int arrSize = H3_EXPORT(maxH3ToChildrenSize)(h3, res + 1) + 1;
|
|
164
|
+
H3Index* children = calloc(arrSize, sizeof(H3Index));
|
|
165
|
+
|
|
166
|
+
H3_EXPORT(h3ToChildren)(h3, res + 1, children);
|
|
167
|
+
// duplicate one index
|
|
168
|
+
children[arrSize - 1] = children[0];
|
|
169
|
+
|
|
170
|
+
H3Index* output = calloc(arrSize, sizeof(H3Index));
|
|
171
|
+
|
|
172
|
+
int compactResult = H3_EXPORT(compact)(children, output, arrSize);
|
|
173
|
+
t_assert(compactResult == COMPACT_DUPLICATE,
|
|
174
|
+
"compact fails on duplicate input (single duplicate)");
|
|
175
|
+
|
|
176
|
+
free(output);
|
|
177
|
+
free(children);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
TEST(compact_duplicatePentagonLimit) {
|
|
181
|
+
// Test that the minimum number of duplicate hexagons causes failure
|
|
182
|
+
H3Index h3;
|
|
183
|
+
int res = 10;
|
|
184
|
+
// Arbitrary pentagon parent cell
|
|
185
|
+
setH3Index(&h3, res, 4, 0);
|
|
186
|
+
|
|
187
|
+
int arrSize = H3_EXPORT(maxH3ToChildrenSize)(h3, res + 1) + 1;
|
|
188
|
+
H3Index* children = calloc(arrSize, sizeof(H3Index));
|
|
189
|
+
|
|
190
|
+
H3_EXPORT(h3ToChildren)(h3, res + 1, children);
|
|
191
|
+
// duplicate one index
|
|
192
|
+
children[arrSize - 1] = H3_EXPORT(h3ToCenterChild)(h3, res + 1);
|
|
193
|
+
|
|
194
|
+
H3Index* output = calloc(arrSize, sizeof(H3Index));
|
|
195
|
+
|
|
196
|
+
int compactResult = H3_EXPORT(compact)(children, output, arrSize);
|
|
197
|
+
t_assert(compactResult == COMPACT_DUPLICATE,
|
|
198
|
+
"compact fails on duplicate input (pentagon parent)");
|
|
199
|
+
|
|
200
|
+
free(output);
|
|
201
|
+
free(children);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
TEST(compact_duplicateIgnored) {
|
|
205
|
+
// Test that duplicated cells are not rejected by compact.
|
|
206
|
+
// This is not necessarily desired - just asserting the
|
|
207
|
+
// existing behavior.
|
|
208
|
+
H3Index h3;
|
|
209
|
+
int res = 10;
|
|
210
|
+
// Arbitrary index
|
|
211
|
+
setH3Index(&h3, res, 0, 2);
|
|
212
|
+
|
|
213
|
+
int arrSize = H3_EXPORT(maxH3ToChildrenSize)(h3, res + 1);
|
|
214
|
+
H3Index* children = calloc(arrSize, sizeof(H3Index));
|
|
215
|
+
|
|
216
|
+
H3_EXPORT(h3ToChildren)(h3, res + 1, children);
|
|
217
|
+
// duplicate one index
|
|
218
|
+
children[arrSize - 1] = children[0];
|
|
219
|
+
|
|
220
|
+
H3Index* output = calloc(arrSize, sizeof(H3Index));
|
|
221
|
+
|
|
222
|
+
int compactResult = H3_EXPORT(compact)(children, output, arrSize);
|
|
223
|
+
t_assert(compactResult == COMPACT_SUCCESS,
|
|
224
|
+
"compact succeeds on duplicate input (correct count)");
|
|
225
|
+
|
|
226
|
+
free(output);
|
|
227
|
+
free(children);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
TEST(compact_empty) {
|
|
231
|
+
t_assert(H3_EXPORT(compact)(NULL, NULL, 0) == 0,
|
|
232
|
+
"compact succeeds on empty input");
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
TEST(compact_disparate) {
|
|
236
|
+
// Exercises a case where compaction needs to be tested but none is
|
|
237
|
+
// possible
|
|
238
|
+
const int numHex = 7;
|
|
239
|
+
H3Index disparate[] = {0, 0, 0, 0, 0, 0, 0};
|
|
240
|
+
for (int i = 0; i < numHex; i++) {
|
|
241
|
+
setH3Index(&disparate[i], 1, i, CENTER_DIGIT);
|
|
242
|
+
}
|
|
243
|
+
H3Index output[] = {0, 0, 0, 0, 0, 0, 0};
|
|
244
|
+
|
|
245
|
+
t_assert(H3_EXPORT(compact)(disparate, output, numHex) == 0,
|
|
246
|
+
"compact succeeds on disparate input");
|
|
247
|
+
|
|
248
|
+
// Assumes that `output` is an exact copy of `disparate`, including
|
|
249
|
+
// the ordering (which may not necessarily be the case)
|
|
250
|
+
for (int i = 0; i < numHex; i++) {
|
|
251
|
+
t_assert(disparate[i] == output[i], "output set equals input set");
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
155
255
|
TEST(uncompact_wrongRes) {
|
|
156
256
|
int numHex = 3;
|
|
157
257
|
H3Index someHexagons[] = {0, 0, 0};
|
|
@@ -221,6 +321,13 @@ SUITE(compact) {
|
|
|
221
321
|
free(result);
|
|
222
322
|
}
|
|
223
323
|
|
|
324
|
+
TEST(uncompact_empty) {
|
|
325
|
+
int uncompactSz = H3_EXPORT(maxUncompactSize)(NULL, 0, 0);
|
|
326
|
+
t_assert(uncompactSz == 0, "maxUncompactSize accepts empty input");
|
|
327
|
+
t_assert(H3_EXPORT(uncompact)(NULL, 0, NULL, 0, 0) == 0,
|
|
328
|
+
"uncompact accepts empty input");
|
|
329
|
+
}
|
|
330
|
+
|
|
224
331
|
TEST(uncompact_onlyZero) {
|
|
225
332
|
// maxUncompactSize and uncompact both permit 0 indexes
|
|
226
333
|
// in the input array, and skip them. When only a zero is
|
|
@@ -237,7 +344,7 @@ SUITE(compact) {
|
|
|
237
344
|
free(children);
|
|
238
345
|
}
|
|
239
346
|
|
|
240
|
-
TEST(
|
|
347
|
+
TEST(uncompact_withZero) {
|
|
241
348
|
// maxUncompactSize and uncompact both permit 0 indexes
|
|
242
349
|
// in the input array, and skip them.
|
|
243
350
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright 2017-
|
|
2
|
+
* Copyright 2017-2020 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.
|
|
@@ -19,11 +19,14 @@
|
|
|
19
19
|
* usage: `testGeoCoord`
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
|
+
#include <float.h>
|
|
22
23
|
#include <math.h>
|
|
24
|
+
|
|
23
25
|
#include "constants.h"
|
|
24
26
|
#include "geoCoord.h"
|
|
25
27
|
#include "h3api.h"
|
|
26
28
|
#include "test.h"
|
|
29
|
+
#include "utility.h"
|
|
27
30
|
|
|
28
31
|
/**
|
|
29
32
|
* Test a function for all resolutions, where the value should be decreasing as
|
|
@@ -32,7 +35,8 @@
|
|
|
32
35
|
* @param function
|
|
33
36
|
* @param message
|
|
34
37
|
*/
|
|
35
|
-
void testDecreasingFunction(double (*function)(int),
|
|
38
|
+
static void testDecreasingFunction(double (*function)(int),
|
|
39
|
+
const char* message) {
|
|
36
40
|
double last = 0;
|
|
37
41
|
double next;
|
|
38
42
|
for (int i = MAX_H3_RES; i >= 0; i--) {
|
|
@@ -51,20 +55,41 @@ SUITE(geoCoord) {
|
|
|
51
55
|
"radsToDegs/degsToRads invertible");
|
|
52
56
|
}
|
|
53
57
|
|
|
54
|
-
TEST(
|
|
58
|
+
TEST(pointDistRads) {
|
|
55
59
|
GeoCoord p1;
|
|
56
60
|
setGeoDegs(&p1, 10, 10);
|
|
57
61
|
GeoCoord p2;
|
|
58
62
|
setGeoDegs(&p2, 0, 10);
|
|
59
63
|
|
|
60
64
|
// TODO: Epsilon is relatively large
|
|
61
|
-
t_assert(
|
|
65
|
+
t_assert(H3_EXPORT(pointDistRads)(&p1, &p1) < EPSILON_RAD * 1000,
|
|
62
66
|
"0 distance as expected");
|
|
63
|
-
t_assert(fabs(
|
|
64
|
-
|
|
67
|
+
t_assert(fabs(H3_EXPORT(pointDistRads)(&p1, &p2) -
|
|
68
|
+
H3_EXPORT(degsToRads)(10)) < EPSILON_RAD * 1000,
|
|
65
69
|
"distance along longitude as expected");
|
|
66
70
|
}
|
|
67
71
|
|
|
72
|
+
TEST(geoAlmostEqualThreshold) {
|
|
73
|
+
GeoCoord a = {15, 10};
|
|
74
|
+
GeoCoord b = {15, 10};
|
|
75
|
+
t_assert(geoAlmostEqualThreshold(&a, &b, DBL_EPSILON), "same point");
|
|
76
|
+
|
|
77
|
+
b.lat = 15.00001;
|
|
78
|
+
b.lon = 10.00002;
|
|
79
|
+
t_assert(geoAlmostEqualThreshold(&a, &b, 0.0001),
|
|
80
|
+
"differences under threshold");
|
|
81
|
+
|
|
82
|
+
b.lat = 15.00001;
|
|
83
|
+
b.lon = 10;
|
|
84
|
+
t_assert(!geoAlmostEqualThreshold(&a, &b, 0.000001),
|
|
85
|
+
"lat over threshold");
|
|
86
|
+
|
|
87
|
+
b.lat = 15;
|
|
88
|
+
b.lon = 10.00001;
|
|
89
|
+
t_assert(!geoAlmostEqualThreshold(&a, &b, 0.000001),
|
|
90
|
+
"lon over threshold");
|
|
91
|
+
}
|
|
92
|
+
|
|
68
93
|
TEST(constrainLatLng) {
|
|
69
94
|
t_assert(constrainLat(0) == 0, "lat 0");
|
|
70
95
|
t_assert(constrainLat(1) == 1, "lat 1");
|
|
@@ -159,13 +184,27 @@ SUITE(geoCoord) {
|
|
|
159
184
|
double distance = H3_EXPORT(degsToRads)(15);
|
|
160
185
|
|
|
161
186
|
_geoAzDistanceRads(&start, azimuth, distance, &out);
|
|
162
|
-
t_assert(fabs(
|
|
187
|
+
t_assert(fabs(H3_EXPORT(pointDistRads)(&start, &out) - distance) <
|
|
188
|
+
EPSILON_RAD,
|
|
163
189
|
"moved distance is as expected");
|
|
164
190
|
|
|
165
191
|
GeoCoord start2 = out;
|
|
166
192
|
_geoAzDistanceRads(&start2, azimuth + degrees180, distance, &out);
|
|
167
193
|
// TODO: Epsilon is relatively large
|
|
168
|
-
t_assert(
|
|
194
|
+
t_assert(H3_EXPORT(pointDistRads)(&start, &out) < 0.01,
|
|
195
|
+
"moved back to origin");
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
TEST(pointDistRads_wrappedLongitude) {
|
|
199
|
+
const GeoCoord negativeLongitude = {.lat = 0, .lon = -(M_PI + M_PI_2)};
|
|
200
|
+
const GeoCoord zero = {.lat = 0, .lon = 0};
|
|
201
|
+
|
|
202
|
+
t_assert(fabs(M_PI_2 - H3_EXPORT(pointDistRads)(&negativeLongitude,
|
|
203
|
+
&zero)) < EPSILON_RAD,
|
|
204
|
+
"Distance with wrapped longitude");
|
|
205
|
+
t_assert(fabs(M_PI_2 - H3_EXPORT(pointDistRads)(
|
|
206
|
+
&zero, &negativeLongitude)) < EPSILON_RAD,
|
|
207
|
+
"Distance with wrapped longitude and swapped arguments");
|
|
169
208
|
}
|
|
170
209
|
|
|
171
210
|
TEST(doubleConstants) {
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2020 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
|
+
/** @file
|
|
18
|
+
* @brief tests H3 cell area functions on a few specific cases
|
|
19
|
+
*
|
|
20
|
+
* usage: `testH3CellArea`
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
#include <math.h>
|
|
24
|
+
|
|
25
|
+
#include "h3Index.h"
|
|
26
|
+
#include "test.h"
|
|
27
|
+
|
|
28
|
+
static const double areasKm2[] = {
|
|
29
|
+
2.562182162955496e+06, 4.476842018179411e+05, 6.596162242711056e+04,
|
|
30
|
+
9.228872919002590e+03, 1.318694490797110e+03, 1.879593512281298e+02,
|
|
31
|
+
2.687164354763186e+01, 3.840848847060638e+00, 5.486939641329893e-01,
|
|
32
|
+
7.838600808637444e-02, 1.119834221989390e-02, 1.599777169186614e-03,
|
|
33
|
+
2.285390931423380e-04, 3.264850232091780e-05, 4.664070326136774e-06,
|
|
34
|
+
6.662957615868888e-07};
|
|
35
|
+
|
|
36
|
+
SUITE(h3CellArea) {
|
|
37
|
+
TEST(specific_cell_area) {
|
|
38
|
+
GeoCoord gc = {0.0, 0.0};
|
|
39
|
+
for (int res = 0; res <= MAX_H3_RES - 1; res++) {
|
|
40
|
+
H3Index cell = H3_EXPORT(geoToH3)(&gc, res);
|
|
41
|
+
double area = H3_EXPORT(cellAreaKm2)(cell);
|
|
42
|
+
|
|
43
|
+
t_assert(fabs(area - areasKm2[res]) < 1e-8,
|
|
44
|
+
"cell area should match expectation");
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2020 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
|
+
/** @file
|
|
18
|
+
* @brief tests H3 cell area functions using tests over a large number
|
|
19
|
+
* of indexes.
|
|
20
|
+
*
|
|
21
|
+
* usage: `testH3CellAreaExhaustive`
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
#include <math.h>
|
|
25
|
+
|
|
26
|
+
#include "h3Index.h"
|
|
27
|
+
#include "test.h"
|
|
28
|
+
#include "utility.h"
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Basic checks around the great circle distance between the centers of two
|
|
32
|
+
* neighboring cells. Tests positivity and commutativity.
|
|
33
|
+
*
|
|
34
|
+
* Tests the functions:
|
|
35
|
+
* pointDistRads
|
|
36
|
+
* pointDistKm
|
|
37
|
+
* pointDistM
|
|
38
|
+
*
|
|
39
|
+
* @param edge H3 unidirectional edge denoting neighboring cells
|
|
40
|
+
*/
|
|
41
|
+
static void haversine_assert(H3Index edge) {
|
|
42
|
+
GeoCoord a, b;
|
|
43
|
+
H3Index origin, destination;
|
|
44
|
+
|
|
45
|
+
origin = H3_EXPORT(getOriginH3IndexFromUnidirectionalEdge)(edge);
|
|
46
|
+
H3_EXPORT(h3ToGeo)(origin, &a);
|
|
47
|
+
|
|
48
|
+
destination = H3_EXPORT(getDestinationH3IndexFromUnidirectionalEdge)(edge);
|
|
49
|
+
H3_EXPORT(h3ToGeo)(destination, &b);
|
|
50
|
+
|
|
51
|
+
char pos[] = "distance between cell centers should be positive";
|
|
52
|
+
char comm[] = "pairwise cell distances should be commutative";
|
|
53
|
+
|
|
54
|
+
double ab, ba;
|
|
55
|
+
|
|
56
|
+
ab = H3_EXPORT(pointDistRads)(&a, &b);
|
|
57
|
+
ba = H3_EXPORT(pointDistRads)(&b, &a);
|
|
58
|
+
t_assert(ab > 0, pos);
|
|
59
|
+
t_assert(ab == ba, comm);
|
|
60
|
+
|
|
61
|
+
ab = H3_EXPORT(pointDistKm)(&a, &b);
|
|
62
|
+
ba = H3_EXPORT(pointDistKm)(&b, &a);
|
|
63
|
+
t_assert(ab > 0, pos);
|
|
64
|
+
t_assert(ab == ba, comm);
|
|
65
|
+
|
|
66
|
+
ab = H3_EXPORT(pointDistM)(&a, &b);
|
|
67
|
+
ba = H3_EXPORT(pointDistM)(&b, &a);
|
|
68
|
+
t_assert(ab > 0, pos);
|
|
69
|
+
t_assert(ab == ba, comm);
|
|
70
|
+
|
|
71
|
+
t_assert(H3_EXPORT(pointDistKm)(&a, &b) > H3_EXPORT(pointDistRads)(&a, &b),
|
|
72
|
+
"measurement in kilometers should be greater than in radians");
|
|
73
|
+
t_assert(H3_EXPORT(pointDistM)(&a, &b) > H3_EXPORT(pointDistKm)(&a, &b),
|
|
74
|
+
"measurement in meters should be greater than in kilometers");
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Tests positivity of edge length calculation for the functions:
|
|
79
|
+
*
|
|
80
|
+
* exactEdgeLengthRads
|
|
81
|
+
* exactEdgeLengthKm
|
|
82
|
+
* exactEdgeLengthM
|
|
83
|
+
*
|
|
84
|
+
* @param edge edge to compute the length of
|
|
85
|
+
*/
|
|
86
|
+
static void edge_length_assert(H3Index edge) {
|
|
87
|
+
char msg[] = "edge has positive length";
|
|
88
|
+
|
|
89
|
+
t_assert(H3_EXPORT(exactEdgeLengthRads)(edge) > 0, msg);
|
|
90
|
+
t_assert(H3_EXPORT(exactEdgeLengthKm)(edge) > 0, msg);
|
|
91
|
+
t_assert(H3_EXPORT(exactEdgeLengthM)(edge) > 0, msg);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Test that cell area calculations are positive for the functions:
|
|
96
|
+
*
|
|
97
|
+
* cellAreaRads2
|
|
98
|
+
* cellAreaKm2
|
|
99
|
+
* cellAreaM2
|
|
100
|
+
*
|
|
101
|
+
* @param cell cell to compute the area of
|
|
102
|
+
*/
|
|
103
|
+
static void cell_area_assert(H3Index cell) {
|
|
104
|
+
char msg[] = "cell has positive area";
|
|
105
|
+
|
|
106
|
+
t_assert(H3_EXPORT(cellAreaRads2)(cell) > 0, msg);
|
|
107
|
+
t_assert(H3_EXPORT(cellAreaKm2)(cell) > 0, msg);
|
|
108
|
+
t_assert(H3_EXPORT(cellAreaM2)(cell) > 0, msg);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Apply a cell area calculation function to every cell on the earth at a given
|
|
113
|
+
* resolution, and check that it sums up the total earth area.
|
|
114
|
+
*
|
|
115
|
+
* @param res resolution of the cells
|
|
116
|
+
* @param cell_area callback to compute area of each cell
|
|
117
|
+
* @param target expected earth area in some units
|
|
118
|
+
* @param tol error tolerance allowed between expected and actual
|
|
119
|
+
*/
|
|
120
|
+
static void earth_area_test(int res, double (*cell_area)(H3Index),
|
|
121
|
+
double target, double tol) {
|
|
122
|
+
double area = mapSumAllCells_double(res, cell_area);
|
|
123
|
+
|
|
124
|
+
t_assert(fabs(area - target) < tol,
|
|
125
|
+
"sum of all cells should give earth area");
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
SUITE(h3CellAreaExhaustive) {
|
|
129
|
+
TEST(haversine_distances) {
|
|
130
|
+
iterateAllUnidirectionalEdgesAtRes(0, haversine_assert);
|
|
131
|
+
iterateAllUnidirectionalEdgesAtRes(1, haversine_assert);
|
|
132
|
+
iterateAllUnidirectionalEdgesAtRes(2, haversine_assert);
|
|
133
|
+
iterateAllUnidirectionalEdgesAtRes(3, haversine_assert);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
TEST(edge_length) {
|
|
137
|
+
iterateAllUnidirectionalEdgesAtRes(0, edge_length_assert);
|
|
138
|
+
iterateAllUnidirectionalEdgesAtRes(1, edge_length_assert);
|
|
139
|
+
iterateAllUnidirectionalEdgesAtRes(2, edge_length_assert);
|
|
140
|
+
iterateAllUnidirectionalEdgesAtRes(3, edge_length_assert);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
TEST(cell_area_positive) {
|
|
144
|
+
iterateAllIndexesAtRes(0, cell_area_assert);
|
|
145
|
+
iterateAllIndexesAtRes(1, cell_area_assert);
|
|
146
|
+
iterateAllIndexesAtRes(2, cell_area_assert);
|
|
147
|
+
iterateAllIndexesAtRes(3, cell_area_assert);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
TEST(cell_area_earth) {
|
|
151
|
+
// earth area in different units
|
|
152
|
+
double rads2 = 4 * M_PI;
|
|
153
|
+
double km2 = rads2 * EARTH_RADIUS_KM * EARTH_RADIUS_KM;
|
|
154
|
+
double m2 = km2 * 1000 * 1000;
|
|
155
|
+
|
|
156
|
+
// Notice the drop in accuracy at resolution 1.
|
|
157
|
+
// I think this has something to do with Class II vs Class III
|
|
158
|
+
// resolutions.
|
|
159
|
+
|
|
160
|
+
earth_area_test(0, H3_EXPORT(cellAreaRads2), rads2, 1e-14);
|
|
161
|
+
earth_area_test(0, H3_EXPORT(cellAreaKm2), km2, 1e-6);
|
|
162
|
+
earth_area_test(0, H3_EXPORT(cellAreaM2), m2, 1e0);
|
|
163
|
+
|
|
164
|
+
earth_area_test(1, H3_EXPORT(cellAreaRads2), rads2, 1e-9);
|
|
165
|
+
earth_area_test(1, H3_EXPORT(cellAreaKm2), km2, 1e-1);
|
|
166
|
+
earth_area_test(1, H3_EXPORT(cellAreaM2), m2, 1e5);
|
|
167
|
+
|
|
168
|
+
earth_area_test(2, H3_EXPORT(cellAreaRads2), rads2, 1e-12);
|
|
169
|
+
earth_area_test(2, H3_EXPORT(cellAreaKm2), km2, 1e-5);
|
|
170
|
+
earth_area_test(2, H3_EXPORT(cellAreaM2), m2, 1e0);
|
|
171
|
+
|
|
172
|
+
earth_area_test(3, H3_EXPORT(cellAreaRads2), rads2, 1e-11);
|
|
173
|
+
earth_area_test(3, H3_EXPORT(cellAreaKm2), km2, 1e-3);
|
|
174
|
+
earth_area_test(3, H3_EXPORT(cellAreaM2), m2, 1e3);
|
|
175
|
+
|
|
176
|
+
earth_area_test(4, H3_EXPORT(cellAreaRads2), rads2, 1e-11);
|
|
177
|
+
earth_area_test(4, H3_EXPORT(cellAreaKm2), km2, 1e-3);
|
|
178
|
+
earth_area_test(4, H3_EXPORT(cellAreaM2), m2, 1e2);
|
|
179
|
+
}
|
|
180
|
+
}
|