or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced-operations.mdcell-hierarchy.mdcore-cell-operations.mddirected-edges.mdgrid-navigation.mdindex.mdmeasurements.mdpolygon-operations.md

cell-hierarchy.mddocs/

0

# Cell Hierarchy

1

2

Operations for working with H3's hierarchical structure, including parent-child relationships, cell compaction, and resolution changes. H3's multi-resolution hierarchy enables efficient storage and analysis across different scales.

3

4

## Capabilities

5

6

### Parent-Child Relationships

7

8

Navigate up and down the hierarchical structure between different resolution levels.

9

10

```python { .api }

11

def cell_to_parent(h: str, res: int = None) -> str:

12

"""

13

Get the parent cell at a coarser resolution.

14

15

Args:

16

h: H3 cell identifier

17

res: Target parent resolution. If None, uses resolution(h) - 1

18

19

Returns:

20

Parent H3 cell identifier at target resolution

21

22

Raises:

23

H3CellInvalidError: If h is not a valid H3 cell

24

H3ResDomainError: If res < 0 or res >= resolution(h)

25

26

Note:

27

Parent resolution must be coarser (lower number) than child.

28

Each cell has exactly one parent at each coarser resolution.

29

"""

30

31

def cell_to_children(h: str, res: int = None) -> list[str]:

32

"""

33

Get all child cells at a finer resolution.

34

35

Args:

36

h: H3 cell identifier

37

res: Target child resolution. If None, uses resolution(h) + 1

38

39

Returns:

40

List of child H3 cell identifiers at target resolution

41

42

Raises:

43

H3CellInvalidError: If h is not a valid H3 cell

44

H3ResDomainError: If res > 15 or res <= resolution(h)

45

46

Note:

47

Child resolution must be finer (higher number) than parent.

48

Most cells have 7 children, but some have different counts due to

49

the spherical geometry and pentagon locations.

50

"""

51

52

def cell_to_children_size(h: str, res: int = None) -> int:

53

"""

54

Get the count of child cells at a finer resolution.

55

56

Args:

57

h: H3 cell identifier

58

res: Target child resolution. If None, uses resolution(h) + 1

59

60

Returns:

61

Number of child cells at target resolution

62

63

Raises:

64

H3CellInvalidError: If h is not a valid H3 cell

65

H3ResDomainError: If res > 15 or res <= resolution(h)

66

67

Note:

68

More efficient than len(cell_to_children(h, res)) for large child counts.

69

"""

70

71

def cell_to_center_child(h: str, res: int = None) -> str:

72

"""

73

Get the center child cell at a finer resolution.

74

75

The center child is the child cell whose center is closest to

76

the parent cell's center.

77

78

Args:

79

h: H3 cell identifier

80

res: Target child resolution. If None, uses resolution(h) + 1

81

82

Returns:

83

Center child H3 cell identifier

84

85

Raises:

86

H3CellInvalidError: If h is not a valid H3 cell

87

H3ResDomainError: If res > 15 or res <= resolution(h)

88

"""

89

```

90

91

### Child Positioning

92

93

Work with child position indices within parent cells.

94

95

```python { .api }

96

def cell_to_child_pos(child: str, res_parent: int) -> int:

97

"""

98

Get the position index of a child cell within its parent.

99

100

Args:

101

child: Child H3 cell identifier

102

res_parent: Resolution of the parent cell

103

104

Returns:

105

Integer position index of child relative to parent

106

107

Raises:

108

H3CellInvalidError: If child is not a valid H3 cell

109

H3ResDomainError: If res_parent >= resolution(child)

110

111

Note:

112

Position indices are stable: the same child always has the same

113

position within its parent across different operations.

114

"""

115

116

def child_pos_to_cell(parent: str, res_child: int, child_pos: int) -> str:

117

"""

118

Get a specific child cell by position index.

119

120

Args:

121

parent: Parent H3 cell identifier

122

res_child: Resolution of desired child cell

123

child_pos: Position index of desired child

124

125

Returns:

126

Child H3 cell identifier at specified position

127

128

Raises:

129

H3CellInvalidError: If parent is not a valid H3 cell

130

H3ResDomainError: If res_child <= resolution(parent) or res_child > 15

131

ValueError: If child_pos is outside valid range for this parent

132

133

Note:

134

Valid child_pos range is 0 to cell_to_children_size(parent, res_child) - 1.

135

"""

136

```

137

138

### Cell Compaction

139

140

Optimize cell collections by combining child cells into parents where possible.

141

142

