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
@@ -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
+ }
@@ -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"
@@ -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"
@@ -19,6 +19,7 @@
19
19
 
20
20
  #include <stdio.h>
21
21
  #include <stdlib.h>
22
+
22
23
  #include "baseCells.h"
23
24
  #include "h3Index.h"
24
25
  #include "h3api.h"
@@ -22,6 +22,7 @@
22
22
  #include <stdio.h>
23
23
  #include <stdlib.h>
24
24
  #include <string.h>
25
+
25
26
  #include "constants.h"
26
27
  #include "h3Index.h"
27
28
  #include "test.h"
@@ -109,12 +110,41 @@ SUITE(h3Index) {
109
110
  for (int i = 0; i <= 0xf; i++) {
110
111
  H3Index h = H3_INIT;
111
112
  H3_SET_MODE(h, i);
112
- char failureMessage[BUFF_SIZE];
113
- sprintf(failureMessage, "h3IsValid failed on mode %d", i);
114
- t_assert(!H3_EXPORT(h3IsValid)(h) || i == 1, failureMessage);
113
+ if (i == H3_HEXAGON_MODE) {
114
+ t_assert(H3_EXPORT(h3IsValid)(h),
115
+ "h3IsValid succeeds on valid mode");
116
+ } else {
117
+ char failureMessage[BUFF_SIZE];
118
+ sprintf(failureMessage, "h3IsValid failed on mode %d", i);
119
+ t_assert(!H3_EXPORT(h3IsValid)(h), failureMessage);
120
+ }
115
121
  }
116
122
  }
117
123
 
