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
@@ -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
+ }
@@ -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"
@@ -86,17 +87,22 @@ SUITE(h3ToLocalIj) {
86
87
  }
87
88
 
88
89
  TEST(ijOutOfRange) {
89
- const int numCoords = 5;
90
- const CoordIJ coords[] = {{0, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0}};
91
- const H3Index expected[] = {0x81283ffffffffff, 0x81293ffffffffff,
92
- 0x8150bffffffffff, 0x8151bffffffffff,
93
- H3_INVALID_INDEX};
90
+ const int numCoords = 7;
91
+ const CoordIJ coords[] = {{0, 0}, {1, 0}, {2, 0}, {3, 0},
92
+ {4, 0}, {-4, 0}, {0, 4}};
93
+ const H3Index expected[] = {0x81283ffffffffff,
94
+ 0x81293ffffffffff,
95
+ 0x8150bffffffffff,
96
+ 0x8151bffffffffff,
97
+ H3_NULL,
98
+ H3_NULL,
99
+ H3_NULL};
94
100
 
95
101
  for (int i = 0; i < numCoords; i++) {
96
102
  H3Index result;
97
103
  const int err = H3_EXPORT(experimentalLocalIjToH3)(
98
104
  expected[0], &coords[i], &result);
99
- if (expected[i] == H3_INVALID_INDEX) {
105
+ if (expected[i] == H3_NULL) {
100
106
  t_assert(err != 0, "coordinates out of range");
101
107
  } else {
102
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
  }