```python { .api }

143

def compact_cells(cells: list[str]) -> list[str]:

144

"""

145

Compact a collection of cells by combining children into parents.

146

147

When all children of a parent cell are present in the input collection,

148

they are replaced by their parent cell. This process continues recursively

149

up the hierarchy until no further compaction is possible.

150

151

Args:

152

cells: Collection of H3 cell identifiers (must all be same resolution)

153

154

Returns:

155

Compacted list of H3 cell identifiers (mixed resolutions)

156

157

Raises:

158

H3ResMismatchError: If input cells have different resolutions

159

H3CellInvalidError: If any cell identifier is invalid

160

161

Note:

162

Input cells must all be at the same resolution.

163

Output may contain cells at various resolutions.

164

Compaction reduces storage and improves query performance.

165

"""

166

167

def uncompact_cells(cells: list[str], res: int) -> list[str]:

168

"""

169

Expand a collection of cells to a uniform resolution.

170

171

All cells in the collection are expanded to their children at the

172

target resolution. This reverses the compact_cells operation.

173

174

Args:

175

cells: Collection of H3 cell identifiers (mixed resolutions allowed)

176

res: Target resolution for all output cells

177

178

Returns:

179

List of H3 cell identifiers all at target resolution

180

181

Raises:

182

H3ResDomainError: If res > 15

183

H3CellInvalidError: If any cell identifier is invalid

184

ValueError: If any input cell has resolution > res

185

186

Note:

187

All input cells must have resolution <= target resolution.

188

Output cells provide complete coverage of input area at uniform resolution.

189

"""

190

```

191

192

### System Introspection

193

194

Get information about cells at specific resolutions and system structure.

195

196

```python { .api }

197

def get_res0_cells() -> list[str]:

198

"""

199

Get all H3 cells at resolution 0 (base cells).

200

201

Returns:

202

List of all 122 base H3 cells covering the Earth

203

204

Note:

205

These are the coarsest cells in the H3 system.

206

All other cells are descendants of these base cells.

207

Order is not guaranteed.

208

"""

209

210

def get_pentagons(res: int) -> list[str]:

211

"""

212

Get all pentagon cells at a given resolution.

213

214

Args:

215

res: H3 resolution (0-15)

216

217

Returns:

218

List of all 12 pentagon H3 cells at the specified resolution

219

220

Raises:

221

H3ResDomainError: If res < 0 or res > 15

222

223

Note:

224

There are exactly 12 pentagons at every resolution level.

225

All other cells at that resolution are hexagons.

226

Pentagons occur at the 12 vertices of the icosahedron.

227

"""

228

```

229

230

## Usage Examples

231

232

### Basic Parent-Child Navigation

233

234

```python

235

import h3

236

237

# Start with a high-resolution cell

238

child_cell = h3.latlng_to_cell(37.7749, -122.4194, 9)

239

print(f"Child cell (res 9): {child_cell}")

240

print(f"Resolution: {h3.get_resolution(child_cell)}")

241

242

# Get parent at resolution 7

243

parent = h3.cell_to_parent(child_cell, res=7)

244

print(f"Parent cell (res 7): {parent}")

245

246

# Get all children of the parent back at resolution 9

247

children = h3.cell_to_children(parent, res=9)

248

print(f"Parent has {len(children)} children at resolution 9")

249

print(f"Original child in children: {child_cell in children}") # True

250

251

# Get just the center child

252

center_child = h3.cell_to_center_child(parent, res=9)

253

print(f"Center child: {center_child}")

254

print(f"Center child is original: {center_child == child_cell}")

255

```

256

257

### Multi-Level Hierarchy

258

259

```python

260

import h3

261

262

# Trace a cell through multiple resolution levels

263

original = h3.latlng_to_cell(51.5074, -0.1278, 10) # London, res 10

264

265

print("Hierarchy from coarse to fine:")

266

current = original

267

268

# Go up to resolution 0

269

while h3.get_resolution(current) > 0:

270

parent = h3.cell_to_parent(current)

271

res = h3.get_resolution(parent)

272

print(f" Resolution {res}: {parent}")

273

current = parent

274

275

print(f" Resolution 0: {current} (base cell)")

276

277

# Go back down showing child counts

278

current = h3.cell_to_parent(original, res=5) # Start from res 5

279

print(f"\nChild expansion from resolution 5:")

280

281

for target_res in range(6, 11):

282

children = h3.cell_to_children(current, res=target_res)

283

print(f" Res {target_res}: {len(children)} children")

284

285

# For next iteration, use the center child

286

if target_res < 10:

287

current = h3.cell_to_center_child(current, res=target_res)

288

```

289

290

### Child Positioning

291

292