124
+ TEST(h3IsValidReservedBits) {
125
+ for (int i = 0; i < 8; i++) {
126
+ H3Index h = H3_INIT;
127
+ H3_SET_MODE(h, H3_HEXAGON_MODE);
128
+ H3_SET_RESERVED_BITS(h, i);
129
+ if (i == 0) {
130
+ t_assert(H3_EXPORT(h3IsValid)(h),
131
+ "h3IsValid succeeds on valid reserved bits");
132
+ } else {
133
+ char failureMessage[BUFF_SIZE];
134
+ sprintf(failureMessage, "h3IsValid failed on reserved bits %d",
135
+ i);
136
+ t_assert(!H3_EXPORT(h3IsValid)(h), failureMessage);
137
+ }
138
+ }
139
+ }
140
+
141
+ TEST(h3IsValidHighBit) {
142
+ H3Index h = H3_INIT;
143
+ H3_SET_MODE(h, H3_HEXAGON_MODE);
144
+ H3_SET_HIGH_BIT(h, 1);
145
+ t_assert(!H3_EXPORT(h3IsValid)(h), "h3IsValid failed on high bit");
146
+ }
147
+
118
148
  TEST(h3BadDigitInvalid) {
119
149
  H3Index h = H3_INIT;
120
150
  // By default the first index digit is out of range.
@@ -22,6 +22,7 @@
22
22
  #include <stdio.h>
23
23
  #include <stdlib.h>
24
24
  #include <string.h>
25
+
25
26
  #include "h3Index.h"
26
27
  #include "h3api.h"
27
28
  #include "localij.h"
@@ -22,6 +22,7 @@
22
22
  #include <stdio.h>
23
23
  #include <stdlib.h>
24
24
  #include <string.h>
25
+
25
26
  #include "h3Index.h"
26
27
  #include "h3api.h"
27
28
  #include "localij.h"
@@ -0,0 +1,175 @@
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 main H3 core library memory management.
18
+ *
19
+ * usage: `testH3Memory`
20
+ */
21
+
22
+ #include <math.h>
23
+ #include <string.h>
24
+
25
+ #include "geoCoord.h"
26
+ #include "h3Index.h"
27
+ #include "h3api.h"
28
+ #include "test.h"
29
+ #include "utility.h"
30
+
31
+ // Whether to fail all allocations
32
+ static bool failAlloc = false;
33
+ // Actual number of malloc/calloc/realloc calls observed
34
+ static int actualAllocCalls = 0;
35
+ // Actual number of free calls observed
36
+ static int actualFreeCalls = 0;
37
+ // Set to non-zero to begin failing allocations after a certain number of calls
38
+ static int permittedAllocCalls = 0;
39
+
40
+ void resetMemoryCounters(int permitted) {
41
+ failAlloc = false;
42
+ actualAllocCalls = 0;
43
+ actualFreeCalls = 0;
44
+ permittedAllocCalls = permitted;
45
+ }
46
+
47
+ void* test_prefix_malloc(size_t size) {
48
+ actualAllocCalls++;
49
+ if (permittedAllocCalls && actualAllocCalls > permittedAllocCalls) {
50
+ failAlloc = true;
51
+ }
52
+ if (failAlloc) {
53
+ return NULL;
54
+ }
55
+ return malloc(size);
56
+ }
57
+
58
+ void* test_prefix_calloc(size_t num, size_t size) {
59
+ actualAllocCalls++;
60
+ if (permittedAllocCalls && actualAllocCalls > permittedAllocCalls) {
61
+ failAlloc = true;
62
+ }
63
+ if (failAlloc) {
64
+ return NULL;
65
+ }
66
+ return calloc(num, size);
67
+ }
68
+
69
+ void* test_prefix_realloc(void* ptr, size_t size) {
70
+ actualAllocCalls++;
71
+ if (permittedAllocCalls && actualAllocCalls > permittedAllocCalls) {
72
+ failAlloc = true;
73
+ }
74
+ if (failAlloc) {
75
+ return NULL;
76
+ }
77
+ return realloc(ptr, size);
78
+ }
79
+
80
+ void test_prefix_free(void* ptr) {
81
+ actualFreeCalls++;
82
+ return free(ptr);
83
+ }
84
+
85
+ H3Index sunnyvale = 0x89283470c27ffff;
86
+ H3Index pentagon = 0x89080000003ffff;
87
+
88
+ SUITE(h3Memory) {
89
+ TEST(kRing) {
90
+ int k = 2;
91
+ int hexCount = H3_EXPORT(maxKringSize)(k);
92
+ H3Index* kRingOutput = calloc(hexCount, sizeof(H3Index));
93
+
94
+ resetMemoryCounters(0);
95
+ H3_EXPORT(kRing)(sunnyvale, k, kRingOutput);
96
+ t_assert(actualAllocCalls == 0, "kRing did not call alloc");
97
+ t_assert(actualFreeCalls == 0, "kRing did not call free");
98
+
99
+ resetMemoryCounters(0);
100
+ H3_EXPORT(kRing)(pentagon, k, kRingOutput);
101
+ t_assert(actualAllocCalls == 1, "kRing called alloc");
102
+ t_assert(actualFreeCalls == 1, "kRing called free");
103
+
104
+ resetMemoryCounters(0);
105
+ failAlloc = true;
106
+ memset(kRingOutput, 0, hexCount * sizeof(H3Index));
107
+ H3_EXPORT(kRing)(pentagon, k, kRingOutput);
108
+ t_assert(actualAllocCalls == 1, "kRing called alloc");
109
+ t_assert(actualFreeCalls == 0, "kRing did not call free");
110
+
111
+ for (int i = 0; i < hexCount; i++) {
112
+ t_assert(!kRingOutput[i],
113
+ "kRing did not produce output without alloc");
114
+ }
115
+
116
+ free(kRingOutput);
117
+ }
118
+
119
+ TEST(compact) {
120
+ int k = 9;
121
+ int hexCount = H3_EXPORT(maxKringSize)(k);
122
+ int expectedCompactCount = 73;
123
+
124
+ // Generate a set of hexagons to compact
125
+ H3Index* sunnyvaleExpanded = calloc(hexCount, sizeof(H3Index));
126
+ resetMemoryCounters(0);
127
+ H3_EXPORT(kRing)(sunnyvale, k, sunnyvaleExpanded);
128
+ t_assert(actualAllocCalls == 0, "kRing did not call alloc");
129
+ t_assert(actualFreeCalls == 0, "kRing did not call free");
130
+
131
+ H3Index* compressed = calloc(hexCount, sizeof(H3Index));
132
+
133
+ resetMemoryCounters(0);
134
+ failAlloc = true;
135
+ int err = H3_EXPORT(compact)(sunnyvaleExpanded, compressed, hexCount);
136
+ t_assert(err == COMPACT_ALLOC_FAILED, "malloc failed (1)");
137
+ t_assert(actualAllocCalls == 1, "alloc called once");
138
+ t_assert(actualFreeCalls == 0, "free not called");
139
+
140
+ resetMemoryCounters(1);
141
+ err = H3_EXPORT(compact)(sunnyvaleExpanded, compressed, hexCount);
142
+ t_assert(err == COMPACT_ALLOC_FAILED, "malloc failed (2)");
143
+ t_assert(actualAllocCalls == 2, "alloc called twice");
144
+ t_assert(actualFreeCalls == 1, "free called once");
145
+
146
+ resetMemoryCounters(2);
147
+ err = H3_EXPORT(compact)(sunnyvaleExpanded, compressed, hexCount);
148
+ t_assert(err == COMPACT_ALLOC_FAILED, "malloc failed (3)");
149
+ t_assert(actualAllocCalls == 3, "alloc called three times");
150
+ t_assert(actualFreeCalls == 2, "free called twice");
151
+
152
+ resetMemoryCounters(3);
153
+ err = H3_EXPORT(compact)(sunnyvaleExpanded, compressed, hexCount);
154
+ t_assert(err == COMPACT_ALLOC_FAILED, "compact failed (4)");
155
+ t_assert(actualAllocCalls == 4, "alloc called four times");
156
+ t_assert(actualFreeCalls == 3, "free called three times");
157
+
158
+ resetMemoryCounters(4);
159
+ err = H3_EXPORT(compact)(sunnyvaleExpanded, compressed, hexCount);
160
+ t_assert(err == COMPACT_SUCCESS, "compact using successful malloc");
161
+ t_assert(actualAllocCalls == 4, "alloc called four times");
162
+ t_assert(actualFreeCalls == 4, "free called four times");
163
+
164
+ int count = 0;
165
+ for (int i = 0; i < hexCount; i++) {
166
+ if (compressed[i] != 0) {
167
+ count++;
168
+ }
169
+ }
170
+ t_assert(count == expectedCompactCount, "got expected compacted count");
171
+
172
+ free(compressed);
173
+ free(sunnyvaleExpanded);
174
+ }
175
+ }