h3 3.6.2 → 3.7.1

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 (161) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +23 -0
  3. data/Gemfile.lock +6 -6
  4. data/README.md +1 -1
  5. data/ext/h3/src/.github/workflows/test-linux.yml +118 -0
  6. data/ext/h3/src/.github/workflows/test-macos.yml +42 -0
  7. data/ext/h3/src/.github/workflows/test-website.yml +32 -0
  8. data/ext/h3/src/.github/workflows/test-windows.yml +44 -0
  9. data/ext/h3/src/.gitignore +5 -0
  10. data/ext/h3/src/.travis.yml +16 -46
  11. data/ext/h3/src/CHANGELOG.md +43 -0
  12. data/ext/h3/src/CMakeLists.txt +133 -33
  13. data/ext/h3/src/CONTRIBUTING.md +1 -1
  14. data/ext/h3/src/README.md +60 -10
  15. data/ext/h3/src/RELEASE.md +3 -1
  16. data/ext/h3/src/VERSION +1 -1
  17. data/ext/h3/src/dev-docs/RFCs/rfc-template.md +21 -0
  18. data/ext/h3/src/dev-docs/RFCs/v4.0.0/error-handling-rfc.md +21 -0
  19. data/ext/h3/src/dev-docs/RFCs/v4.0.0/names_for_concepts_types_functions.md +276 -0
  20. data/ext/h3/src/dev-docs/RFCs/v4.0.0/overrideable-allocators-rfc.md +141 -0
  21. data/ext/h3/src/dev-docs/RFCs/v4.0.0/polyfill-modes-rfc.md +21 -0
  22. data/ext/h3/src/dev-docs/RFCs/v4.0.0/vertex-mode-rfc.md +50 -0
  23. data/ext/h3/src/dev-docs/build_windows.md +6 -1
  24. data/ext/h3/src/dev-docs/creating_bindings.md +3 -3
  25. data/ext/h3/src/dev-docs/custom_alloc.md +27 -0
  26. data/ext/h3/src/docs/{overview/mainpage.md → README.md} +2 -3
  27. data/ext/h3/src/docs/api/misc.md +76 -0
  28. data/ext/h3/src/docs/community/applications.md +1 -0
  29. data/ext/h3/src/docs/community/bindings.md +7 -1
  30. data/ext/h3/src/docs/community/tutorials.md +8 -3
  31. data/ext/h3/src/docs/core-library/coordsystems.md +5 -4
  32. data/ext/h3/src/docs/core-library/filters.md +8 -9
  33. data/ext/h3/src/docs/core-library/geoToH3desc.md +2 -3
  34. data/ext/h3/src/docs/core-library/h3ToGeoBoundaryDesc.md +4 -5
  35. data/ext/h3/src/docs/core-library/h3ToGeoDesc.md +3 -4
  36. data/ext/h3/src/docs/core-library/h3indexing.md +26 -17
  37. data/ext/h3/src/docs/core-library/overview.md +2 -3
  38. data/ext/h3/src/docs/core-library/restable.md +1 -2
  39. data/ext/h3/src/docs/core-library/usage.md +1 -2
  40. data/ext/h3/src/docs/table-of-contents.json +47 -0
  41. data/ext/h3/src/docs/{overview/usecases.md → usecases.md} +6 -11
  42. data/ext/h3/src/scripts/binding_functions.sh +1 -1
  43. data/ext/h3/src/scripts/coverage.sh.in +1 -1
  44. data/ext/h3/src/scripts/update_version.sh +2 -2
  45. data/ext/h3/src/src/apps/applib/include/args.h +1 -0
  46. data/ext/h3/src/src/apps/applib/include/test.h +1 -0
  47. data/ext/h3/src/src/apps/applib/include/utility.h +7 -1
  48. data/ext/h3/src/src/apps/applib/lib/args.c +2 -0
  49. data/ext/h3/src/src/apps/applib/lib/kml.c +2 -0
  50. data/ext/h3/src/src/apps/applib/lib/test.c +1 -0
  51. data/ext/h3/src/src/apps/applib/lib/utility.c +133 -2
  52. data/ext/h3/src/src/apps/benchmarks/benchmarkH3Api.c +1 -1
  53. data/ext/h3/src/{website/html.config.js → src/apps/benchmarks/benchmarkH3UniEdge.c} +15 -12
  54. data/ext/h3/src/src/apps/filters/h3ToComponents.c +1 -0
  55. data/ext/h3/src/src/apps/filters/h3ToGeo.c +1 -0
  56. data/ext/h3/src/src/apps/filters/h3ToGeoBoundary.c +1 -0
  57. data/ext/h3/src/src/apps/filters/h3ToLocalIj.c +1 -0
  58. data/ext/h3/src/src/apps/filters/hexRange.c +1 -0
  59. data/ext/h3/src/src/apps/filters/kRing.c +1 -0
  60. data/ext/h3/src/src/apps/filters/localIjToH3.c +1 -0
  61. data/ext/h3/src/src/apps/miscapps/generateFaceCenterPoint.c +1 -0
  62. data/ext/h3/src/src/apps/miscapps/generateNumHexagons.c +1 -0
  63. data/ext/h3/src/src/apps/miscapps/generatePentagonDirectionFaces.c +67 -0
  64. data/ext/h3/src/src/apps/miscapps/h3ToGeoBoundaryHier.c +1 -0
  65. data/ext/h3/src/src/apps/miscapps/h3ToGeoHier.c +1 -0
  66. data/ext/h3/src/src/apps/miscapps/h3ToHier.c +1 -0
  67. data/ext/h3/src/src/apps/testapps/mkRandGeo.c +1 -0
  68. data/ext/h3/src/src/apps/testapps/mkRandGeoBoundary.c +1 -0
  69. data/ext/h3/src/src/apps/testapps/testBBox.c +1 -0
  70. data/ext/h3/src/src/apps/testapps/testBaseCells.c +15 -1
  71. data/ext/h3/src/src/apps/testapps/testCompact.c +75 -0
  72. data/ext/h3/src/src/apps/testapps/testCoordIj.c +1 -0
  73. data/ext/h3/src/src/apps/testapps/testGeoCoord.c +40 -13
  74. data/ext/h3/src/src/apps/testapps/testGeoToH3.c +1 -0
  75. data/ext/h3/src/src/apps/testapps/testH3Api.c +1 -0
  76. data/ext/h3/src/src/apps/testapps/testH3CellArea.c +47 -0
  77. data/ext/h3/src/src/apps/testapps/testH3CellAreaExhaustive.c +180 -0
  78. data/ext/h3/src/src/apps/testapps/testH3Distance.c +1 -0
  79. data/ext/h3/src/src/apps/testapps/testH3DistanceExhaustive.c +1 -0
  80. data/ext/h3/src/src/apps/testapps/testH3GetFaces.c +1 -0
  81. data/ext/h3/src/src/apps/testapps/testH3Index.c +33 -3
  82. data/ext/h3/src/src/apps/testapps/testH3Line.c +1 -0
  83. data/ext/h3/src/src/apps/testapps/testH3LineExhaustive.c +1 -0
  84. data/ext/h3/src/src/apps/testapps/testH3Memory.c +175 -0
  85. data/ext/h3/src/src/apps/testapps/testH3NeighborRotations.c +1 -0
  86. data/ext/h3/src/src/apps/testapps/testH3SetToLinkedGeo.c +1 -0
  87. data/ext/h3/src/src/apps/testapps/testH3SetToVertexGraph.c +1 -0
  88. data/ext/h3/src/src/apps/testapps/testH3ToCenterChild.c +1 -0
  89. data/ext/h3/src/src/apps/testapps/testH3ToChildren.c +1 -0
  90. data/ext/h3/src/src/apps/testapps/testH3ToGeo.c +1 -0
  91. data/ext/h3/src/src/apps/testapps/testH3ToGeoBoundary.c +1 -0
  92. data/ext/h3/src/src/apps/testapps/testH3ToLocalIj.c +9 -5
  93. data/ext/h3/src/src/apps/testapps/testH3ToLocalIjExhaustive.c +1 -0
  94. data/ext/h3/src/src/apps/testapps/testH3ToParent.c +1 -0
  95. data/ext/h3/src/src/apps/testapps/testH3UniEdge.c +45 -16
  96. data/ext/h3/src/src/apps/testapps/testH3UniEdgeExhaustive.c +111 -0
  97. data/ext/h3/src/src/apps/testapps/testHexRanges.c +1 -0
  98. data/ext/h3/src/src/apps/testapps/testHexRing.c +1 -0
  99. data/ext/h3/src/src/apps/testapps/testKRing.c +1 -0
  100. data/ext/h3/src/src/apps/testapps/testLinkedGeo.c +1 -0
  101. data/ext/h3/src/src/apps/testapps/testMaxH3ToChildrenSize.c +1 -0
  102. data/ext/h3/src/src/apps/testapps/testPentagonIndexes.c +1 -0
  103. data/ext/h3/src/src/apps/testapps/testPolyfill.c +72 -9
  104. data/ext/h3/src/src/apps/testapps/testPolyfillReported.c +157 -0
  105. data/ext/h3/src/src/apps/testapps/testPolygon.c +1 -0
  106. data/ext/h3/src/src/apps/testapps/testVec2d.c +1 -0
  107. data/ext/h3/src/src/apps/testapps/testVec3d.c +1 -0
  108. data/ext/h3/src/src/apps/testapps/testVertex.c +66 -0
  109. data/ext/h3/src/src/apps/testapps/testVertexGraph.c +1 -0
  110. data/ext/h3/src/src/h3lib/include/algos.h +8 -0
  111. data/ext/h3/src/src/h3lib/include/alloc.h +40 -0
  112. data/ext/h3/src/src/h3lib/include/baseCells.h +4 -0
  113. data/ext/h3/src/src/h3lib/include/bbox.h +4 -1
  114. data/ext/h3/src/src/h3lib/include/faceijk.h +3 -2
  115. data/ext/h3/src/src/h3lib/include/geoCoord.h +2 -3
  116. data/ext/h3/src/src/h3lib/include/h3Index.h +37 -4
  117. data/ext/h3/src/src/h3lib/include/h3api.h.in +65 -17
  118. data/ext/h3/src/src/h3lib/include/linkedGeo.h +1 -0
  119. data/ext/h3/src/src/h3lib/include/polygon.h +1 -0
  120. data/ext/h3/src/src/h3lib/include/polygonAlgos.h +1 -0
  121. data/ext/h3/src/src/h3lib/include/vertex.h +44 -0
  122. data/ext/h3/src/src/h3lib/include/vertexGraph.h +1 -0
  123. data/ext/h3/src/src/h3lib/lib/algos.c +300 -75
  124. data/ext/h3/src/src/h3lib/lib/baseCells.c +26 -4
  125. data/ext/h3/src/src/h3lib/lib/bbox.c +56 -31
  126. data/ext/h3/src/src/h3lib/lib/coordijk.c +2 -0
  127. data/ext/h3/src/src/h3lib/lib/faceijk.c +32 -21
  128. data/ext/h3/src/src/h3lib/lib/geoCoord.c +162 -44
  129. data/ext/h3/src/src/h3lib/lib/h3Index.c +81 -43
  130. data/ext/h3/src/src/h3lib/lib/h3UniEdge.c +42 -57
  131. data/ext/h3/src/src/h3lib/lib/linkedGeo.c +20 -15
  132. data/ext/h3/src/src/h3lib/lib/localij.c +1 -1
  133. data/ext/h3/src/src/h3lib/lib/polygon.c +2 -0
  134. data/ext/h3/src/src/h3lib/lib/vec2d.c +1 -0
  135. data/ext/h3/src/src/h3lib/lib/vec3d.c +1 -0
  136. data/ext/h3/src/src/h3lib/lib/vertex.c +134 -0
  137. data/ext/h3/src/src/h3lib/lib/vertexGraph.c +8 -5
  138. data/ext/h3/src/website/.eslintignore +2 -0
  139. data/ext/h3/src/website/.gitignore +57 -0
  140. data/ext/h3/src/website/.nvmrc +1 -0
  141. data/ext/h3/src/website/README.md +8 -6
  142. data/ext/h3/src/website/gatsby-config.js +83 -0
  143. data/ext/h3/src/website/package.json +20 -12
  144. data/ext/h3/src/website/scripts/build-to-gh-pages.sh +7 -5
  145. data/ext/h3/src/website/src/.gitkeep +0 -0
  146. data/ext/h3/src/website/templates/documentation.jsx +129 -0
  147. data/ext/h3/src/website/yarn.lock +13723 -0
  148. data/lib/h3/bindings/private.rb +3 -0
  149. data/lib/h3/miscellaneous.rb +123 -0
  150. data/lib/h3/version.rb +1 -1
  151. data/spec/miscellaneous_spec.rb +117 -0
  152. data/spec/regions_spec.rb +1 -1
  153. metadata +35 -14
  154. data/ext/h3/src/.ycm_extra_conf.py +0 -92
  155. data/ext/h3/src/appveyor.yml +0 -50
  156. data/ext/h3/src/src/apps/testapps/testPolyfill_GH136.c +0 -58
  157. data/ext/h3/src/website/src/config.js +0 -46
  158. data/ext/h3/src/website/src/mdRoutes.js +0 -151
  159. data/ext/h3/src/website/src/styles/_variables.scss +0 -16
  160. data/ext/h3/src/website/src/styles/index.scss +0 -3
  161. data/ext/h3/src/website/static/index.html +0 -15
