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

directed-edges.mddocs/

0

# Directed Edges

1

2

Operations for working with directed edges between adjacent H3 cells. H3 directed edges represent connections between neighboring cells and enable analysis of cell boundaries, adjacency relationships, and edge-based operations.

3

4

## Capabilities

5

6

### Edge Creation and Validation

7

8

Create and validate H3 directed edges between adjacent cells.

9

10

```python { .api }

11

def cells_to_directed_edge(origin: str, destination: str) -> str:

12

"""

13

Create a directed edge between two adjacent H3 cells.

14

15

Creates an H3 directed edge identifier representing the connection

16

from origin cell to destination cell.

17

18

Args:

19

origin: Starting H3 cell identifier

20

destination: Ending H3 cell identifier

21

22

Returns:

23

H3 directed edge identifier

24

25

Raises:

26

H3CellInvalidError: If either cell identifier is invalid

27

H3NotNeighborsError: If cells are not adjacent neighbors

28

H3ResMismatchError: If cells have different resolutions

29

30

Note:

31

Cells must be immediate neighbors (grid_distance = 1).

32

Both cells must be at the same resolution.

33

Edge direction matters: edge(A,B) ≠ edge(B,A).

34

"""

35

36

def is_valid_directed_edge(edge: str) -> bool:

37

"""

38

Check if an H3 directed edge identifier is valid.

39

40

Args:

41

edge: H3 directed edge identifier (string or int)

42

43

Returns:

44

True if valid H3 directed edge, False otherwise

45

46

Note:

47

Returns False for any input that cannot be parsed as H3 edge,

48

including H3 cells or vertices.

49

"""

50

```

51

52

### Edge Decomposition

53

54

Extract information from H3 directed edges.

55

56

```python { .api }

57

def directed_edge_to_cells(e: str) -> tuple[str, str]:

58

"""

59

Get the origin and destination cells from a directed edge.

60

61

Args:

62

e: H3 directed edge identifier

63

64

Returns:

65

Tuple of (origin_cell, destination_cell)

66

67

Raises:

68

H3DirEdgeInvalidError: If e is not a valid H3 directed edge

69

70

Note:

71

This is the inverse operation of cells_to_directed_edge().

72

"""

73

74

def get_directed_edge_origin(e: str) -> str:

75

"""

76

Get the origin cell from a directed edge.

77

78

Args:

79

e: H3 directed edge identifier

80

81

Returns:

82

Origin H3 cell identifier

83

84

Raises:

85

H3DirEdgeInvalidError: If e is not a valid H3 directed edge

86

"""

87

88

def get_directed_edge_destination(e: str) -> str:

89

"""

90

Get the destination cell from a directed edge.

91

92

Args:

93

e: H3 directed edge identifier

94

95

Returns:

96

Destination H3 cell identifier

97

98

Raises:

99

H3DirEdgeInvalidError: If e is not a valid H3 directed edge

100

"""

101

```

102

103

### Edge Enumeration

104

105

Find all directed edges associated with a cell.

106

107

```python { .api }

108

def origin_to_directed_edges(origin: str) -> list[str]:

109

"""

110

Get all directed edges starting from an origin cell.

111

112

Returns edges from the origin cell to each of its neighbors.

113

114

Args:

115

origin: H3 cell identifier

116

117

Returns:

118

List of H3 directed edge identifiers starting from origin.

119

Order is not guaranteed.

120

121

Raises:

122

H3CellInvalidError: If origin is not a valid H3 cell

123

124

Note:

125

Hexagon cells return 6 edges, pentagon cells return 5 edges.

126

Each edge connects to one of the cell's immediate neighbors.

127

"""

128

```

129

130

### Edge Geometry

131

132

Extract geometric information from directed edges.

133

134

```python { .api }

135

def directed_edge_to_boundary(edge: str) -> tuple[tuple[float, float], ...]:

136

"""

137

Get the boundary points of a directed edge.

138

139

Returns the line segments that form the edge boundary between

140

two adjacent cells.

141

142

Args:

143

edge: H3 directed edge identifier

144

145

Returns:

146

Tuple of (lat, lng) coordinate pairs defining the edge boundary.

147

Typically returns 2 points (start and end of the edge line).

148

149

Raises:

150

H3DirEdgeInvalidError: If edge is not a valid H3 directed edge

151

152

Note:

153

Points are ordered from origin cell boundary toward destination cell.

154

The edge represents the shared boundary between the two cells.

155

"""

156

```

157

158

## Usage Examples

159

160

### Basic Edge Operations

161

162

