1 | /* |
2 | * Copyright 2016-2018 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 h3api.h |
17 | * @brief Primary H3 core library entry points. |
18 | * |
19 | * This file defines the public API of the H3 library. Incompatible changes to |
20 | * these functions require the library's major version be increased. |
21 | */ |
22 | |
23 | #ifndef H3API_H |
24 | #define H3API_H |
25 | |
26 | /* |
27 | * Preprocessor code to support renaming (prefixing) the public API. |
28 | * All public functions should be wrapped in H3_EXPORT so they can be |
29 | * renamed. |
30 | */ |
31 | #ifdef H3_PREFIX |
32 | #define XTJOIN(a, b) a##b |
33 | #define TJOIN(a, b) XTJOIN(a, b) |
34 | |
35 | /* export joins the user provided prefix with our exported function name */ |
36 | #define H3_EXPORT(name) TJOIN(H3_PREFIX, name) |
37 | #else |
38 | #define H3_EXPORT(name) name |
39 | #endif |
40 | |
41 | /* For uint64_t */ |
42 | #include <stdint.h> |
43 | /* For size_t */ |
44 | #include <stdlib.h> |
45 | |
46 | /* |
47 | * H3 is compiled as C, not C++ code. `extern "C"` is needed for C++ code |
48 | * to be able to use the library. |
49 | */ |
50 | #ifdef __cplusplus |
51 | extern "C" { |
52 | #endif |
53 | |
54 | /** @brief the H3Index fits within a 64-bit unsigned integer */ |
55 | typedef uint64_t H3Index; |
56 | |
57 | /* library version numbers generated from VERSION file */ |
58 | // clang-format off |
59 | #define H3_VERSION_MAJOR |
60 | #define H3_VERSION_MINOR |
61 | #define H3_VERSION_PATCH |
62 | // clang-format on |
63 | |
64 | /** Maximum number of cell boundary vertices; worst case is pentagon: |
65 | * 5 original verts + 5 edge crossings |
66 | */ |
67 | #define MAX_CELL_BNDRY_VERTS 10 |
68 | |
69 | /** @struct GeoCoord |
70 | @brief latitude/longitude in radians |
71 | */ |
72 | typedef struct { |
73 | double lat; ///< latitude in radians |
74 | double lon; ///< longitude in radians |
75 | } GeoCoord; |
76 | |
77 | /** @struct GeoBoundary |
78 | @brief cell boundary in latitude/longitude |
79 | */ |
80 | typedef struct { |
81 | int numVerts; ///< number of vertices |
82 | GeoCoord verts[MAX_CELL_BNDRY_VERTS]; ///< vertices in ccw order |
83 | } GeoBoundary; |
84 | |
85 | /** @struct Geofence |
86 | * @brief similar to GeoBoundary, but requires more alloc work |
87 | */ |
88 | typedef struct { |
89 | int numVerts; |
90 | GeoCoord *verts; |
91 | } Geofence; |
92 | |
93 | /** @struct GeoPolygon |
94 | * @brief Simplified core of GeoJSON Polygon coordinates definition |
95 | */ |
96 | typedef struct { |
97 | Geofence geofence; ///< exterior boundary of the polygon |
98 | int numHoles; ///< number of elements in the array pointed to by holes |
99 | Geofence *holes; ///< interior boundaries (holes) in the polygon |
100 | } GeoPolygon; |
101 | |
102 | /** @struct GeoMultiPolygon |
103 | * @brief Simplified core of GeoJSON MultiPolygon coordinates definition |
104 | */ |
105 | typedef struct { |
106 | int numPolygons; |
107 | GeoPolygon *polygons; |
108 | } GeoMultiPolygon; |
109 | |
110 | /** @struct LinkedGeoCoord |
111 | * @brief A coordinate node in a linked geo structure, part of a linked list |
112 | */ |
113 | typedef struct LinkedGeoCoord LinkedGeoCoord; |
114 | struct LinkedGeoCoord { |
115 | GeoCoord vertex; |
116 | LinkedGeoCoord *next; |
117 | }; |
118 | |
119 | /** @struct LinkedGeoLoop |
120 | * @brief A loop node in a linked geo structure, part of a linked list |
121 | */ |
122 | typedef struct LinkedGeoLoop LinkedGeoLoop; |
123 | struct LinkedGeoLoop { |
124 | LinkedGeoCoord *first; |
125 | LinkedGeoCoord *last; |
126 | LinkedGeoLoop *next; |
127 | }; |
128 | |
129 | /** @struct LinkedGeoPolygon |
130 | * @brief A polygon node in a linked geo structure, part of a linked list. |
131 | */ |
132 | typedef struct LinkedGeoPolygon LinkedGeoPolygon; |
133 | struct LinkedGeoPolygon { |
134 | LinkedGeoLoop *first; |
135 | LinkedGeoLoop *last; |
136 | LinkedGeoPolygon *next; |
137 | }; |
138 | |
139 | /** @struct CoordIJ |
140 | * @brief IJ hexagon coordinates |
141 | * |
142 | * Each axis is spaced 120 degrees apart. |
143 | */ |
144 | typedef struct { |
145 | int i; ///< i component |
146 | int j; ///< j component |
147 | } CoordIJ; |
148 | |
149 | /** @defgroup geoToH3 geoToH3 |
150 | * Functions for geoToH3 |
151 | * @{ |
152 | */ |
153 | /** @brief find the H3 index of the resolution res cell containing the lat/lon g |
154 | */ |
155 | H3Index H3_EXPORT(geoToH3)(const GeoCoord *g, int res); |
156 | /** @} */ |
157 | |
158 | /** @defgroup h3ToGeo h3ToGeo |
159 | * Functions for h3ToGeo |
160 | * @{ |
161 | */ |
162 | /** @brief find the lat/lon center point g of the cell h3 */ |
163 | void H3_EXPORT(h3ToGeo)(H3Index h3, GeoCoord *g); |
164 | /** @} */ |
165 | |
166 | /** @defgroup h3ToGeoBoundary h3ToGeoBoundary |
167 | * Functions for h3ToGeoBoundary |
168 | * @{ |
169 | */ |
170 | /** @brief give the cell boundary in lat/lon coordinates for the cell h3 */ |
171 | void H3_EXPORT(h3ToGeoBoundary)(H3Index h3, GeoBoundary *gp); |
172 | /** @} */ |
173 | |
174 | /** @defgroup kRing kRing |
175 | * Functions for kRing |
176 | * @{ |
177 | */ |
178 | /** @brief maximum number of hexagons in k-ring */ |
179 | int H3_EXPORT(maxKringSize)(int k); |
180 | |
181 | /** @brief hexagons neighbors in all directions, assuming no pentagons */ |
182 | int H3_EXPORT(hexRange)(H3Index origin, int k, H3Index *out); |
183 | /** @} */ |
184 | |
185 | /** @brief hexagons neighbors in all directions, assuming no pentagons, |
186 | * reporting |
187 | * distance from origin */ |
188 | int H3_EXPORT(hexRangeDistances)(H3Index origin, int k, H3Index *out, |
189 | int *distances); |
190 | |
191 | /** @brief collection of hex rings sorted by ring for all given hexagons */ |
192 | int H3_EXPORT(hexRanges)(H3Index *h3Set, int length, int k, H3Index *out); |
193 | |
194 | /** @brief hexagon neighbors in all directions */ |
195 | void H3_EXPORT(kRing)(H3Index origin, int k, H3Index *out); |
196 | /** @} */ |
197 | |
198 | /** @defgroup kRingDistances kRingDistances |
199 | * Functions for kRingDistances |
200 | * @{ |
201 | */ |
202 | /** @brief hexagon neighbors in all directions, reporting distance from origin |
203 | */ |
204 | void H3_EXPORT(kRingDistances)(H3Index origin, int k, H3Index *out, |
205 | int *distances); |
206 | /** @} */ |
207 | |
208 | /** @defgroup hexRing hexRing |
209 | * Functions for hexRing |
210 | * @{ |
211 | */ |
212 | /** @brief hollow hexagon ring at some origin */ |
213 | int H3_EXPORT(hexRing)(H3Index origin, int k, H3Index *out); |
214 | /** @} */ |
215 | |
216 | /** @defgroup polyfill polyfill |
217 | * Functions for polyfill |
218 | * @{ |
219 | */ |
220 | /** @brief maximum number of hexagons in the geofence */ |
221 | int H3_EXPORT(maxPolyfillSize)(const GeoPolygon *geoPolygon, int res); |
222 | |
223 | /** @brief hexagons within the given geofence */ |
224 | void H3_EXPORT(polyfill)(const GeoPolygon *geoPolygon, int res, H3Index *out); |
225 | /** @} */ |
226 | |
227 | /** @defgroup h3SetToMultiPolygon h3SetToMultiPolygon |
228 | * Functions for h3SetToMultiPolygon (currently a binding-only concept) |
229 | * @{ |
230 | */ |
231 | /** @brief Create a LinkedGeoPolygon from a set of contiguous hexagons */ |
232 | void H3_EXPORT(h3SetToLinkedGeo)(const H3Index *h3Set, const int numHexes, |
233 | LinkedGeoPolygon *out); |
234 | |
235 | /** @brief Free all memory created for a LinkedGeoPolygon */ |
236 | void H3_EXPORT(destroyLinkedPolygon)(LinkedGeoPolygon *polygon); |
237 | /** @} */ |
238 | |
239 | /** @defgroup degsToRads degsToRads |
240 | * Functions for degsToRads |
241 | * @{ |
242 | */ |
243 | /** @brief converts degrees to radians */ |
244 | double H3_EXPORT(degsToRads)(double degrees); |
245 | /** @} */ |
246 | |
247 | /** @defgroup radsToDegs radsToDegs |
248 | * Functions for radsToDegs |
249 | * @{ |
250 | */ |
251 | /** @brief converts radians to degrees */ |
252 | double H3_EXPORT(radsToDegs)(double radians); |
253 | /** @} */ |
254 | |
255 | /** @defgroup hexArea hexArea |
256 | * Functions for hexArea |
257 | * @{ |
258 | */ |
259 | /** @brief hexagon area in square kilometers */ |
260 | double H3_EXPORT(hexAreaKm2)(int res); |
261 | |
262 | /** @brief hexagon area in square meters */ |
263 | double H3_EXPORT(hexAreaM2)(int res); |
264 | /** @} */ |
265 | |
266 | /** @defgroup edgeLength edgeLength |
267 | * Functions for edgeLength |
268 | * @{ |
269 | */ |
270 | /** @brief hexagon edge length in kilometers */ |
271 | double H3_EXPORT(edgeLengthKm)(int res); |
272 | |
273 | /** @brief hexagon edge length in meters */ |
274 | double H3_EXPORT(edgeLengthM)(int res); |
275 | /** @} */ |
276 | |
277 | /** @defgroup numHexagons numHexagons |
278 | * Functions for numHexagons |
279 | * @{ |
280 | */ |
281 | /** @brief number of hexagons for a given resolution */ |
282 | int64_t H3_EXPORT(numHexagons)(int res); |
283 | /** @} */ |
284 | |
285 | /** @defgroup getRes0Indexes getRes0Indexes |
286 | * Functions for getRes0Indexes |
287 | * @{ |
288 | */ |
289 | /** @brief returns the number of resolution 0 indexes */ |
290 | int H3_EXPORT(res0IndexCount)(); |
291 | |
292 | /** @brief provides all base cells */ |
293 | void H3_EXPORT(getRes0Indexes)(H3Index *out); |
294 | /** @} */ |
295 | |
296 | /** @defgroup h3GetResolution h3GetResolution |
297 | * Functions for h3GetResolution |
298 | * @{ |
299 | */ |
300 | /** @brief returns the resolution of the provided hexagon */ |
301 | int H3_EXPORT(h3GetResolution)(H3Index h); |
302 | /** @} */ |
303 | |
304 | /** @defgroup h3GetBaseCell h3GetBaseCell |
305 | * Functions for h3GetBaseCell |
306 | * @{ |
307 | */ |
308 | /** @brief returns the base cell of the provided hexagon */ |
309 | int H3_EXPORT(h3GetBaseCell)(H3Index h); |
310 | /** @} */ |
311 | |
312 | /** @defgroup stringToH3 stringToH3 |
313 | * Functions for stringToH3 |
314 | * @{ |
315 | */ |
316 | /** @brief converts the canonical string format to H3Index format */ |
317 | H3Index H3_EXPORT(stringToH3)(const char *str); |
318 | /** @} */ |
319 | |
320 | /** @defgroup h3ToString h3ToString |
321 | * Functions for h3ToString |
322 | * @{ |
323 | */ |
324 | /** @brief converts an H3Index to a canonical string */ |
325 | void H3_EXPORT(h3ToString)(H3Index h, char *str, size_t sz); |
326 | /** @} */ |
327 | |
328 | /** @defgroup h3IsValid h3IsValid |
329 | * Functions for h3IsValid |
330 | * @{ |
331 | */ |
332 | /** @brief confirms if an H3Index is valid */ |
333 | int H3_EXPORT(h3IsValid)(H3Index h); |
334 | /** @} */ |
335 | |
336 | /** @defgroup h3ToParent h3ToParent |
337 | * Functions for h3ToParent |
338 | * @{ |
339 | */ |
340 | /** @brief returns the parent (or grandparent, etc) hexagon of the given hexagon |
341 | */ |
342 | H3Index H3_EXPORT(h3ToParent)(H3Index h, int parentRes); |
343 | /** @} */ |
344 | |
345 | /** @defgroup h3ToChildren h3ToChildren |
346 | * Functions for h3ToChildren |
347 | * @{ |
348 | */ |
349 | /** @brief determines the maximum number of children (or grandchildren, etc) |
350 | * that |
351 | * could be returned for the given hexagon */ |
352 | int H3_EXPORT(maxH3ToChildrenSize)(H3Index h, int childRes); |
353 | |
354 | /** @brief provides the children (or grandchildren, etc) of the given hexagon */ |
355 | void H3_EXPORT(h3ToChildren)(H3Index h, int childRes, H3Index *children); |
356 | /** @} */ |
357 | |
358 | /** @defgroup compact compact |
359 | * Functions for compact |
360 | * @{ |
361 | */ |
362 | /** @brief compacts the given set of hexagons as best as possible */ |
363 | int H3_EXPORT(compact)(const H3Index *h3Set, H3Index *compactedSet, |
364 | const int numHexes); |
365 | /** @} */ |
366 | |
367 | /** @defgroup uncompact uncompact |
368 | * Functions for uncompact |
369 | * @{ |
370 | */ |
371 | /** @brief determines the maximum number of hexagons that could be uncompacted |
372 | * from the compacted set */ |
373 | int H3_EXPORT(maxUncompactSize)(const H3Index *compactedSet, const int numHexes, |
374 | const int res); |
375 | |
376 | /** @brief uncompacts the compacted hexagon set */ |
377 | int H3_EXPORT(uncompact)(const H3Index *compactedSet, const int numHexes, |
378 | H3Index *h3Set, const int maxHexes, const int res); |
379 | /** @} */ |
380 | |
381 | /** @defgroup h3IsResClassIII h3IsResClassIII |
382 | * Functions for h3IsResClassIII |
383 | * @{ |
384 | */ |
385 | /** @brief determines if a hexagon is Class III (or Class II) */ |
386 | int H3_EXPORT(h3IsResClassIII)(H3Index h); |
387 | /** @} */ |
388 | |
389 | /** @defgroup h3IsPentagon h3IsPentagon |
390 | * Functions for h3IsPentagon |
391 | * @{ |
392 | */ |
393 | /** @brief determines if a hexagon is actually a pentagon */ |
394 | int H3_EXPORT(h3IsPentagon)(H3Index h); |
395 | /** @} */ |
396 | |
397 | /** @defgroup h3IndexesAreNeighbors h3IndexesAreNeighbors |
398 | * Functions for h3IndexesAreNeighbors |
399 | * @{ |
400 | */ |
401 | /** @brief returns whether or not the provided hexagons border */ |
402 | int H3_EXPORT(h3IndexesAreNeighbors)(H3Index origin, H3Index destination); |
403 | /** @} */ |
404 | |
405 | /** @defgroup getH3UnidirectionalEdge getH3UnidirectionalEdge |
406 | * Functions for getH3UnidirectionalEdge |
407 | * @{ |
408 | */ |
409 | /** @brief returns the unidirectional edge H3Index for the specified origin and |
410 | * destination */ |
411 | H3Index H3_EXPORT(getH3UnidirectionalEdge)(H3Index origin, H3Index destination); |
412 | /** @} */ |
413 | |
414 | /** @defgroup h3UnidirectionalEdgeIsValid h3UnidirectionalEdgeIsValid |
415 | * Functions for h3UnidirectionalEdgeIsValid |
416 | * @{ |
417 | */ |
418 | /** @brief returns whether the H3Index is a valid unidirectional edge */ |
419 | int H3_EXPORT(h3UnidirectionalEdgeIsValid)(H3Index edge); |
420 | /** @} */ |
421 | |
422 | /** @defgroup getOriginH3IndexFromUnidirectionalEdge \ |
423 | * getOriginH3IndexFromUnidirectionalEdge |
424 | * Functions for getOriginH3IndexFromUnidirectionalEdge |
425 | * @{ |
426 | */ |
427 | /** @brief Returns the origin hexagon H3Index from the unidirectional edge |
428 | * H3Index */ |
429 | H3Index H3_EXPORT(getOriginH3IndexFromUnidirectionalEdge)(H3Index edge); |
430 | /** @} */ |
431 | |
432 | /** @defgroup getDestinationH3IndexFromUnidirectionalEdge \ |
433 | * getDestinationH3IndexFromUnidirectionalEdge |
434 | * Functions for getDestinationH3IndexFromUnidirectionalEdge |
435 | * @{ |
436 | */ |
437 | /** @brief Returns the destination hexagon H3Index from the unidirectional edge |
438 | * H3Index */ |
439 | H3Index H3_EXPORT(getDestinationH3IndexFromUnidirectionalEdge)(H3Index edge); |
440 | /** @} */ |
441 | |
442 | /** @defgroup getH3IndexesFromUnidirectionalEdge \ |
443 | * getH3IndexesFromUnidirectionalEdge |
444 | * Functions for getH3IndexesFromUnidirectionalEdge |
445 | * @{ |
446 | */ |
447 | /** @brief Returns the origin and destination hexagons from the unidirectional |
448 | * edge H3Index */ |
449 | void H3_EXPORT(getH3IndexesFromUnidirectionalEdge)(H3Index edge, |
450 | H3Index *originDestination); |
451 | /** @} */ |
452 | |
453 | /** @defgroup getH3UnidirectionalEdgesFromHexagon \ |
454 | * getH3UnidirectionalEdgesFromHexagon |
455 | * Functions for getH3UnidirectionalEdgesFromHexagon |
456 | * @{ |
457 | */ |
458 | /** @brief Returns the 6 (or 5 for pentagons) edges associated with the H3Index |
459 | */ |
460 | void H3_EXPORT(getH3UnidirectionalEdgesFromHexagon)(H3Index origin, |
461 | H3Index *edges); |
462 | /** @} */ |
463 | |
464 | /** @defgroup getH3UnidirectionalEdgeBoundary getH3UnidirectionalEdgeBoundary |
465 | * Functions for getH3UnidirectionalEdgeBoundary |
466 | * @{ |
467 | */ |
468 | /** @brief Returns the GeoBoundary containing the coordinates of the edge */ |
469 | void H3_EXPORT(getH3UnidirectionalEdgeBoundary)(H3Index edge, GeoBoundary *gb); |
470 | /** @} */ |
471 | |
472 | /** @defgroup h3Distance h3Distance |
473 | * Functions for h3Distance |
474 | * @{ |
475 | */ |
476 | /** @brief Returns grid distance between two indexes */ |
477 | int H3_EXPORT(h3Distance)(H3Index origin, H3Index h3); |
478 | /** @} */ |
479 | |
480 | /** @defgroup h3Line h3Line |
481 | * Functions for h3Line |
482 | * @{ |
483 | */ |
484 | /** @brief Number of indexes in a line connecting two indexes */ |
485 | int H3_EXPORT(h3LineSize)(H3Index start, H3Index end); |
486 | |
487 | /** @brief Line of h3 indexes connecting two indexes */ |
488 | int H3_EXPORT(h3Line)(H3Index start, H3Index end, H3Index *out); |
489 | /** @} */ |
490 | |
491 | /** @defgroup experimentalH3ToLocalIj experimentalH3ToLocalIj |
492 | * Functions for experimentalH3ToLocalIj |
493 | * @{ |
494 | */ |
495 | /** @brief Returns two dimensional coordinates for the given index */ |
496 | int H3_EXPORT(experimentalH3ToLocalIj)(H3Index origin, H3Index h3, |
497 | CoordIJ *out); |
498 | /** @} */ |
499 | |
500 | /** @defgroup experimentalLocalIjToH3 experimentalLocalIjToH3 |
501 | * Functions for experimentalLocalIjToH3 |
502 | * @{ |
503 | */ |
504 | /** @brief Returns index for the given two dimensional coordinates */ |
505 | int H3_EXPORT(experimentalLocalIjToH3)(H3Index origin, const CoordIJ *ij, |
506 | H3Index *out); |
507 | /** @} */ |
508 | |
509 | #ifdef __cplusplus |
510 | } // extern "C" |
511 | #endif |
512 | |
513 | #endif |
514 | |