@@ -29,6 +29,7 @@
29
29
  #include <inttypes.h>
30
30
  #include <stdio.h>
31
31
  #include <stdlib.h>
32
+
32
33
  #include "algos.h"
33
34
  #include "baseCells.h"
34
35
  #include "h3Index.h"
@@ -15,6 +15,7 @@
15
15
  */
16
16
 
17
17
  #include <stdio.h>
18
+
18
19
  #include "algos.h"
19
20
  #include "test.h"
20
21
  #include "utility.h"
@@ -15,6 +15,7 @@
15
15
  */
16
16
 
17
17
  #include <stdio.h>
18
+
18
19
  #include "algos.h"
19
20
  #include "test.h"
20
21
  #include "utility.h"
@@ -16,6 +16,7 @@
16
16
 
17
17
  #include <inttypes.h>
18
18
  #include <stdlib.h>
19
+
19
20
  #include "h3Index.h"
20
21
  #include "test.h"
21
22
 
@@ -15,6 +15,7 @@
15
15
  */
16
16
 
17
17
  #include <stdlib.h>
18
+
18
19
  #include "h3Index.h"
19
20
  #include "test.h"
20
21
 
@@ -26,6 +26,7 @@
26
26
 
27
27
  #include <stdio.h>
28
28
  #include <stdlib.h>
