0
# Grid Navigation
1
2
Functions for navigating the hexagonal grid system, including distance calculations, finding neighboring cells, and pathfinding between cells. H3's hexagonal grid enables efficient spatial queries and navigation operations.
3
4
## Capabilities
5
6
### Distance Calculation
7
8
Calculate grid distance between cells in the hexagonal coordinate system.
9
10
```python { .api }
11
def grid_distance(h1: str, h2: str) -> int:
12
"""
13
Calculate grid distance between two H3 cells.
14
15
Grid distance is the minimum number of grid steps needed to reach
16
one cell from another, following adjacent cell connections.
17
18
Args:
19
h1: First H3 cell identifier
20
h2: Second H3 cell identifier
21
22
Returns:
23
Grid distance as integer (minimum steps between cells)
24
25
Raises:
26
H3CellInvalidError: If either cell identifier is invalid
27
H3GridNavigationError: If cells are too far apart to compute distance
28
29
Note:
30
Both cells must be at the same resolution.
31
Maximum computable distance depends on resolution but is typically
32
several thousand grid steps.
33
"""
34
```
35
36
### Neighbor Discovery
37
38
Find cells within a specified grid distance, creating disk and ring patterns.
39
40
```python { .api }
41
def grid_disk(h: str, k: int = 1) -> list[str]:
42
"""
43
Get all cells within grid distance k from origin cell (filled disk).
44
45
Returns the origin cell plus all cells reachable within k grid steps,
46
forming a filled hexagonal pattern.
47
48
Args:
49
h: Origin H3 cell identifier
50
k: Maximum grid distance (default 1 for immediate neighbors)
51
52
Returns:
53
List of H3 cell identifiers including origin and all cells within distance k.
54
Order is not guaranteed.
55
56
Raises:
57
H3CellInvalidError: If h is not a valid H3 cell
58
H3GridNavigationError: If k is too large or operation fails
59
60
Note:
61
k=0 returns just the origin cell [h]
62
k=1 returns origin + 6 immediate neighbors (7 total)
63
k=2 returns origin + 6 + 12 neighbors (19 total)
64
Cell count follows pattern: 3k² + 3k + 1
65
"""
66
67
def grid_ring(h: str, k: int = 1) -> list[str]:
68
"""
69
Get all cells at exactly grid distance k from origin cell (hollow ring).
70
71
Returns only cells that are exactly k grid steps away, forming
72
a hexagonal ring around the origin.
73
74
Args:
75
h: Origin H3 cell identifier
76
k: Exact grid distance (default 1)
77
78
Returns:
79
List of H3 cell identifiers at distance k from origin.
80
Order is not guaranteed.
81
82
Raises:
83
H3CellInvalidError: If h is not a valid H3 cell
84
H3GridNavigationError: If k is too large or operation fails
85
86
Note:
87
k=0 returns just the origin cell [h]
88
k=1 returns 6 immediate neighbors
89
k=2 returns 12 cells in the second ring
90
Ring size follows pattern: 6k for k > 0
91
"""
92
```
93
94
### Neighbor Testing
95
96
Check if two cells are adjacent neighbors.
97
98
```python { .api }
99
def are_neighbor_cells(h1: str, h2: str) -> bool:
100
"""
101
Check if two H3 cells are immediate neighbors.
102
103
Two cells are neighbors if they share an edge (grid distance = 1).
104
105
Args:
106
h1: First H3 cell identifier
107
h2: Second H3 cell identifier
108
109
Returns:
110
True if cells are immediate neighbors, False otherwise
111
112
Raises:
113
H3CellInvalidError: If either cell identifier is invalid
114
115
Note:
116
Cells must be at the same resolution.
117
Each hexagon has exactly 6 neighbors.
118
Each pentagon has exactly 5 neighbors.
119
"""
120
```
121
122
### Pathfinding
123
124
Find paths between cells in the hexagonal grid.
125
126
```python { .api }
127
def grid_path_cells(start: str, end: str) -> list[str]:
128
"""
129
Find a path of cells from start to end cell.
130
131
Returns an ordered sequence of adjacent cells forming a minimum-length
132
path from start to end. The path includes both start and end cells.
133
134
Args:
135
start: Starting H3 cell identifier
136
end: Ending H3 cell identifier
137
138
Returns:
139
Ordered list of H3 cell identifiers from start to end.
140
First cell is start, last cell is end.
141
142
Raises:
143
H3CellInvalidError: If either cell identifier is invalid
144
H3GridNavigationError: If path cannot be computed (cells too far apart)
145
146
Note:
147
Cells must be at the same resolution.
148
Path length equals grid_distance(start, end) + 1.
149
Multiple valid paths may exist; this returns one of minimum length.
150
"""
151
```
152
153
## Usage Examples
154
155
### Basic Distance and Neighbors
156
157
```python
158
import h3
159
160
# Create a cell and find its neighbors
161
origin = h3.latlng_to_cell(37.7749, -122.4194, 9)
162
print(f"Origin cell: {origin}")
163
164
# Get immediate neighbors (k=1)
165
neighbors = h3.grid_disk(origin, k=1)
166
print(f"Cell + neighbors: {len(neighbors)} cells") # 7 cells (1 + 6 neighbors)
167
168
# Get just the neighboring ring
169
ring = h3.grid_ring(origin, k=1)
170
print(f"Neighbor ring: {len(ring)} cells") # 6 cells
171
172
# Test if specific cells are neighbors
173
neighbor = ring[0] # Pick first neighbor
174
is_neighbor = h3.are_neighbor_cells(origin, neighbor)
175
print(f"Are neighbors: {is_neighbor}") # True
176
177
# Calculate distance
178
distance = h3.grid_distance(origin, neighbor)
179
print(f"Grid distance: {distance}") # 1
180
```
181
182
### Multi-Ring Analysis
183
184
```python
185
import h3
186
187
origin = h3.latlng_to_cell(40.7589, -73.9851, 8) # NYC
188
189
# Analyze expanding rings
190
for k in range(5):
191
disk = h3.grid_disk(origin, k)
192
ring = h3.grid_ring(origin, k) if k > 0 else [origin]
193
194
print(f"k={k}: disk={len(disk)} cells, ring={len(ring)} cells")
195
196
# Verify the mathematical relationship
197
expected_disk_size = 3 * k * k + 3 * k + 1
198
expected_ring_size = 6 * k if k > 0 else 1
199
200
assert len(disk) == expected_disk_size
201
assert len(ring) == expected_ring_size
202
203
# Output:
204
# k=0: disk=1 cells, ring=1 cells
205
# k=1: disk=7 cells, ring=6 cells
206
# k=2: disk=19 cells, ring=12 cells
207
# k=3: disk=37 cells, ring=18 cells
208
# k=4: disk=61 cells, ring=24 cells
209
```
210
211
### Pathfinding Example
212
213
```python
214
import h3
215
216
# Create start and end points
217
start_cell = h3.latlng_to_cell(37.7749, -122.4194, 9) # San Francisco
218
end_cell = h3.latlng_to_cell(37.7849, -122.4094, 9) # Slightly northeast
219
220
# Calculate distance
221
distance = h3.grid_distance(start_cell, end_cell)
222
print(f"Grid distance: {distance} steps")
223
224
# Find a path
225
path = h3.grid_path_cells(start_cell, end_cell)
226
print(f"Path length: {len(path)} cells")
227
print(f"Path distance matches: {len(path) - 1 == distance}") # True
228
229
# Verify path integrity
230
for i in range(len(path) - 1):
231
current = path[i]
232
next_cell = path[i + 1]
233
assert h3.are_neighbor_cells(current, next_cell), f"Path broken at step {i}"
234
235
print("Path verified: all consecutive cells are neighbors")
236
237
# Print path coordinates
238
print("\nPath coordinates:")
239
for i, cell in enumerate(path):
240
lat, lng = h3.cell_to_latlng(cell)
241
print(f" Step {i}: {cell} -> {lat:.6f}, {lng:.6f}")
242
```
243
244
### Large Area Coverage
245
246
```python
247
import h3
248
249
# Find all cells within 3km of a point (approximate)
250
center_lat, center_lng = 51.5074, -0.1278 # London
251
resolution = 8 # ~500m edge length
252
253
center_cell = h3.latlng_to_cell(center_lat, center_lng, resolution)
254
255
# Experiment with different k values to find ~3km coverage
256
# At resolution 8, each cell is ~500m across, so k=6 gives ~3km radius
257
coverage_cells = h3.grid_disk(center_cell, k=6)
258
259
print(f"Coverage area: {len(coverage_cells)} cells")
260
print(f"Approximate area: {len(coverage_cells) * 0.25:.1f} km²")
261
# Rough estimate: each res-8 cell is ~0.25 km²
262
263
# Get the boundary cells only (perimeter)
264
perimeter = h3.grid_ring(center_cell, k=6)
265
print(f"Perimeter: {len(perimeter)} cells")
266
267
# Convert coverage to lat/lng boundaries for visualization
268
boundary_points = []
269
for cell in coverage_cells:
270
boundary = h3.cell_to_boundary(cell)
271
boundary_points.extend(boundary)
272
273
print(f"Total boundary points: {len(boundary_points)}")
274
```
275
276
### Performance Considerations
277
278
```python
279
import h3
280
import time
281
282
# Large grid operations can be expensive
283
origin = h3.latlng_to_cell(0, 0, 7) # Equator, resolution 7
284
285
# Time expanding disk operations
286
for k in [5, 10, 15, 20]:
287
start_time = time.time()
288
try:
289
disk = h3.grid_disk(origin, k)
290
elapsed = time.time() - start_time
291
print(f"k={k}: {len(disk)} cells in {elapsed:.3f}s")
292
except Exception as e:
293
print(f"k={k}: Failed - {e}")
294
295
# Note: Very large k values may fail or be slow
296
# Consider breaking large areas into smaller chunks
297
```