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
51extern "C" {
52#endif
53
54/** @brief the H3Index fits within a 64-bit unsigned integer */
55typedef 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*/
72typedef 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*/
80typedef 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 */
88typedef struct {
89 int numVerts;
90 GeoCoord *verts;
91} Geofence;
92
93/** @struct GeoPolygon
94 * @brief Simplified core of GeoJSON Polygon coordinates definition
95 */
96typedef 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 */
105typedef 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 */
113typedef struct LinkedGeoCoord LinkedGeoCoord;
114struct 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 */
122typedef struct LinkedGeoLoop LinkedGeoLoop;
123struct 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 */
132typedef struct LinkedGeoPolygon LinkedGeoPolygon;
133struct 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 */
144typedef 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 */
155H3Index 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 */
163void 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 */
171void 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 */
179int H3_EXPORT(maxKringSize)(int k);
180
181/** @brief hexagons neighbors in all directions, assuming no pentagons */
182int 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 */
188int 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 */
192int H3_EXPORT(hexRanges)(H3Index *h3Set, int length, int k, H3Index *out);
193
194/** @brief hexagon neighbors in all directions */
195void 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 */
204void 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 */
213int 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 */
221int H3_EXPORT(maxPolyfillSize)(const GeoPolygon *geoPolygon, int res);
222
223/** @brief hexagons within the given geofence */
224void 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 */
232void H3_EXPORT(h3SetToLinkedGeo)(const H3Index *h3Set, const int numHexes,
233 LinkedGeoPolygon *out);
234
235/** @brief Free all memory created for a LinkedGeoPolygon */
236void H3_EXPORT(destroyLinkedPolygon)(LinkedGeoPolygon *polygon);
237/** @} */
238
239/** @defgroup degsToRads degsToRads
240 * Functions for degsToRads
241 * @{
242 */
243/** @brief converts degrees to radians */
244double H3_EXPORT(degsToRads)(double degrees);
245/** @} */
246
247/** @defgroup radsToDegs radsToDegs
248 * Functions for radsToDegs
249 * @{
250 */
251/** @brief converts radians to degrees */
252double H3_EXPORT(radsToDegs)(double radians);
253/** @} */
254
255/** @defgroup hexArea hexArea
256 * Functions for hexArea
257 * @{
258 */
259/** @brief hexagon area in square kilometers */
260double H3_EXPORT(hexAreaKm2)(int res);
261
262/** @brief hexagon area in square meters */
263double H3_EXPORT(hexAreaM2)(int res);
264/** @} */
265
266/** @defgroup edgeLength edgeLength
267 * Functions for edgeLength
268 * @{
269 */
270/** @brief hexagon edge length in kilometers */
271double H3_EXPORT(edgeLengthKm)(int res);
272
273/** @brief hexagon edge length in meters */
274double 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 */
282int64_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 */
290int H3_EXPORT(res0IndexCount)();
291
292/** @brief provides all base cells */
293void 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 */
301int 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 */
309int 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 */
317H3Index 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 */
325void 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 */
333int 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 */
342H3Index 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 */
352int H3_EXPORT(maxH3ToChildrenSize)(H3Index h, int childRes);
353
354/** @brief provides the children (or grandchildren, etc) of the given hexagon */
355void 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 */
363int 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 */
373int H3_EXPORT(maxUncompactSize)(const H3Index *compactedSet, const int numHexes,
374 const int res);
375
376/** @brief uncompacts the compacted hexagon set */
377int 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) */
386int 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 */
394int 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 */
402int 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 */
411H3Index 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 */
419int 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 */
429H3Index 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 */
439H3Index 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 */
449void 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 */
460void 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 */
469void 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 */
477int 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 */
485int H3_EXPORT(h3LineSize)(H3Index start, H3Index end);
486
487/** @brief Line of h3 indexes connecting two indexes */
488int 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 */
496int 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 */
505int 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