```python

163

import h3

164

165

# Create two adjacent cells

166

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

167

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

168

destination = neighbors[0] # Pick first neighbor

169

170

print(f"Origin: {origin}")

171

print(f"Destination: {destination}")

172

173

# Verify they are neighbors

174

is_neighbor = h3.are_neighbor_cells(origin, destination)

175

print(f"Are neighbors: {is_neighbor}")

176

177

# Create directed edge

178

edge = h3.cells_to_directed_edge(origin, destination)

179

print(f"Directed edge: {edge}")

180

181

# Validate the edge

182

is_valid = h3.is_valid_directed_edge(edge)

183

print(f"Edge is valid: {is_valid}")

184

```

185

186

### Edge Decomposition

187

188

```python

189

import h3

190

191

# Start with a known edge

192

origin = h3.latlng_to_cell(40.7589, -73.9851, 8) # NYC

193

all_edges = h3.origin_to_directed_edges(origin)

194

edge = all_edges[0] # Pick first edge

195

196

print(f"Working with edge: {edge}")

197

198

# Extract components

199

extracted_origin = h3.get_directed_edge_origin(edge)

200

extracted_dest = h3.get_directed_edge_destination(edge)

201

202

print(f"Extracted origin: {extracted_origin}")

203

print(f"Extracted destination: {extracted_dest}")

204

print(f"Origin matches: {origin == extracted_origin}")

205

206

# Use combined extraction

207

origin_dest = h3.directed_edge_to_cells(edge)

208

print(f"Combined extraction: {origin_dest}")

209

print(f"Matches individual: {(extracted_origin, extracted_dest) == origin_dest}")

210

211

# Verify round-trip

212

reconstructed_edge = h3.cells_to_directed_edge(extracted_origin, extracted_dest)

213

print(f"Reconstructed edge: {reconstructed_edge}")

214

print(f"Round-trip success: {edge == reconstructed_edge}")

215

```

216

217

### Edge Enumeration and Analysis

218

219

```python

220

import h3

221

222

# Analyze edges for different cell types

223

cells = [

224

h3.latlng_to_cell(37.7749, -122.4194, 7), # Regular hexagon

225

h3.get_pentagons(7)[0] # Pentagon at same resolution

226

]

227

228

for i, cell in enumerate(cells):

229

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

230

print(f"\nCell {i+1} ({cell_type}): {cell}")

231

232

# Get all outgoing edges

233

edges = h3.origin_to_directed_edges(cell)

234

print(f" Outgoing edges: {len(edges)}")

235

236

# Analyze each edge

237

for j, edge in enumerate(edges):

238

dest = h3.get_directed_edge_destination(edge)

239

print(f" Edge {j}: {edge} -> {dest}")

240

241

# Verify neighbor relationship

242

is_neighbor = h3.are_neighbor_cells(cell, dest)

243

assert is_neighbor, f"Edge destination should be neighbor"

244

245

# Expected: hexagon has 6 edges, pentagon has 5 edges

246

expected_count = 5 if h3.is_pentagon(cell) else 6

247

print(f" Expected edges: {expected_count}, actual: {len(edges)}")

248

assert len(edges) == expected_count

249

```

250

251

### Edge Geometry and Boundaries

252

253

```python

254

import h3

255

256

# Create an edge and examine its geometry

257

center = h3.latlng_to_cell(51.5074, -0.1278, 9) # London

258

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

259

edge = h3.cells_to_directed_edge(center, neighbors[0])

260

261

print(f"Analyzing edge: {edge}")

262

263

# Get edge boundary

264

boundary = h3.directed_edge_to_boundary(edge)

265

print(f"Edge boundary points: {len(boundary)}")

266

267

for i, (lat, lng) in enumerate(boundary):

268

print(f" Point {i}: {lat:.6f}, {lng:.6f}")

269

270

# Compare with cell boundaries

271

origin_boundary = h3.cell_to_boundary(center)

272

dest_boundary = h3.cell_to_boundary(neighbors[0])

273

274

print(f"\nOrigin cell boundary: {len(origin_boundary)} points")

275

print(f"Destination cell boundary: {len(dest_boundary)} points")

276

277

# Edge boundary should be part of both cell boundaries

278

print(f"\nEdge represents shared boundary between cells")

279

```

280

281

### Edge Network Analysis

282

283

