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 h3Index.h
17 * @brief H3Index functions.
18 */
19
20#ifndef H3INDEX_H
21#define H3INDEX_H
22
23#include "faceijk.h"
24#include "h3api.h"
25
26// define's of constants and macros for bitwise manipulation of H3Index's.
27
28/** The number of bits in an H3 index. */
29#define H3_NUM_BITS 64
30
31/** The bit offset of the max resolution digit in an H3 index. */
32#define H3_MAX_OFFSET 63
33
34/** The bit offset of the mode in an H3 index. */
35#define H3_MODE_OFFSET 59
36
37/** The bit offset of the base cell in an H3 index. */
38#define H3_BC_OFFSET 45
39
40/** The bit offset of the resolution in an H3 index. */
41#define H3_RES_OFFSET 52
42
43/** The bit offset of the reserved bits in an H3 index. */
44#define H3_RESERVED_OFFSET 56
45
46/** The number of bits in a single H3 resolution digit. */
47#define H3_PER_DIGIT_OFFSET 3
48
49/** 1's in the 4 mode bits, 0's everywhere else. */
50#define H3_MODE_MASK ((uint64_t)(15) << H3_MODE_OFFSET)
51
52/** 0's in the 4 mode bits, 1's everywhere else. */
53#define H3_MODE_MASK_NEGATIVE (~H3_MODE_MASK)
54
55/** 1's in the 7 base cell bits, 0's everywhere else. */
56#define H3_BC_MASK ((uint64_t)(127) << H3_BC_OFFSET)
57
58/** 0's in the 7 base cell bits, 1's everywhere else. */
59#define H3_BC_MASK_NEGATIVE (~H3_BC_MASK)
60
61/** 1's in the 4 resolution bits, 0's everywhere else. */
62#define H3_RES_MASK (UINT64_C(15) << H3_RES_OFFSET)
63
64/** 0's in the 4 resolution bits, 1's everywhere else. */
65#define H3_RES_MASK_NEGATIVE (~H3_RES_MASK)
66
67/** 1's in the 3 reserved bits, 0's everywhere else. */
68#define H3_RESERVED_MASK ((uint64_t)(7) << H3_RESERVED_OFFSET)
69
70/** 0's in the 3 reserved bits, 1's everywhere else. */
71#define H3_RESERVED_MASK_NEGATIVE (~H3_RESERVED_MASK)
72
73/** 1's in the 3 bits of res 15 digit bits, 0's everywhere else. */
74#define H3_DIGIT_MASK ((uint64_t)(7))
75
76/** 0's in the 7 base cell bits, 1's everywhere else. */
77#define H3_DIGIT_MASK_NEGATIVE (~H3_DIGIT_MASK_NEGATIVE)
78
79/** H3 index with mode 0, res 0, base cell 0, and 7 for all index digits. */
80#define H3_INIT (UINT64_C(35184372088831))
81
82/**
83 * Gets the integer mode of h3.
84 */
85#define H3_GET_MODE(h3) ((int)((((h3)&H3_MODE_MASK) >> H3_MODE_OFFSET)))
86
87/**
88 * Sets the integer mode of h3 to v.
89 */
90#define H3_SET_MODE(h3, v) \
91 (h3) = (((h3)&H3_MODE_MASK_NEGATIVE) | (((uint64_t)(v)) << H3_MODE_OFFSET))
92
93/**
94 * Gets the integer base cell of h3.
95 */
96#define H3_GET_BASE_CELL(h3) ((int)((((h3)&H3_BC_MASK) >> H3_BC_OFFSET)))
97
98/**
99 * Sets the integer base cell of h3 to bc.
100 */
101#define H3_SET_BASE_CELL(h3, bc) \
102 (h3) = (((h3)&H3_BC_MASK_NEGATIVE) | (((uint64_t)(bc)) << H3_BC_OFFSET))
103
104/**
105 * Gets the integer resolution of h3.
106 */
107#define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
108
109/**
110 * Sets the integer resolution of h3.
111 */
112#define H3_SET_RESOLUTION(h3, res) \
113 (h3) = (((h3)&H3_RES_MASK_NEGATIVE) | (((uint64_t)(res)) << H3_RES_OFFSET))
114
115/**
116 * Gets the resolution res integer digit (0-7) of h3.
117 */
118#define H3_GET_INDEX_DIGIT(h3, res) \
119 ((Direction)((((h3) >> ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)) & \
120 H3_DIGIT_MASK)))
121
122/**
123 * Sets a value in the reserved space. Setting to non-zero may produce invalid
124 * indexes.
125 */
126#define H3_SET_RESERVED_BITS(h3, v) \
127 (h3) = (((h3)&H3_RESERVED_MASK_NEGATIVE) | \
128 (((uint64_t)(v)) << H3_RESERVED_OFFSET))
129
130/**
131 * Gets a value in the reserved space. Should always be zero for valid indexes.
132 */
133#define H3_GET_RESERVED_BITS(h3) \
134 ((int)((((h3)&H3_RESERVED_MASK) >> H3_RESERVED_OFFSET)))
135
136/**
137 * Sets the resolution res digit of h3 to the integer digit (0-7)
138 */
139#define H3_SET_INDEX_DIGIT(h3, res, digit) \
140 (h3) = (((h3) & ~((H3_DIGIT_MASK \
141 << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))) | \
142 (((uint64_t)(digit)) \
143 << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))
144
145/**
146 * Invalid index used to indicate an error from geoToH3 and related functions.
147 */
148#define H3_INVALID_INDEX 0
149
150void setH3Index(H3Index* h, int res, int baseCell, Direction initDigit);
151int isResClassIII(int res);
152
153// Internal functions
154
155int _h3ToFaceIjkWithInitializedFijk(H3Index h, FaceIJK* fijk);
156H3Index _faceIjkToH3(const FaceIJK* fijk, int res);
157Direction _h3LeadingNonZeroDigit(H3Index h);
158H3Index _h3RotatePent60ccw(H3Index h);
159H3Index _h3RotatePent60cw(H3Index h);
160H3Index _h3Rotate60ccw(H3Index h);
161H3Index _h3Rotate60cw(H3Index h);
162
163#endif
164