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.
Files changed (175) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby_ci.yml +30 -0
  3. data/.rubocop.yml +1 -1
  4. data/.ruby-version +1 -0
  5. data/CHANGELOG.md +39 -0
  6. data/Gemfile.lock +6 -24
  7. data/LICENSE.md +1 -1
  8. data/README.md +2 -3
  9. data/ext/h3/src/.github/workflows/test-linux.yml +118 -0
  10. data/ext/h3/src/.github/workflows/test-macos.yml +42 -0
  11. data/ext/h3/src/.github/workflows/test-website.yml +32 -0
  12. data/ext/h3/src/.github/workflows/test-windows.yml +44 -0
  13. data/ext/h3/src/.gitignore +5 -0
  14. data/ext/h3/src/.travis.yml +20 -42
  15. data/ext/h3/src/CHANGELOG.md +57 -0
  16. data/ext/h3/src/CMakeLists.txt +135 -33
  17. data/ext/h3/src/CONTRIBUTING.md +1 -1
  18. data/ext/h3/src/README.md +61 -11
  19. data/ext/h3/src/RELEASE.md +3 -1
  20. data/ext/h3/src/VERSION +1 -1
  21. data/ext/h3/src/dev-docs/RFCs/rfc-template.md +21 -0
  22. data/ext/h3/src/dev-docs/RFCs/v4.0.0/error-handling-rfc.md +21 -0
  23. data/ext/h3/src/dev-docs/RFCs/v4.0.0/names_for_concepts_types_functions.md +276 -0
  24. data/ext/h3/src/dev-docs/RFCs/v4.0.0/overrideable-allocators-rfc.md +141 -0
  25. data/ext/h3/src/dev-docs/RFCs/v4.0.0/polyfill-modes-rfc.md +21 -0
  26. data/ext/h3/src/dev-docs/RFCs/v4.0.0/vertex-mode-rfc.md +50 -0
  27. data/ext/h3/src/dev-docs/build_windows.md +6 -1
  28. data/ext/h3/src/dev-docs/creating_bindings.md +3 -3
  29. data/ext/h3/src/dev-docs/custom_alloc.md +27 -0
  30. data/ext/h3/src/docs/{overview/mainpage.md → README.md} +2 -3
  31. data/ext/h3/src/docs/api/misc.md +76 -0
  32. data/ext/h3/src/docs/community/applications.md +1 -0
  33. data/ext/h3/src/docs/community/bindings.md +10 -0
  34. data/ext/h3/src/docs/community/tutorials.md +8 -3
  35. data/ext/h3/src/docs/core-library/coordsystems.md +5 -4
  36. data/ext/h3/src/docs/core-library/filters.md +8 -9
  37. data/ext/h3/src/docs/core-library/geoToH3desc.md +2 -3
  38. data/ext/h3/src/docs/core-library/h3ToGeoBoundaryDesc.md +4 -5
  39. data/ext/h3/src/docs/core-library/h3ToGeoDesc.md +3 -4
  40. data/ext/h3/src/docs/core-library/h3indexing.md +26 -17
  41. data/ext/h3/src/docs/core-library/overview.md +2 -3
  42. data/ext/h3/src/docs/core-library/restable.md +1 -2
  43. data/ext/h3/src/docs/core-library/usage.md +1 -2
  44. data/ext/h3/src/docs/table-of-contents.json +47 -0
  45. data/ext/h3/src/docs/{overview/usecases.md → usecases.md} +6 -11
  46. data/ext/h3/src/scripts/binding_functions.sh +1 -1
  47. data/ext/h3/src/scripts/coverage.sh.in +1 -1
  48. data/ext/h3/src/scripts/update_version.sh +2 -2
  49. data/ext/h3/src/src/apps/applib/include/args.h +1 -0
  50. data/ext/h3/src/src/apps/applib/include/test.h +1 -0
  51. data/ext/h3/src/src/apps/applib/include/utility.h +7 -1
  52. data/ext/h3/src/src/apps/applib/lib/args.c +2 -0
  53. data/ext/h3/src/src/apps/applib/lib/kml.c +2 -0
  54. data/ext/h3/src/src/apps/applib/lib/test.c +1 -0
  55. data/ext/h3/src/src/apps/applib/lib/utility.c +133 -2
  56. data/ext/h3/src/src/apps/benchmarks/benchmarkH3Api.c +1 -1
  57. data/ext/h3/src/{website/html.config.js → src/apps/benchmarks/benchmarkH3UniEdge.c} +15 -12
  58. data/ext/h3/src/src/apps/filters/h3ToComponents.c +1 -0
  59. data/ext/h3/src/src/apps/filters/h3ToGeo.c +1 -0
  60. data/ext/h3/src/src/apps/filters/h3ToGeoBoundary.c +1 -0
  61. data/ext/h3/src/src/apps/filters/h3ToLocalIj.c +1 -0
  62. data/ext/h3/src/src/apps/filters/hexRange.c +1 -0
  63. data/ext/h3/src/src/apps/filters/kRing.c +1 -0
  64. data/ext/h3/src/src/apps/filters/localIjToH3.c +1 -0
  65. data/ext/h3/src/src/apps/miscapps/generateFaceCenterPoint.c +1 -0
  66. data/ext/h3/src/src/apps/miscapps/generateNumHexagons.c +1 -0
  67. data/ext/h3/src/src/apps/miscapps/generatePentagonDirectionFaces.c +67 -0
  68. data/ext/h3/src/src/apps/miscapps/h3ToGeoBoundaryHier.c +1 -0
  69. data/ext/h3/src/src/apps/miscapps/h3ToGeoHier.c +1 -0
  70. data/ext/h3/src/src/apps/miscapps/h3ToHier.c +1 -0
  71. data/ext/h3/src/src/apps/testapps/mkRandGeo.c +1 -0
  72. data/ext/h3/src/src/apps/testapps/mkRandGeoBoundary.c +1 -0
  73. data/ext/h3/src/src/apps/testapps/testBBox.c +1 -0
  74. data/ext/h3/src/src/apps/testapps/testBaseCells.c +15 -1
  75. data/ext/h3/src/src/apps/testapps/testCompact.c +109 -2
  76. data/ext/h3/src/src/apps/testapps/testCoordIj.c +1 -0
  77. data/ext/h3/src/src/apps/testapps/testGeoCoord.c +47 -8
  78. data/ext/h3/src/src/apps/testapps/testGeoToH3.c +1 -0
  79. data/ext/h3/src/src/apps/testapps/testH3Api.c +1 -0
  80. data/ext/h3/src/src/apps/testapps/testH3CellArea.c +47 -0
  81. data/ext/h3/src/src/apps/testapps/testH3CellAreaExhaustive.c +180 -0
  82. data/ext/h3/src/src/apps/testapps/testH3Distance.c +1 -0
  83. data/ext/h3/src/src/apps/testapps/testH3DistanceExhaustive.c +1 -0
  84. data/ext/h3/src/src/apps/testapps/testH3GetFaces.c +1 -0
  85. data/ext/h3/src/src/apps/testapps/testH3Index.c +33 -3
  86. data/ext/h3/src/src/apps/testapps/testH3Line.c +1 -0
  87. data/ext/h3/src/src/apps/testapps/testH3LineExhaustive.c +1 -0
  88. data/ext/h3/src/src/apps/testapps/testH3Memory.c +175 -0
  89. data/ext/h3/src/src/apps/testapps/testH3NeighborRotations.c +1 -0
  90. data/ext/h3/src/src/apps/testapps/testH3SetToLinkedGeo.c +1 -0
  91. data/ext/h3/src/src/apps/testapps/testH3SetToVertexGraph.c +1 -0
  92. data/ext/h3/src/src/apps/testapps/testH3ToCenterChild.c +1 -0
  93. data/ext/h3/src/src/apps/testapps/testH3ToChildren.c +1 -0
  94. data/ext/h3/src/src/apps/testapps/testH3ToGeo.c +1 -0
  95. data/ext/h3/src/src/apps/testapps/testH3ToGeoBoundary.c +1 -0
  96. data/ext/h3/src/src/apps/testapps/testH3ToLocalIj.c +12 -6
  97. data/ext/h3/src/src/apps/testapps/testH3ToLocalIjExhaustive.c +1 -0
  98. data/ext/h3/src/src/apps/testapps/testH3ToParent.c +1 -0
  99. data/ext/h3/src/src/apps/testapps/testH3UniEdge.c +45 -16
  100. data/ext/h3/src/src/apps/testapps/testH3UniEdgeExhaustive.c +111 -0
  101. data/ext/h3/src/src/apps/testapps/testHexRanges.c +1 -0
  102. data/ext/h3/src/src/apps/testapps/testHexRing.c +1 -0
  103. data/ext/h3/src/src/apps/testapps/testKRing.c +19 -0
  104. data/ext/h3/src/src/apps/testapps/testLinkedGeo.c +1 -0
  105. data/ext/h3/src/src/apps/testapps/testMaxH3ToChildrenSize.c +1 -0
  106. data/ext/h3/src/src/apps/testapps/testPentagonIndexes.c +1 -0
  107. data/ext/h3/src/src/apps/testapps/testPolyfill.c +72 -9
  108. data/ext/h3/src/src/apps/testapps/testPolyfillReported.c +157 -0
  109. data/ext/h3/src/src/apps/testapps/testPolygon.c +27 -1
  110. data/ext/h3/src/src/apps/testapps/testVec2d.c +1 -0
  111. data/ext/h3/src/src/apps/testapps/testVec3d.c +1 -0
  112. data/ext/h3/src/src/apps/testapps/testVertex.c +66 -0
  113. data/ext/h3/src/src/apps/testapps/testVertexGraph.c +1 -0
  114. data/ext/h3/src/src/h3lib/include/algos.h +8 -0
  115. data/ext/h3/src/src/h3lib/include/alloc.h +40 -0
  116. data/ext/h3/src/src/h3lib/include/baseCells.h +4 -0
  117. data/ext/h3/src/src/h3lib/include/bbox.h +4 -1
  118. data/ext/h3/src/src/h3lib/include/faceijk.h +3 -2
  119. data/ext/h3/src/src/h3lib/include/geoCoord.h +2 -3
  120. data/ext/h3/src/src/h3lib/include/h3Index.h +37 -4
  121. data/ext/h3/src/src/h3lib/include/h3api.h.in +65 -17
  122. data/ext/h3/src/src/h3lib/include/linkedGeo.h +1 -0
  123. data/ext/h3/src/src/h3lib/include/polygon.h +1 -0
  124. data/ext/h3/src/src/h3lib/include/polygonAlgos.h +1 -0
  125. data/ext/h3/src/src/h3lib/include/vertex.h +44 -0
  126. data/ext/h3/src/src/h3lib/include/vertexGraph.h +1 -0
  127. data/ext/h3/src/src/h3lib/lib/algos.c +304 -76
  128. data/ext/h3/src/src/h3lib/lib/baseCells.c +26 -4
  129. data/ext/h3/src/src/h3lib/lib/bbox.c +56 -27
  130. data/ext/h3/src/src/h3lib/lib/coordijk.c +2 -0
  131. data/ext/h3/src/src/h3lib/lib/faceijk.c +32 -21
  132. data/ext/h3/src/src/h3lib/lib/geoCoord.c +162 -44
  133. data/ext/h3/src/src/h3lib/lib/h3Index.c +83 -42
  134. data/ext/h3/src/src/h3lib/lib/h3UniEdge.c +42 -57
  135. data/ext/h3/src/src/h3lib/lib/linkedGeo.c +20 -15
  136. data/ext/h3/src/src/h3lib/lib/localij.c +1 -1
  137. data/ext/h3/src/src/h3lib/lib/polygon.c +2 -0
  138. data/ext/h3/src/src/h3lib/lib/vec2d.c +1 -0
  139. data/ext/h3/src/src/h3lib/lib/vec3d.c +1 -0
  140. data/ext/h3/src/src/h3lib/lib/vertex.c +134 -0
  141. data/ext/h3/src/src/h3lib/lib/vertexGraph.c +8 -5
  142. data/ext/h3/src/website/.eslintignore +2 -0
  143. data/ext/h3/src/website/.gitignore +57 -0
  144. data/ext/h3/src/website/.nvmrc +1 -0
  145. data/ext/h3/src/website/README.md +8 -6
  146. data/ext/h3/src/website/gatsby-config.js +83 -0
  147. data/ext/h3/src/website/package.json +20 -12
  148. data/ext/h3/src/website/scripts/build-to-gh-pages.sh +7 -5
  149. data/ext/h3/src/website/src/.gitkeep +0 -0
  150. data/ext/h3/src/website/templates/documentation.jsx +129 -0
  151. data/ext/h3/src/website/yarn.lock +13723 -0
  152. data/h3.gemspec +2 -2
  153. data/lib/h3/bindings/base.rb +14 -4
  154. data/lib/h3/bindings/private.rb +12 -9
  155. data/lib/h3/hierarchy.rb +0 -18
  156. data/lib/h3/indexing.rb +0 -18
  157. data/lib/h3/inspection.rb +3 -59
  158. data/lib/h3/miscellaneous.rb +119 -14
  159. data/lib/h3/regions.rb +3 -0
  160. data/lib/h3/traversal.rb +0 -18
  161. data/lib/h3/unidirectional_edges.rb +5 -60
  162. data/lib/h3/version.rb +1 -1
  163. data/spec/geo_json_spec.rb +8 -0
  164. data/spec/miscellaneous_spec.rb +117 -0
  165. data/spec/{region_spec.rb → regions_spec.rb} +1 -1
  166. data/spec/spec_helper.rb +2 -2
  167. metadata +44 -36
  168. data/.travis.yml +0 -11
  169. data/ext/h3/src/.ycm_extra_conf.py +0 -92
  170. data/ext/h3/src/appveyor.yml +0 -50
  171. data/ext/h3/src/website/src/config.js +0 -46
  172. data/ext/h3/src/website/src/mdRoutes.js +0 -151
  173. data/ext/h3/src/website/src/styles/_variables.scss +0 -16
  174. data/ext/h3/src/website/src/styles/index.scss +0 -3
  175. data/ext/h3/src/website/static/index.html +0 -15
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright 2017-2018 Uber Technologies, Inc.
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(uncompactZero) {
347
+ TEST(uncompact_withZero) {
241
348
  // maxUncompactSize and uncompact both permit 0 indexes
242
349
  // in the input array, and skip them.
243
350
 
@@ -22,6 +22,7 @@
22
22
  #include <stdio.h>
23
23
  #include <stdlib.h>
24
24
  #include <string.h>
25
+
25
26
  #include "algos.h"
26
27
  #include "baseCells.h"
27
28
  #include "constants.h"
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright 2017-2018 Uber Technologies, Inc.
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), const char* message) {
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(_geoDistRads) {
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(_geoDistRads(&p1, &p1) < EPSILON_RAD * 1000,
65
+ t_assert(H3_EXPORT(pointDistRads)(&p1, &p1) < EPSILON_RAD * 1000,
62
66
  "0 distance as expected");
63
- t_assert(fabs(_geoDistRads(&p1, &p2) - H3_EXPORT(degsToRads)(10)) <
64
- EPSILON_RAD * 1000,
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(_geoDistRads(&start, &out) - distance) < EPSILON_RAD,
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(_geoDistRads(&start, &out) < 0.01, "moved back to origin");
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) {
@@ -26,6 +26,7 @@
26
26
 
27
27
  #include <stdio.h>
28
28
  #include <stdlib.h>
29
+
29
30
  #include "geoCoord.h"
30
31
  #include "h3Index.h"
31
32
  #include "test.h"
@@ -20,6 +20,7 @@
20
20
  */
21
21
 
22
22
  #include <math.h>
23
+
23
24
  #include "geoCoord.h"
24
25
  #include "h3api.h"
25
26
  #include "test.h"
@@ -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
+ }