h3 3.6.2 → 3.7.1

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -2,8 +2,10 @@
2
2
 
3
3
  1. Create a PR "Preparing for release X.Y.Z" against master branch
4
4
  * Alter CHANGELOG.md from `[Unreleased]` to `[X.Y.Z] YYYY-MM-DD`
5
- * Run `make update-version` and give `X.Y.Z` when prompted
5
+ * Run `make update-version` and give `X.Y.Z` when prompted (this updates
6
+ the VERSION file, so don't change it manually)
6
7
  * Check that all merges that need to be in the changelog are present
8
+ * Get reviews and merge the PR
7
9
 
8
10
  2. Create a release "Release X.Y.Z" on Github
9
11
  * Create Tag `vX.Y.Z`
@@ -1 +1 @@
1
- 3.6.2
1
+ 3.7.1
@@ -0,0 +1,21 @@
1
+ # RFC: <Subject>
2
+
3
+ * **Authors**: -
4
+ * **Date**: -
5
+ * **Status**: Draft
6
+
7
+ ## Abstract
8
+
9
+ *Brief overview of the subject and proposal*
10
+
11
+ ## Motivation
12
+
13
+ *Why is this important?*
14
+
15
+ ## Approaches
16
+
17
+ *What are the various options to address this issue?*
18
+
19
+ ## Proposal
20
+
21
+ *What is the recommended approach?*
@@ -0,0 +1,21 @@
1
+ # RFC: Consistent error handling
2
+
3
+ * **Authors**: -
4
+ * **Date**: -
5
+ * **Status**: Draft
6
+
7
+ ## Abstract
8
+
9
+ Error handling in the H3 library is inconsistent across functions, many of which have no explicit mechanism to indicate that an error occured. This RFC proposes updating all functions that allocate blocks of memory or that could receive invalid input to return an integer code indicating success or error.
10
+
11
+ ## Motivation
12
+
13
+ *Why is this important?*
14
+
15
+ ## Approaches
16
+
17
+ *What are the various options to address this issue?*
18
+
19
+ ## Proposal
20
+
21
+ *What is the recommended approach?*
@@ -0,0 +1,276 @@
1
+ # RFC: Names for H3 Concepts, Types, and Functions
2
+
3
+ - **Authors**:
4
+ - AJ Friend
5
+ - Nick Rabinowitz
6
+ - Isaac Brodsky
7
+ - David Ellis
8
+ - **Dates**:
9
+ - Started: 2020-02-02
10
+ - Accepted: 2020-03-26
11
+ - **Status**: Accepted
12
+ - **Discussions**:
13
+ - <https://github.com/uber/h3/pull/308>
14
+
15
+ ## Motivation
16
+
17
+ Concepts like `hexagon`, `cell`, and `index` are currently used ambiguously in the H3 codebase and in documentation.
18
+ This can cause confusion, for example, when a function might only work on strict H3 *hexagons*, but fails when encountering H3 *pentagons*.
19
+
20
+ Reaching a consensus on the precise, technical language used when discussing H3 concepts will clarify future library discussions and improve end-user documentation.
21
+
22
+ We would also like to standardize a function-naming scheme.
23
+
24
+ ## Terminology
25
+
26
+ The following technical terms should be used in the documentation, the H3 codebase, and precise technical discussions of the library.
27
+
28
+ - `H3Index`:
29
+ - an unsigned 64-bit integer representing *any* H3 object (hexagon, pentagon, directed edge ...)
30
+ - often represented as a 15-character (or 16-character) hexadecimal string, like `'8928308280fffff'`
31
+ - the full term "H3 index" should be used to avoid confusion with other common uses of "index";
32
+ when a "traditional" index is needed, prefer using "number", "pos", or another term to avoid confusion
33
+ - **mode**:
34
+ - an integer describing the type of object being represented by an H3 index
35
+ - this integer is encoded in the `H3Index`
36
+ - **cell** or **H3 cell**:
37
+ - a geometric/geographic unit polygon in the H3 grid, corresponding to an `H3Index` of `mode 1` (hexagon or pentagon)
38
+ - for functions that can handle either hexagons or pentagons, the more general term "cell" should be used whenever possible
39
+ - **hexagon**:
40
+ - an H3 **cell** that is a **topological** hexagon
41
+ - below, we explain that functions that *only* work with **hexagons** have an `Unsafe` suffix;
42
+ these functions are paired with ones having a `Safe` suffix, meaning they can handle **pentagons**, but are slower
43
+ - **pentagon**:
44
+ - an H3 **cell** that is a **topological** pentagon
45
+ - **directed edge**:
46
+ - represents a traversal from an origin **cell** to an adjacent destination **cell**
47
+ - corresponds to an `H3Index` of `mode 2`
48
+ - **grid**:
49
+ - the graph with nodes corresponding to H3 cells, and edges given by pairs of adjacent cells
50
+ - for example, `gridDistance` is the minimal number of edges in a graph path connecting two cells
51
+ - **point**:
52
+ - a representation of a geographic point in terms of a latitude/longitude pair
53
+ - **topological**:
54
+ - H3 cells are **topological** pentagons or hexagons, in the sense that they have 5 or 6 neighbors, respectively, in the H3 **grid**
55
+ - the majority of **hexagons** are also **geometric** hexagons (similarly with **pentagons**), in that they have 6 edges and vertices when represented as polygons of lat/lng points
56
+ - a small number of **hexagons** are not **geometric** hexagons (similarly with **pentagons**), in that they have extra vertices and edges due to distortion around icosahedron boundaries
57
+ - for more details, see this [h3-js issue](https://github.com/uber/h3-js/issues/53) or this [Observable post](https://observablehq.com/@fil/h3-oddities)
58
+ - **base cell**:
59
+ - one of the 122 H3 **cells** (110 hexagons and 12 pentagons) of resolution `0`
60
+ - every other cell in H3 is a child of a base cell
61
+ - each base cell has a "base cell number" (0--121), which is encoded into the `H3Index` representation of every H3 cell
62
+ - there is a one-to-one correspondence between the "base cell number" and the `H3Index` representation of resolution `0` cells
63
+ + e.g., base cell 0 has `H3Index` hexadecimal representation `'8001fffffffffff'`
64
+ - **boundary**:
65
+ - all or part of the list of geometric points that enclose an H3 cell
66
+ - may include more than 6 points in the case that a cell is not a geometric hexagon, such as when a hexagon crosses an icosahedron boundary
67
+ - may also be used to describe the boundary between two geometric cells, as in the case of an edge
68
+ - represented in the H3 codebase with the `CellBoundary` struct (previously `GeoBoundary` before v4.0)
69
+ - `H3_NULL`;
70
+ - equivalent to `0` and guaranteed to never be a valid `H3Index` (even after any future H3 **modes** are added)
71
+ - returned by functions to denote an error, or to denote missing data in arrays of `H3Index`
72
+ - analogous to `NaN` in floating point
73
+
74
+
75
+ ### Use of "hex", "hexagon", "cell", "pentagon", etc.
76
+
77
+ We realize that "hex" or "hexagon" will still be used informally to refer to the concept of "cell" (As the development team, we do it ourselves!).
78
+ This should be expected in casual, informal discussions of H3.
79
+ However, when *precision* is required, we advise the use of strict technical terms like "index", "cell", "hexagon", "pentagon", etc.
80
+ In the codebase and in the documentation, strictly correct terminology should *always* be used, as many functions and algorithms distinguish between hexagons and pentagons.
81
+
82
+
83
+ ## `H3_EXPORT` and C name collisions
84
+
85
+ To avoid C name collisions, we should build the bindings (`h3-py`, `h3-java`, `h3-go`, and `h3-node`) with a standard function prefix, using the `H3_EXPORT` C macro.
86
+ The `h3-js` binding would not need this.
87
+
88
+ The proposed prefix is `h3_`.
89
+
90
+ ## Functions
91
+
92
+ ### Conventions for "property getters" and transforms
93
+
94
+ - use `get` prefix for
95
+ + constant data (`getNumCells`, `getRes0Cells`)
96
+ + object properties (`getResolution`, `getBaseCellNumber`)
97
+ - use `to` to denote transforms
98
+ + different representations of the same object
99
+ + when doing a lossy transformation to a new object (`cellToParent`, `pointToCell`)
100
+ - do not use `get` or `to` for *computations*
101
+ + e.g., `polyfill`, `compact`, `cellAreaKm2`
102
+
103
+ There is some ambiguity between property, transform, and computation, so use your best judgement with these guidelines in mind.
104
+
105
+ ### Validity checks
106
+
107
+ - `isValid*` should mean that a *full* validity check is made
108
+ - without `Valid` (like in the case of `isPentagon`), we do not guarantee
109
+ that a full validity check is made; instead, a user should assume only a
110
+ minimal bit mask check is done
111
+ - we could imagine a `isValidPengaton` function, if full verification
112
+ would be convenient
113
+ - similarly, a function like `areNeighborCells` will assume each cell
114
+ has passed the `isValidCell` check; the function will do only minimal
115
+ work to determine if they are neighbors
116
+
117
+
118
+ ### General Function Names
119
+
120
+ | Current name | Proposed name |
121
+ |-------------------------------|-----------------------|
122
+ | *Does Not Exist (DNE)* | `isValidIndex` |
123
+ | `h3IsValid` | `isValidCell` |
124
+ | `h3UnidirectionalEdgeIsValid` | `isValidDirectedEdge` |
125
+ | `h3IsPentagon` | `isPentagon` |
126
+ | `h3IsResClassIII` | `isResClassIII` |
127
+ | `h3IndexesAreNeighbors` | `areNeighborCells` |
128
+ | `h3ToParent` | `cellToParent` |
129
+ | `h3ToCenterChild` | `cellToCenterChild` |
130
+ | `h3ToChildren` | `cellToChildren` |
131
+ | `numHexagons` | `getNumCells` |
132
+ | `getRes0Indexes` | `getRes0Cells` |
133
+ | `getPentagonIndexes` | `getPentagons` |
134
+ | `h3GetBaseCell` | `getBaseCellNumber` |
135
+ | `h3GetResolution` | `getResolution` |
136
+ | *DNE* | `getMode` |
137
+ | `h3GetFaces` | `getIcosahedronFaces` |
138
+ | `geoToH3` | `pointToCell` |
139
+ | `h3ToGeo` | `cellToPoint` |
140
+ | `compact` | `compactCells` |
141
+ | `uncompact` | `uncompactCells` |
142
+ | `polyfill` | `polygonToCells` |
143
+
144
+ **Note**: `getResolution` and `getBaseCellNumber` should work for both cells and edges.
145
+
146
+
147
+ ### H3 Grid Functions
148
+
149
+ Many of these functions will have three forms:
150
+ - `<func_name>`
151
+ - `<func_name>Unsafe`
152
+ - `<func_name>Safe`
153
+
154
+ The `Unsafe` version is fast, but may fail if it encounters a pentagon.
155
+ It should return a failure code in this case.
156
+
157
+ The `Safe` version is slower, but will work in all cases.
158
+
159
+ The version without either suffix is intended to be the one typically
160
+ used.
161
+ This version will first attempt the `Unsafe` version, and if
162
+ it detects failure, will fall back to the `Safe` version.
163
+ Encountering pentagons is rare in most use-cases, so this version
164
+ should usually be equivalent to the fast version, but with a guarantee
165
+ that it will not fail.
166
+
167
+ Initially, we **will not** expose the `Safe` versions to users in the API.
168
+ We may expose them in the future if a need becomes clear.
169
+
170
+
171
+ #### Distance
172
+
173
+ | Current name | Proposed name |
174
+ |--------------|-------------------------|
175
+ | `h3Distance` | `gridDistance` |
176
+ | `h3Line` | `gridPathCells` |
177
+ | *DNE* | `gridPathEdges` |
178
+ | *DNE* | `gridPathDirectedEdges` |
179
+
180
+
181
+ #### Filled-In Disk With Distances
182
+
183
+ | Current name | Proposed name | Calls |
184
+ |---------------------|---------------------------|---------------------------------------|
185
+ | `hexRangeDistances` | `gridDiskDistancesUnsafe` | NONE |
186
+ | `_kRingInternal` | `gridDiskDistancesSafe` | NONE |
187
+ | `kRingDistances` | `gridDiskDistances` | `hexRangeDistances`, `_kRingInternal` |
188
+
189
+
190
+ #### Filled-In Disk Without Distances
191
+
192
+ | Current name | Proposed name | Calls |
193
+ |--------------|-------------------|---------------------|
194
+ | `hexRange` | `gridDiskUnsafe` | `hexRangeDistances` |
195
+ | *DNE* | `gridDiskSafe` | |
196
+ | `kRing` | `gridDisk` | `kRingDistances` |
197
+ | `hexRanges` | `gridDisksUnsafe` | N x `hexRange` |
198
+
199
+ - **Note**: We may remove `hexRanges` from the API, as it is just a very simple wrapper around
200
+ `hexRange`. Inclusion is a discussion separate from this RFC. We'll simply state that
201
+ *if we do* include it, we will rename it `gridDisksUnsafe`.
202
+
203
+
204
+ #### Hollow Ring
205
+
206
+ | Current name | Proposed name | Calls |
207
+ |--------------|------------------|----------------------------------|
208
+ | `hexRing` | `gridRingUnsafe` | NONE |
209
+ | *DNE* | `gridRingSafe` | `gridDiskDistancesSafe` |
210
+ | *DNE* | `gridRing` | `gridRingUnsafe`, `gridRingSafe` |
211
+
212
+ ### H3 Edge Types
213
+
214
+ Instead of `UnidirectionalEdge`, use the term `DirectedEdge`.
215
+
216
+ For a future undirected edge mode, use the term `Edge`.
217
+
218
+ | Current name | Proposed name |
219
+ |-----------------------------------------------|------------------------------|
220
+ | `h3UnidirectionalEdgeIsValid` | `isValidDirectedEdge` |
221
+ | `getH3UnidirectionalEdge` | `cellsToDirectedEdge` |
222
+ | `getH3IndexesFromUnidirectionalEdge` | `directedEdgeToCells` |
223
+ | `getH3UnidirectionalEdgesFromHexagon` | `originToDirectedEdges` |
224
+ | *DNE* | `destinationToDirectedEdges` |
225
+ | `getH3UnidirectionalEdgeBoundary` | `directedEdgeToBoundary` |
226
+ | `getOriginH3IndexFromUnidirectionalEdge` | `getDirectedEdgeOrigin` |
227
+ | `getDestinationH3IndexFromUnidirectionalEdge` | `getDirectedEdgeDestination` |
228
+
229
+
230
+ ### Area/Length Functions
231
+
232
+ | Current name | Proposed name |
233
+ |----------------|-----------------------------|
234
+ | `hexAreaKm2` | `getHexagonAreaAvgKm2` |
235
+ | `hexAreaM2` | `getHexagonAreaAvgM2` |
236
+ | `edgeLengthKm` | `getHexagonEdgeLengthAvgKm` |
237
+ | `edgeLengthM` | `getHexagonEdgeLengthAvgM` |
238
+ | *DNE* | `getPentagonAreaAvg*` |
239
+ | *DNE* | `getPentagonEdgeLengthAvg*` |
240
+ | *DNE* | `cellAreaKm2` |
241
+ | *DNE* | `cellAreaM2` |
242
+
243
+ **Note**: `cellAreaKm2` and `cellAreaM2` would return the actual area of
244
+ the passed-in cell.
245
+
246
+
247
+ ## Polygons
248
+
249
+ **Note**: In addition to the changes listed in this section, we are considering
250
+ removing the `Linked*` data types from the public API. However, that is a larger
251
+ discussion requiring benchmarking, so we will defer that to a
252
+ [separate issue](https://github.com/uber/h3/issues/323) outside of this RFC.
253
+
254
+
255
+ ### Data Structures
256
+
257
+ - rename `GeoBoundary` to `CellBoundary` to indicate it is space-limited to describing the geometry of cells
258
+
259
+ | Current name | Proposed name | Notes |
260
+ |-------------------|-------------------|-----------------------------------|
261
+ | `GeoBoundary` | `CellBoundary` | <= 10 stack-allocated `GeoPoint`s |
262
+ | `GeoCoord` | `GeoPoint` | |
263
+ | `Geofence` | `GeoLoop` | heap-allocated `GeoPoint`s |
264
+ | `GeoPolygon` | `GeoPolygon` | |
265
+ | `GeoMultiPolygon` | `GeoMultiPolygon` | currently not used |
266
+
267
+
268
+ ### Functions
269
+
270
+ | Current name | Proposed name | Notes |
271
+ |-----------------------------------|--------------------------|------------------------|
272
+ | `h3ToGeoBoundary` | `cellToBoundary` | returns `CellBoundary` |
273
+ | *DNE* | `cellToLoop` | returns `GeoLoop` |
274
+ | *DNE* | `loopToBoundary` | |
275
+ | *DNE* | `boundaryToLoop` | |
276
+ | `getH3UnidirectionalEdgeBoundary` | `directedEdgeToBoundary` | returns `CellBoundary` |
@@ -0,0 +1,141 @@
1
+ # RFC: Overrideable allocation functions for H3
2
+
3
+ * **Authors**: Isaac Brodsky (@isaacbrodsky)
4
+ * **Date**: February 7, 2020
5
+ * **Status**: Draft
6
+
7
+ ## Overview
8
+
9
+ This is a proposal for adding a mechanism for users of the H3 library to provide heap allocator instead of the default
10
+ malloc implementation.
11
+
12
+ ## Motivation
13
+
14
+ This will address the following use cases:
15
+
16
+ * H3 is used inside of another application which has its own heap management scheme. For example, using the allocation
17
+ functions provided by Postgres or the Java Virtual Machine.
18
+ * Testing of failure cases of H3, by simulating allocation failures.
19
+
20
+ Most H3 functions accept memory from the caller in order to avoid this problem. This will still be the preferred way
21
+ to handle memory management in H3. Stack allocation is avoided because H3 cannot know whether there is sufficient stack
22
+ memory available. (Note that `_kRingInternal`/`kRingDistances` implicitly uses stack allocation because it implements DFS
23
+ recursively.)
24
+
25
+ A few functions in H3 do heap allocate memory because it is not feasible to do otherwise, or as a convenience. The
26
+ functions that heap allocate are:
27
+
28
+ | Function | Reason
29
+ | --- | ---
30
+ | `kRing`| Convenience wrapper around `kRingDistances`
31
+ | `polyfill` | Convenience (could be passed in, requires internal knowledge)
32
+ | `compact` | Convenience (could be passed in, requires internal knowledge)
33
+ | `h3SetToLinkedGeo` | Requires knowledge of how to initialize the internal struct
34
+ | `destroyLinkedPolygon` | Required for `h3SetToLinkedGeo`
35
+
36
+ ## Prior Art
37
+
38
+ Reading materials to reference:
39
+
40
+ * [C++ `vector`](http://www.cplusplus.com/reference/vector/vector/) (via templates)
41
+ * [SDL](https://discourse.libsdl.org/t/sdl-2-0-7-prerelease/23232) (via `SDL_SetMemoryFunctions`)
42
+ * [PostgreSQL](https://www.postgresql.org/docs/10/xfunc-c.html) (via `palloc`)
43
+ * [SQLite](https://sqlite.org/malloc.html)
44
+
45
+ ## Approaches
46
+
47
+ All approaches assume the user has defined the following functions:
48
+
49
+ ```
50
+ void* my_malloc(size_t size);
51
+ void* my_calloc(size_t count, size_t size);
52
+ void my_free(void* pointer);
53
+
54
+ // TODO: Do we want my_realloc?
55
+ ```
56
+
57
+ ### Global statics
58
+
59
+ In this approach, H3 stores the allocation functions in a set of static variables.
60
+
61
+ ```
62
+ h3SetAllocator(&my_alloc, &my_calloc, &my_free);
63
+
64
+ // call into H3 as before
65
+ polyfill(geoPolygon, res, out);
66
+ ```
67
+
68
+ Pro:
69
+ * Allows the user to replace allocators at run time.
70
+
71
+ Con:
72
+ * Not thread safe, or an additional, complicated dependency is needed to ensure thread safety.
73
+ * Global state.
74
+
75
+ ### Templates
76
+
77
+ This approach is similar to how C++ handles allocator replacement in its standard library, by accepting the allocator
78
+ as a template argument. However, H3 is written in C and must implement templates using macros.
79
+
80
+ ```
81
+ POLYFILL_WITH_ALLLOCATORS(my_polyfill, my_malloc, my_calloc, my_free);
82
+
83
+ // Call the function created by the template
84
+ my_polyfill(geoPolygon, res, out);
85
+ ```
86
+
87
+ Pro:
88
+ * Allows the user to have multiple allocator replacements in use at once.
89
+
90
+ Con:
91
+ * Exposes a complicated build process to the user in the form of macros.
92
+
93
+ ### Allocator argument approach
94
+
95
+ In this approach, every function call includes allocators.
96
+
97
+ ```
98
+ H3MemoryManager allocFunctions = {
99
+ .malloc = &my_malloc,
100
+ .calloc = &my_calloc,
101
+ .free = &my_free
102
+ };
103
+
104
+ polyfill(geoPolygon, res, out, &allocFunctions);
105
+ ```
106
+
107
+ Pro:
108
+ * Allowing replacement on a per-call basis allows for maximum control by the user.
109
+
110
+ Con:
111
+ * The user must always specify allocators, which is unlikely to be needed by most users.
112
+ * Alternately, additional overloads of all H3 functions that heap-allocate are needed.
113
+
114
+ ### `#define` approach
115
+
116
+ In this approach, the allocators are specified at build time.
117
+
118
+ ```
119
+ # In build process:
120
+ cmake -DH3_ALLOC_PREFIX=my_ ...
121
+
122
+ // in source file, functions are used as before.
123
+ ```
124
+
125
+ Alternately, instead of setting a prefix, the build could accept individual options
126
+ for functions, such as `-DH3_MALLOC=my_malloc -DH3_CALLOC=my_calloc`. (Although this
127
+ could allow a user to accidentally override `malloc` but not `free`, which is generally
128
+ very bad.)
129
+
130
+ Pro:
131
+ * Minimal overhead for users and developers when allocator replacement is not needed.
132
+
133
+ Con:
134
+ * Complex allocator replacement (i.e. different allocators for different calls) is possible but requires implementation
135
+ by the user.
136
+
137
+ ## Proposal
138
+
139
+ `#define` based allocator replacement seems like the clearest and lowest overhead to implement, while still supporting
140
+ the full range of use cases. A user could optionally implement a more complicated replacement inside their custom
141
+ allocator functions.