```python

293

import h3

294

295

# Work with child positions

296

parent = h3.latlng_to_cell(40.7589, -73.9851, 6) # NYC, res 6

297

children = h3.cell_to_children(parent)

298

299

print(f"Parent: {parent}")

300

print(f"Children ({len(children)}):")

301

302

# Show each child with its position

303

positions = []

304

for child in children:

305

pos = h3.cell_to_child_pos(child, res_parent=6)

306

positions.append((child, pos))

307

print(f" Position {pos}: {child}")

308

309

# Sort by position and verify we can reconstruct

310

positions.sort(key=lambda x: x[1])

311

print(f"\nReconstructing children by position:")

312

313

for child, pos in positions:

314

reconstructed = h3.child_pos_to_cell(parent, res_child=7, child_pos=pos)

315

print(f" Position {pos}: {reconstructed} (matches: {child == reconstructed})")

316

```

317

318

### Cell Compaction

319

320

```python

321

import h3

322

import random

323

324

# Create a region with some complete families of children

325

center = h3.latlng_to_cell(37.7749, -122.4194, 6)

326

region_cells = h3.grid_disk(center, k=2) # Get area around center

327

328

# Expand all to resolution 8

329

expanded = h3.uncompact_cells(region_cells, res=8)

330

print(f"Original region: {len(region_cells)} cells at res 6")

331

print(f"Expanded region: {len(expanded)} cells at res 8")

332

333

# Add some random cells at resolution 8 to create incomplete families

334

random_cells = []

335

for _ in range(20):

336

lat = 37.7749 + random.uniform(-0.1, 0.1)

337

lng = -122.4194 + random.uniform(-0.1, 0.1)

338

cell = h3.latlng_to_cell(lat, lng, 8)

339

random_cells.append(cell)

340

341

all_cells = expanded + random_cells

342

print(f"With random additions: {len(all_cells)} cells")

343

344

# Compact back down

345

compacted = h3.compact_cells(all_cells)

346

print(f"After compaction: {len(compacted)} cells")

347

348

# Verify coverage is preserved by expanding back

349

verification = h3.uncompact_cells(compacted, res=8)

350

original_set = set(all_cells)

351

verification_set = set(verification)

352

353

print(f"Coverage preserved: {original_set == verification_set}")

354

print(f"Compression ratio: {len(compacted) / len(all_cells):.2f}")

355

```

356

357

### Pentagon Analysis

358

359

```python

360

import h3

361

362

# Analyze pentagons across resolutions

363

print("Pentagon analysis:")

364

for res in range(0, 6):

365

pentagons = h3.get_pentagons(res)

366

print(f"Resolution {res}: {len(pentagons)} pentagons")

367

368

# Show some pentagon properties

369

pentagon = pentagons[0] # Pick first pentagon

370

neighbors = h3.grid_ring(pentagon, k=1)

371

372

print(f" Example pentagon {pentagon}:")

373

print(f" Has {len(neighbors)} neighbors (vs 6 for hexagons)")

374

print(f" Boundary has {len(h3.cell_to_boundary(pentagon))} vertices")

375

376

# Find pentagon children behavior

377

res0_pentagon = h3.get_pentagons(0)[0]

378

children = h3.cell_to_children(res0_pentagon, res=1)

379

print(f"\nResolution 0 pentagon has {len(children)} children at res 1")

380

381

# Compare to a hexagon at res 0

382

res0_cells = h3.get_res0_cells()

383

res0_hexagons = [cell for cell in res0_cells if not h3.is_pentagon(cell)]

384

hexagon = res0_hexagons[0]

385

hex_children = h3.cell_to_children(hexagon, res=1)

386

print(f"Resolution 0 hexagon has {len(hex_children)} children at res 1")

387

```

388

389

### Base Cell Analysis

390

391

```python

392

import h3

393

394

# Analyze the base H3 system structure

395

base_cells = h3.get_res0_cells()

396

print(f"Total base cells: {len(base_cells)}")

397

398

pentagon_count = sum(1 for cell in base_cells if h3.is_pentagon(cell))

399

hexagon_count = len(base_cells) - pentagon_count

400

401

print(f" Pentagons: {pentagon_count}")

402

print(f" Hexagons: {hexagon_count}")

403

404

# Show base cell numbers

405

print(f"\nBase cell number range:")

406

base_numbers = [h3.get_base_cell_number(cell) for cell in base_cells]

407

print(f" Min: {min(base_numbers)}")

408

print(f" Max: {max(base_numbers)}")

409

print(f" Unique count: {len(set(base_numbers))}")

410

411

# Verify all base cells are resolution 0

412

resolutions = [h3.get_resolution(cell) for cell in base_cells]

413

print(f"\nAll resolution 0: {all(res == 0 for res in resolutions)}")

414

415

# Show some base cell coverage

416

print(f"\nSample base cells with centers:")

417

for i, cell in enumerate(base_cells[:5]):

418

lat, lng = h3.cell_to_latlng(cell)

419

is_pent = "pentagon" if h3.is_pentagon(cell) else "hexagon"

420

base_num = h3.get_base_cell_number(cell)

421

print(f" Base {base_num}: {cell} -> {lat:.1f}, {lng:.1f} ({is_pent})")

422

```