```python

284

import h3

285

286

# Build a local edge network

287

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

288

region = h3.grid_disk(center, k=2)

289

290

print(f"Analyzing edge network for {len(region)} cells")

291

292

# Collect all edges within the region

293

all_edges = []

294

edge_count_by_cell = {}

295

296

for cell in region:

297

edges = h3.origin_to_directed_edges(cell)

298

299

# Filter edges to only include those within our region

300

internal_edges = []

301

for edge in edges:

302

dest = h3.get_directed_edge_destination(edge)

303

if dest in region:

304

internal_edges.append(edge)

305

306

all_edges.extend(internal_edges)

307

edge_count_by_cell[cell] = len(internal_edges)

308

309

print(f"Total internal edges: {len(all_edges)}")

310

311

# Analyze edge distribution

312

edge_counts = list(edge_count_by_cell.values())

313

print(f"Edge count per cell - min: {min(edge_counts)}, max: {max(edge_counts)}, avg: {sum(edge_counts)/len(edge_counts):.1f}")

314

315

# Verify each edge connects cells within region

316

print("\nValidating edge network:")

317

valid_edges = 0

318

for edge in all_edges:

319

origin, dest = h3.directed_edge_to_cells(edge)

320

if origin in region and dest in region:

321

valid_edges += 1

322

323

print(f"Valid internal edges: {valid_edges}/{len(all_edges)}")

324

```

325

326

### Bidirectional Edge Analysis

327

328

```python

329

import h3

330

331

# Analyze bidirectional relationships

332

cell_a = h3.latlng_to_cell(40.7589, -73.9851, 9)

333

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

334

cell_b = neighbors[0]

335

336

print(f"Cell A: {cell_a}")

337

print(f"Cell B: {cell_b}")

338

339

# Create edges in both directions

340

edge_a_to_b = h3.cells_to_directed_edge(cell_a, cell_b)

341

edge_b_to_a = h3.cells_to_directed_edge(cell_b, cell_a)

342

343

print(f"A->B edge: {edge_a_to_b}")

344

print(f"B->A edge: {edge_b_to_a}")

345

print(f"Edges are different: {edge_a_to_b != edge_b_to_a}")

346

347

# Verify both edges represent the same geometric boundary

348

boundary_a_to_b = h3.directed_edge_to_boundary(edge_a_to_b)

349

boundary_b_to_a = h3.directed_edge_to_boundary(edge_b_to_a)

350

351

print(f"\nBoundary A->B: {len(boundary_a_to_b)} points")

352

print(f"Boundary B->A: {len(boundary_b_to_a)} points")

353

354

# Boundaries should be related (possibly reversed)

355

print(f"Same boundary points: {set(boundary_a_to_b) == set(boundary_b_to_a)}")

356

357

# Check all pairs of neighbors have symmetric edges

358

cell_edges = h3.origin_to_directed_edges(cell_a)

359

print(f"\nSymmetric edge verification:")

360

361

for edge in cell_edges:

362

neighbor = h3.get_directed_edge_destination(edge)

363

reverse_edge = h3.cells_to_directed_edge(neighbor, cell_a)

364

365

print(f" {cell_a} -> {neighbor}: {edge}")

366

print(f" {neighbor} -> {cell_a}: {reverse_edge}")

367

print(f" Both valid: {h3.is_valid_directed_edge(edge) and h3.is_valid_directed_edge(reverse_edge)}")

368

```

369

370

### Edge Length Calculation

371

372

```python

373

import h3

374

375

# Calculate edge lengths using the edge measurement functions

376

center = h3.latlng_to_cell(0, 0, 10) # Equator, high resolution

377

edges = h3.origin_to_directed_edges(center)

378

379

print(f"Edge length analysis for resolution 10 cell at equator:")

380

print(f"Cell has {len(edges)} edges")

381

382

# Calculate length of each edge

383

edge_lengths = []

384

for i, edge in enumerate(edges):

385

length_km = h3.edge_length(edge, 'km')

386

length_m = h3.edge_length(edge, 'm')

387

edge_lengths.append(length_km)

388

389

print(f" Edge {i}: {length_km:.3f} km ({length_m:.1f} m)")

390

391

# Compare to average for this resolution

392

avg_edge_length = h3.average_hexagon_edge_length(10, 'km')

393

actual_avg = sum(edge_lengths) / len(edge_lengths)

394

395

print(f"\nAverage edge length (H3 system): {avg_edge_length:.3f} km")

396

print(f"Average edge length (this cell): {actual_avg:.3f} km")

397

print(f"Match: {abs(avg_edge_length - actual_avg) < 0.001}")

398

399

# Variation in edge lengths (should be minimal for regular hexagon)

400

max_length = max(edge_lengths)

401

min_length = min(edge_lengths)

402

variation = (max_length - min_length) / avg_edge_length

403

404

print(f"Edge length variation: {variation:.1%}")

405

```