29
+
29
30
  #include "constants.h"
30
31
  #include "geoCoord.h"
31
32
  #include "h3Index.h"
@@ -27,6 +27,7 @@
27
27
  #include <math.h>
28
28
  #include <stdio.h>
29
29
  #include <stdlib.h>
30
+
30
31
  #include "baseCells.h"
31
32
  #include "geoCoord.h"
32
33
  #include "h3Index.h"
@@ -23,6 +23,7 @@
23
23
  #include <stdio.h>
24
24
  #include <stdlib.h>
25
25
  #include <string.h>
26
+
26
27
  #include "algos.h"
27
28
  #include "baseCells.h"
28
29
  #include "constants.h"
@@ -89,16 +90,19 @@ SUITE(h3ToLocalIj) {
89
90
  const int numCoords = 7;
90
91
  const CoordIJ coords[] = {{0, 0}, {1, 0}, {2, 0}, {3, 0},
91
92
  {4, 0}, {-4, 0}, {0, 4}};
92
- const H3Index expected[] = {0x81283ffffffffff, 0x81293ffffffffff,
93
- 0x8150bffffffffff, 0x8151bffffffffff,
94
- H3_INVALID_INDEX, H3_INVALID_INDEX,
95
- H3_INVALID_INDEX};
93
+ const H3Index expected[] = {0x81283ffffffffff,
94
+ 0x81293ffffffffff,
95
+ 0x8150bffffffffff,
96
+ 0x8151bffffffffff,
97
+ H3_NULL,
98
+ H3_NULL,
99
+ H3_NULL};
96
100
 
97
101
  for (int i = 0; i < numCoords; i++) {
98
102
  H3Index result;
99
103
  const int err = H3_EXPORT(experimentalLocalIjToH3)(
100
104
  expected[0], &coords[i], &result);
101
- if (expected[i] == H3_INVALID_INDEX) {
105
+ if (expected[i] == H3_NULL) {
102
106
  t_assert(err != 0, "coordinates out of range");
103
107
  } else {
104
108
  t_assert(err == 0, "coordinates in range");
@@ -24,6 +24,7 @@
24
24
  #include <stdio.h>
25
25
  #include <stdlib.h>
26
26
  #include <string.h>
27
+
27
28
  #include "algos.h"
28
29
  #include "baseCells.h"
29
30
  #include "constants.h"
@@ -15,6 +15,7 @@
15
15
  */
16
16
 
17
17
  #include <stdlib.h>
18
+
18
19
  #include "h3Index.h"
19
20
  #include "test.h"
20
21
 
@@ -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.
@@ -20,10 +20,12 @@
20
20
  */
21
21
 
22
22
  #include <stdlib.h>
23
+
23
24
  #include "constants.h"
24
25
  #include "geoCoord.h"
25
26
  #include "h3Index.h"
26
27
  #include "test.h"
28
+ #include "utility.h"
27
29
 
28
30
  // Fixtures
29
31
  static GeoCoord sfGeo = {0.659966917655, -2.1364398519396};
@@ -123,13 +125,31 @@ SUITE(h3UniEdge) {
123
125
  }
124
126
 
125
127
  TEST(getH3UnidirectionalEdgeFromPentagon) {
128
+ H3Index pentagons[NUM_PENTAGONS] = {0};
129
+ H3Index ring[7] = {0};
126
130
  H3Index pentagon;
127
- setH3Index(&pentagon, 0, 4, 0);
128
- H3Index adjacent;
129
- setH3Index(&adjacent, 0, 8, 0);
130
-
131
- H3Index edge = H3_EXPORT(getH3UnidirectionalEdge)(pentagon, adjacent);
132
- t_assert(edge != 0, "Produces a valid edge");
131
+ H3Index edge;
132
+
133
+ for (int res = 0; res < MAX_H3_RES; res++) {
134
+ H3_EXPORT(getPentagonIndexes)(res, pentagons);
135
+ for (int p = 0; p < NUM_PENTAGONS; p++) {
136
+ pentagon = pentagons[p];
137
+ H3_EXPORT(kRing)(pentagon, 1, ring);
138
+
139
+ for (int i = 0; i < 7; i++) {
140
+ H3Index neighbor = ring[i];
141
+ if (neighbor == pentagon || neighbor == H3_NULL) continue;
142
+ edge =
143
+ H3_EXPORT(getH3UnidirectionalEdge)(pentagon, neighbor);
144
+ t_assert(H3_EXPORT(h3UnidirectionalEdgeIsValid)(edge),
145
+ "pentagon-to-neighbor is a valid edge");
146
+ edge =
147
+ H3_EXPORT(getH3UnidirectionalEdge)(neighbor, pentagon);
148
+ t_assert(H3_EXPORT(h3UnidirectionalEdgeIsValid)(edge),
149
+ "neighbor-to-pentagon is a valid edge");
150
+ }
151
+ }
152
+ }
133
153
  }
134
154
 
135
155
  TEST(h3UnidirectionalEdgeIsValid) {
@@ -166,6 +186,11 @@ SUITE(h3UniEdge) {
166
186
  H3_SET_RESERVED_BITS(badPentagonalEdge, 1);
167
187
  t_assert(H3_EXPORT(h3UnidirectionalEdgeIsValid)(badPentagonalEdge) == 0,
168
188
  "missing pentagonal edge does not validate");
189
+
190
+ H3Index highBitEdge = edge;
191
+ H3_SET_HIGH_BIT(highBitEdge, 1);
192
+ t_assert(H3_EXPORT(h3UnidirectionalEdgeIsValid)(highBitEdge) == 0,
193
+ "high bit set edge does not validate");
169
194
  }
170
195
 
171
196
  TEST(getH3UnidirectionalEdgesFromHexagon) {
@@ -222,9 +247,7 @@ SUITE(h3UniEdge) {
222
247
  const int expectedVertices[][2] = {{3, 4}, {1, 2}, {2, 3},
223
248
  {5, 0}, {4, 5}, {0, 1}};
224
249
 
225
- // TODO: The current implementation relies on lat/lon comparison and
226
- // fails on resolutions finer than 12
227
- for (int res = 0; res < 13; res++) {
250
+ for (int res = 0; res < MAX_H3_RES; res++) {
228
251
  sf = H3_EXPORT(geoToH3)(&sfGeo, res);
229
252
  H3_EXPORT(h3ToGeoBoundary)(sf, &boundary);
230
253
  H3_EXPORT(getH3UnidirectionalEdgesFromHexagon)(sf, edges);
@@ -253,9 +276,7 @@ SUITE(h3UniEdge) {
253
276
  const int expectedVertices[][3] = {{-1, -1, -1}, {2, 3, 4}, {4, 5, 6},
254
277
  {8, 9, 0}, {6, 7, 8}, {0, 1, 2}};
255
278
 
256
- // TODO: The current implementation relies on lat/lon comparison and
257
- // fails on resolutions finer than 12
258
- for (int res = 1; res < 13; res += 2) {
279
+ for (int res = 1; res < MAX_H3_RES; res += 2) {
259
280
  setH3Index(&pentagon, res, 24, 0);
260
281
  H3_EXPORT(h3ToGeoBoundary)(pentagon, &boundary);
261
282
  H3_EXPORT(getH3UnidirectionalEdgesFromHexagon)(pentagon, edges);
@@ -293,9 +314,7 @@ SUITE(h3UniEdge) {
293
314
  const int expectedVertices[][3] = {{-1, -1}, {1, 2}, {2, 3},
294
315
  {4, 0}, {3, 4}, {0, 1}};
295
316
 
296
- // TODO: The current implementation relies on lat/lon comparison and
297
- // fails on resolutions finer than 12
298
- for (int res = 0; res < 12; res += 2) {
317
+ for (int res = 0; res < MAX_H3_RES; res += 2) {
299
318
  setH3Index(&pentagon, res, 24, 0);
300
319
  H3_EXPORT(h3ToGeoBoundary)(pentagon, &boundary);
301
320
  H3_EXPORT(getH3UnidirectionalEdgesFromHexagon)(pentagon, edges);
@@ -323,4 +342,14 @@ SUITE(h3UniEdge) {
323
342
  "Only one edge was deleted for the pentagon");
324
343
  }
325
344
  }
345
+
346
+ TEST(exactEdgeLength_invalid) {
347
+ // Test that invalid inputs do not cause crashes.
348
+ t_assert(H3_EXPORT(exactEdgeLengthRads)(0) == 0,
349
+ "Invalid edge has zero length");
350
+ GeoCoord zero = {0, 0};
351
+ H3Index h3 = H3_EXPORT(geoToH3)(&zero, 0);
352
+ t_assert(H3_EXPORT(exactEdgeLengthRads)(h3) == 0,
353
+ "Non-edge (cell) has zero edge length");
354
+ }
326
355
  }
@@ -0,0 +1,111 @@
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
+ /** @file
17
+ * @brief tests H3 unidirectional edge functions using tests over a large number
18
+ * of indexes.
19
+ *
20
+ * usage: `testH3UniEdgeExhaustive`
21
+ */
22
+
23
+ #include <stdio.h>
24
+ #include <stdlib.h>
25
+ #include <string.h>
26
+
27
+ #include "baseCells.h"
28
+ #include "constants.h"
29
+ #include "geoCoord.h"
30
+ #include "h3Index.h"
31
+ #include "test.h"
32
+ #include "utility.h"
33
+
34
+ static void h3UniEdge_correctness_assertions(H3Index h3) {
35
+ H3Index edges[6] = {H3_NULL};
36
+ int isPentagon = H3_EXPORT(h3IsPentagon)(h3);
37
+ H3_EXPORT(getH3UnidirectionalEdgesFromHexagon)(h3, edges);
38
+ H3Index destination;
39
+
40
+ for (int i = 0; i < 6; i++) {
41
+ if (isPentagon && i == 0) {
42
+ t_assert(edges[i] == H3_NULL, "last pentagon edge is empty");
43
+ continue;
44
+ }
45
+ t_assert(H3_EXPORT(h3UnidirectionalEdgeIsValid)(edges[i]) == 1,
46
+ "edge is an edge");
47
+ t_assert(
48
+ H3_EXPORT(getOriginH3IndexFromUnidirectionalEdge)(edges[i]) == h3,
49
+ "origin matches input origin");
50
+
51
+ destination =
52
+ H3_EXPORT(getDestinationH3IndexFromUnidirectionalEdge)(edges[i]);
53
+ t_assert(H3_EXPORT(h3IndexesAreNeighbors)(h3, destination),
54
+ "destination is a neighbor");
55
+ }
56
+ }
57
+
58
+ static void h3UniEdge_boundary_assertions(H3Index h3) {
59
+ H3Index edges[6] = {H3_NULL};
60
+ H3_EXPORT(getH3UnidirectionalEdgesFromHexagon)(h3, edges);
61
+ H3Index destination;
62
+ H3Index revEdge;
63
+ GeoBoundary edgeBoundary;
64
+ GeoBoundary revEdgeBoundary;
65
+
66
+ for (int i = 0; i < 6; i++) {
67
+ if (edges[i] == H3_NULL) continue;
68
+ H3_EXPORT(getH3UnidirectionalEdgeBoundary)(edges[i], &edgeBoundary);
69
+ destination =
70
+ H3_EXPORT(getDestinationH3IndexFromUnidirectionalEdge)(edges[i]);
71
+ revEdge = H3_EXPORT(getH3UnidirectionalEdge)(destination, h3);
72
+ H3_EXPORT(getH3UnidirectionalEdgeBoundary)(revEdge, &revEdgeBoundary);
73
+
74
+ t_assert(edgeBoundary.numVerts == revEdgeBoundary.numVerts,
75
+ "numVerts is equal for edge and reverse");
76
+
77
+ for (int j = 0; j < edgeBoundary.numVerts; j++) {
78
+ int almostEqual = geoAlmostEqualThreshold(
79
+ &edgeBoundary.verts[j],
80
+ &revEdgeBoundary.verts[revEdgeBoundary.numVerts - 1 - j],
81
+ 0.000001);
82
+ t_assert(almostEqual, "Got expected vertex");
83
+ }
84
+ }
85
+ }
86
+
87
+ SUITE(h3UniEdge) {
88
+ TEST(h3UniEdge_correctness) {
89
+ iterateAllIndexesAtRes(0, h3UniEdge_correctness_assertions);
90
+ iterateAllIndexesAtRes(1, h3UniEdge_correctness_assertions);
91
+ iterateAllIndexesAtRes(2, h3UniEdge_correctness_assertions);
92
+ iterateAllIndexesAtRes(3, h3UniEdge_correctness_assertions);
93
+ iterateAllIndexesAtRes(4, h3UniEdge_correctness_assertions);
94
+ }
95
+
96
+ TEST(h3UniEdge_boundary) {
97
+ iterateAllIndexesAtRes(0, h3UniEdge_boundary_assertions);
98
+ iterateAllIndexesAtRes(1, h3UniEdge_boundary_assertions);
99
+ iterateAllIndexesAtRes(2, h3UniEdge_boundary_assertions);
100
+ iterateAllIndexesAtRes(3, h3UniEdge_boundary_assertions);
101
+ iterateAllIndexesAtRes(4, h3UniEdge_boundary_assertions);
102
+ // Res 5: normal base cell
103
+ iterateBaseCellIndexesAtRes(5, h3UniEdge_boundary_assertions, 0);
104
+ // Res 5: pentagon base cell
105
+ iterateBaseCellIndexesAtRes(5, h3UniEdge_boundary_assertions, 14);
106
+ // Res 5: polar pentagon base cell
107
+ iterateBaseCellIndexesAtRes(5, h3UniEdge_boundary_assertions, 117);
108
+ // Res 6: Test one pentagon just to check for new edge cases
109
+ iterateBaseCellIndexesAtRes(6, h3UniEdge_boundary_assertions, 14);
110
+ }
111
+ }
@@ -15,6 +15,7 @@
15
15
  */
16
16
 
17
17
  #include <stdlib.h>
18
+
18
19
  #include "algos.h"
19
20
  #include "test.h"
20
21
 
@@ -15,6 +15,7 @@
15
15
  */
16
16
 
17
17
  #include <stdlib.h>
18
+
18
19
  #include "algos.h"
19
20
  #include "constants.h"
20
21
  #include "h3Index.h"
@@ -20,6 +20,7 @@
20
20
  */
21
21
 
22
22
  #include <stdlib.h>
23
+
23
24
  #include "algos.h"
24
25
  #include "baseCells.h"
25
26
  #include "h3Index.h"
@@ -16,6 +16,7 @@
16
16
 
17
17
  #include <stdio.h>
18
18
  #include <stdlib.h>
19
+
19
20
  #include "geoCoord.h"
20
21
  #include "h3api.h"
21
22
  #include "linkedGeo.h"
@@ -15,6 +15,7 @@
15
15
  */
16
16
 
17
17
  #include <stdlib.h>
18
+
18
19
  #include "h3Index.h"
19
20
  #include "test.h"
20
21
 
@@ -15,6 +15,7 @@
15
15
  */
16
16
 
17
17
  #include <stdlib.h>
18
+
18
19
  #include "h3api.h"
19
20
  #include "test.h"
20
21
 
@@ -15,11 +15,13 @@
15
15
  */
16
16
 
17
17
  #include <stdlib.h>
18
+
18
19
  #include "algos.h"
19
20
  #include "constants.h"
20
21
  #include "geoCoord.h"
21
22
  #include "h3Index.h"
22
23
  #include "test.h"
24
+ #include "utility.h"
23
25
 
24
26
  // Fixtures
25
27
  static GeoCoord sfVerts[] = {
@@ -41,14 +43,69 @@ static GeoCoord emptyVerts[] = {{0.659966917655, -2.1364398519394},
41
43
  static Geofence emptyGeofence = {.numVerts = 3, .verts = emptyVerts};
42
44
  static GeoPolygon emptyGeoPolygon;
43
45
 
44
- static int countActualHexagons(H3Index* hexagons, int numHexagons) {
45
- int actualNumHexagons = 0;
46
- for (int i = 0; i < numHexagons; i++) {
47
- if (hexagons[i] != 0) {
48
- actualNumHexagons++;
46
+ /**
47
+ * Return true if the cell crosses the meridian.
48
+ */
49
+ static bool isTransmeridianCell(H3Index h) {
50
+ GeoBoundary bndry;
51
+ H3_EXPORT(h3ToGeoBoundary)(h, &bndry);
52
+
53
+ double minLon = M_PI, maxLon = -M_PI;
54
+ for (int i = 0; i < bndry.numVerts; i++) {
55
+ if (bndry.verts[i].lon < minLon) minLon = bndry.verts[i].lon;
56
+ if (bndry.verts[i].lon > maxLon) maxLon = bndry.verts[i].lon;
57
+ }
58
+
59
+ return maxLon - minLon > M_PI - (M_PI / 4);
60
+ }
61
+
62
+ static void fillIndex_assertions(H3Index h) {
63
+ if (isTransmeridianCell(h)) {
64
+ // TODO: these do not work correctly
65
+ return;
66
+ }
67
+
68
+ int currentRes = H3_EXPORT(h3GetResolution)(h);
69
+ // TODO: Not testing more than one depth because the assertions fail.
70
+ for (int nextRes = currentRes; nextRes <= currentRes + 1; nextRes++) {
71
+ GeoBoundary bndry;
72
+ H3_EXPORT(h3ToGeoBoundary)(h, &bndry);
73
+ GeoPolygon polygon = {
74
+ .geofence = {.numVerts = bndry.numVerts, .verts = bndry.verts},
75
+ .numHoles = 0,
76
+ .holes = 0};
77
+
78
+ int polyfillSize = H3_EXPORT(maxPolyfillSize)(&polygon, nextRes);
79
+ H3Index* polyfillOut = calloc(polyfillSize, sizeof(H3Index));
80
+ H3_EXPORT(polyfill)(&polygon, nextRes, polyfillOut);
81
+
82
+ int polyfillCount = countActualHexagons(polyfillOut, polyfillSize);
83
+
84
+ int childrenSize = H3_EXPORT(maxH3ToChildrenSize)(h, nextRes);
85
+ H3Index* children = calloc(childrenSize, sizeof(H3Index));
86
+ H3_EXPORT(h3ToChildren)(h, nextRes, children);
87
+
88
+ int h3ToChildrenCount = countActualHexagons(children, childrenSize);
89
+
90
+ t_assert(polyfillCount == h3ToChildrenCount,
91
+ "Polyfill count matches h3ToChildren count");
92
+
93
+ for (int i = 0; i < childrenSize; i++) {
94
+ bool found = false;
95
+ if (children[i] == H3_NULL) continue;
96
+ for (int j = 0; j < polyfillSize; j++) {
97
+ if (polyfillOut[j] == children[i]) {
98
+ found = true;
99
+ break;
100
+ }
101
+ }
102
+ t_assert(found,
103
+ "All indexes match between polyfill and h3ToChildren");
49
104
  }
105
+
106
+ free(polyfillOut);
107
+ free(children);
50
108
  }
51
- return actualNumHexagons;
52
109
  }
53
110
 
54
111
  SUITE(polyfill) {
@@ -64,13 +121,13 @@ SUITE(polyfill) {
64
121
 
65
122
  TEST(maxPolyfillSize) {
66
123
  int numHexagons = H3_EXPORT(maxPolyfillSize)(&sfGeoPolygon, 9);
67
- t_assert(numHexagons == 7057, "got expected max polyfill size");
124
+ t_assert(numHexagons == 5613, "got expected max polyfill size");
68
125
 
69
126
  numHexagons = H3_EXPORT(maxPolyfillSize)(&holeGeoPolygon, 9);
70
- t_assert(numHexagons == 7057, "got expected max polyfill size (hole)");
127
+ t_assert(numHexagons == 5613, "got expected max polyfill size (hole)");
71
128
 
72
129
  numHexagons = H3_EXPORT(maxPolyfillSize)(&emptyGeoPolygon, 9);
73
- t_assert(numHexagons == 1, "got expected max polyfill size (empty)");
130
+ t_assert(numHexagons == 15, "got expected max polyfill size (empty)");
74
131
  }
75
132
 
76
133
  TEST(polyfill) {
@@ -300,4 +357,10 @@ SUITE(polyfill) {
300
357
  t_assert(numPentagons == 1, "one pentagon found");
301
358
  free(hexagons);
302
359
  }
360
+
361
+ TEST(fillIndex) {
362
+ iterateAllIndexesAtRes(0, fillIndex_assertions);
363
+ iterateAllIndexesAtRes(1, fillIndex_assertions);
364
+ iterateAllIndexesAtRes(2, fillIndex_assertions);
365
+ }
303
366
  }