Source: https://gometry.monicz.dev/api/h3/

# H3

H3 hexagonal cells, area covers, neighbors, directed edges, and vertices.

**Related:** [Grid-generic API](https://gometry.monicz.dev/api/grids/)

## Types

## H3Cell

Accepted call forms

```python
H3Cell(value: H3Cell | (int | integer[Any] | ndarray[tuple[()], dtype[signedinteger[Any] | unsignedinteger[Any]]]) | str, /) -> H3Cell
```

```python
H3Cell(value: Point, /, *, resolution: int | integer[Any]) -> H3Cell
```

```python
H3Cell(value: FloatScalar | ScalarFloatArray, /, lat: FloatScalar | ScalarFloatArray, *, resolution: int | integer[Any]) -> H3Cell
```

One H3 cell: a resolution-addressed hexagonal (or pentagonal) tile.

Wraps the 64-bit cell index with typed accessors (`cell.resolution`,
`cell.polygon`, `cell.center`, `cell.area`), hierarchy moves
(`parent`/`children`), and grid traversal (`grid_disk`,
`grid_ring`, `grid_path`, `grid_distance`). Convert via
`H3Cell(...)`, and back with `int(cell)`.

One H3 cell from an id, token, lon/lat pair, or point geometry.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `value` | `H3Cell \| (int \| integer[Any] \| ndarray[tuple[()], dtype[signedinteger[Any] \| unsignedinteger[Any]]]) \| str \| Point \| (FloatScalar \| ScalarFloatArray)` | An existing cell, id, token, longitude of a `lon, lat` pair, or a point geometry. | *required* |
| `resolution` | `int \| integer[Any]` | H3 resolution (`0`-`15`); required for coordinate construction. | `varies by call form` |
| `lat` | `FloatScalar \| ScalarFloatArray` | Latitude when `value` is a scalar longitude. | `varies by call form` |

Returns:

| Type | Description |
| --- | --- |
| `H3Cell` |  |

Raises:

| Type | Description |
| --- | --- |
| `ParseError` | If `value` is not a valid H3 cell id or token. |
| `GeometryError` | If `resolution` is out of range. |
| `InvalidGeometryError` | If a scalar coordinate is non-finite or out of range. |

Examples:

```pycon
>>> import gometry as gm
>>> gm.H3Cell(13.4, 52.5, resolution=7).resolution
7
```

### base\_cell `property`

```python
base_cell: int
```

The base (resolution-0) cell number this cell descends from
(0-121).

Returns:

| Type | Description |
| --- | --- |
| `int` |  |

### edges `property`

```python
edges: H3EdgeArray
```

The directed edges leaving this cell (6, or 5 on a pentagon).

Returns:

| Type | Description |
| --- | --- |
| `H3EdgeArray` |  |

### is\_pentagon `property`

```python
is_pentagon: bool
```

Whether this cell is one of the 12 pentagons at its resolution.

Returns:

| Type | Description |
| --- | --- |
| `bool` |  |

### resolution `property`

```python
resolution: int
```

H3 resolution of this cell (`0`-`15`).

Returns:

| Type | Description |
| --- | --- |
| `int` |  |

### vertices `property`

```python
vertices: H3VertexArray
```

The cell's topological vertices, with canonical shared identity.

Adjacent cells return the *same* vertex objects for their shared
corners (equal ids), so vertices deduplicate across a coverage —
unlike `polygon`, which yields per-cell coordinate copies.

Returns:

| Type | Description |
| --- | --- |
| `H3VertexArray` | Five vertices for a pentagon, six for a hexagon. |

### cell\_from\_local\_ij

```python
cell_from_local_ij(i: int, j: int) -> H3Cell
```

Return the cell at local `(i, j)` coordinates relative to this origin —
the inverse of `local_ij`.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `i` | `int` | Local IJ coordinates. | *required* |
| `j` | `int` | Local IJ coordinates. | *required* |

Returns:

| Type | Description |
| --- | --- |
| `H3Cell` |  |

Examples:

```pycon
>>> import gometry as gm
>>> cell = gm.h3_cover(gm.Point(-122.4194, 37.7749, crs=4326), resolution=7)[0]
>>> assert cell is not None
>>> cell.cell_from_local_ij(160, 88).token
'872830828ffffff'
```

### center\_child

```python
center_child(resolution: int) -> H3Cell
```

Return the child whose center coincides with this cell's center.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `resolution` | `int` | Target resolution (`0`-`15`); must not be coarser than this cell's. | *required* |

Returns:

| Type | Description |
| --- | --- |
| `H3Cell` | The center child at `resolution`. |

Raises:

| Type | Description |
| --- | --- |
| `GeometryError` | If `resolution` is out of range or coarser than the cell's. |

Examples:

```pycon
>>> import gometry as gm
>>> cell = gm.h3_cover(gm.Point(-122.4194, 37.7749, crs=4326), resolution=7)[0]
>>> assert cell is not None
>>> cell.center_child(resolution=8).token
'8828308281fffff'
```

### child\_at

```python
child_at(position: int, resolution: int) -> H3Cell
```

Return the child at `position` in this cell's ordered descendants.

The inverse of `child_position`:
`cell.child_at(position, resolution)` recovers the cell that
reported `position` at this cell's resolution.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `position` | `int` | Zero-based position among this cell's descendants at `resolution` (`0` to `children_count(resolution) - 1`). | *required* |
| `resolution` | `int` | Target resolution (`0`-`15`); must not be coarser than this cell's. | *required* |

Returns:

| Type | Description |
| --- | --- |
| `H3Cell` | The descendant cell at `position`. |

Raises:

| Type | Description |
| --- | --- |
| `GeometryError` | If `resolution` is out of range or coarser than the cell's. |

Examples:

```pycon
>>> import gometry as gm
>>> cell = gm.h3_cover(gm.Point(-122.4194, 37.7749, crs=4326), resolution=7)[0]
>>> assert cell is not None
>>> cell.child_at(0, 8).token
'8828308281fffff'
```

### child\_position

```python
child_position(resolution: int) -> int | None
```

This cell's position among `parent(resolution)`'s descendants at
this cell's resolution, or None when resolution is finer than
the cell's own.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `resolution` | `int` | The ancestor resolution to count from. | *required* |

Returns:

| Type | Description |
| --- | --- |
| `int or None` |  |

Examples:

```pycon
>>> import gometry as gm
>>> cell = gm.h3_cover(gm.Point(-122.4194, 37.7749, crs=4326), resolution=7)[0]
>>> assert cell is not None
>>> child = cell.children(resolution=8)[0]
>>> assert child is not None
>>> child.child_position(7)
0
```

### children

```python
children(resolution: int | None = None) -> CellArray[H3Cell]
```

Child cells at a finer resolution.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `resolution` | `int` | Target resolution; must not be coarser than this cell's. Defaults to one finer than this cell's resolution; a maximum-depth cell has no children and yields an empty CellArray. | `None` |

Returns:

| Type | Description |
| --- | --- |
| `CellArray of H3Cell` | The descendant cells in the grid's public identity order. |

Raises:

| Type | Description |
| --- | --- |
| `GeometryError` | If the target depth is invalid for this cell. |

Examples:

```pycon
>>> import gometry as gm
>>> cell = gm.h3_cover(gm.Point(-122.4194, 37.7749, crs=4326), resolution=7)[0]
>>> assert cell is not None
>>> len(cell.children(resolution=8))
7
```

### children\_count

```python
children_count(resolution: int | None = None) -> int
```

Number of descendant cells at a finer resolution, counted closed-form without materializing them.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `resolution` | `int` | Target resolution; must not be coarser than this cell's. Defaults to one finer than this cell's resolution; a maximum-depth cell has no children and returns `0`. | `None` |

Returns:

| Type | Description |
| --- | --- |
| `int` | The exact descendant count (H3 pentagons have slightly fewer than hexagons). |

Raises:

| Type | Description |
| --- | --- |
| `GeometryError` | If the target depth is coarser than this cell's, or invalid. |

Examples:

```pycon
>>> import gometry as gm
>>> cell = gm.h3_cover(gm.Point(-122.4194, 37.7749, crs=4326), resolution=7)[0]
>>> assert cell is not None
>>> cell.children_count(resolution=8)
7
```

### edge

```python
edge(destination: H3Cell | int | str) -> H3Edge
```

Return the directed edge from this cell to a neighboring cell.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `destination` | `H3Cell, int, or str` | The neighboring cell the edge points into. | *required* |

Returns:

| Type | Description |
| --- | --- |
| `H3Edge` |  |

Raises:

| Type | Description |
| --- | --- |
| `GeometryError` | If `destination` is not a neighbor of this cell. |
| `ParseError` | If `destination` is not a valid H3 cell. |

Examples:

```pycon
>>> import gometry as gm
>>> cell = gm.H3Cell(13.4, 52.5, resolution=7)
>>> neighbor = cell.neighbors[0]
>>> assert neighbor is not None
>>> edge = cell.edge(neighbor)
>>> (edge.origin == cell, edge.destination == neighbor)
(True, True)
```

### grid\_disk

```python
grid_disk(k: int, *, max_cells: int | None = 1000000) -> CellArray[H3Cell]
```

Return cells within k grid steps (filled disk).

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `k` | `int` | Grid radius in steps (`>= 0`); `k=0` is this cell alone. | *required* |
| `max_cells` | `int or None` | Hard cap on returned cells. Pass `None` for unlimited traversal. | `1000000` |

Returns:

| Type | Description |
| --- | --- |
| `CellArray of H3Cell` |  |

Raises:

| Type | Description |
| --- | --- |
| `GeometryError` | If `k` is negative or too large, or the result exceeds `max_cells`. |

Examples:

```pycon
>>> import gometry as gm
>>> cell = gm.h3_cover(gm.Point(-122.4194, 37.7749, crs=4326), resolution=7)[0]
>>> assert cell is not None
>>> len(cell.grid_disk(1))
7
```

### grid\_distance

```python
grid_distance(other: H3Cell | int | str) -> int
```

Grid-step distance to another cell.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `other` | `H3Cell, int, or str` | The target cell; must share this cell's resolution. | *required* |

Returns:

| Type | Description |
| --- | --- |
| `int` |  |

Raises:

| Type | Description |
| --- | --- |
| `GeometryError` | If the cells cannot be connected (different resolutions or too far apart). |
| `ParseError` | If `other` is not a valid H3 cell. |

Examples:

```pycon
>>> import gometry as gm
>>> cell = gm.h3_cover(gm.Point(-122.4194, 37.7749, crs=4326), resolution=7)[0]
>>> assert cell is not None
>>> neighbor = list(cell.neighbors)[0]
>>> assert neighbor is not None
>>> cell.grid_distance(neighbor)
1
```

### grid\_path

```python
grid_path(other: H3Cell | int | str, *, max_cells: int | None = 1000000) -> CellArray[H3Cell]
```

Grid path of cells to another cell.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `other` | `H3Cell, int, or str` | The target cell; must share this cell's resolution. | *required* |
| `max_cells` | `int or None` | Hard cap on returned cells. Pass `None` for unlimited traversal. | `1000000` |

Returns:

| Type | Description |
| --- | --- |
| `CellArray of H3Cell` |  |

Raises:

| Type | Description |
| --- | --- |
| `GeometryError` | If the cells cannot be connected or the result exceeds `max_cells`. |
| `ParseError` | If `other` is not a valid H3 cell. |

Examples:

```pycon
>>> import gometry as gm
>>> cell = gm.h3_cover(gm.Point(-122.4194, 37.7749, crs=4326), resolution=7)[0]
>>> assert cell is not None
>>> nbr = list(cell.neighbors)[0]
>>> assert nbr is not None
>>> len(cell.grid_path(nbr))
2
```

### grid\_ring

```python
grid_ring(k: int, *, max_cells: int | None = 1000000) -> CellArray[H3Cell]
```

Return cells exactly `k` grid steps away (hollow ring).

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `k` | `int` | Grid radius in steps (`>= 0`); `k=0` is this cell alone. | *required* |
| `max_cells` | `int or None` | Hard cap on returned cells. Pass `None` for unlimited traversal. | `1000000` |

Returns:

| Type | Description |
| --- | --- |
| `CellArray of H3Cell` |  |

Raises:

| Type | Description |
| --- | --- |
| `GeometryError` | If `k` is negative or too large, or the result exceeds `max_cells`. |

Examples:

```pycon
>>> import gometry as gm
>>> cell = gm.h3_cover(gm.Point(-122.4194, 37.7749, crs=4326), resolution=7)[0]
>>> assert cell is not None
>>> len(cell.grid_ring(1))
6
```

### is\_neighbor

```python
is_neighbor(other: H3Cell | int | str) -> bool
```

Test whether `other` is an edge-adjacent neighbor of this cell.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `other` | `H3Cell, int, or str` | The candidate neighbor; must share this cell's resolution. | *required* |

Returns:

| Type | Description |
| --- | --- |
| `bool` |  |

Raises:

| Type | Description |
| --- | --- |
| `GeometryError` | If the cells cannot be compared (different resolutions). |
| `ParseError` | If `other` is not a valid H3 cell. |

Examples:

```pycon
>>> import gometry as gm
>>> cell = gm.h3_cover(gm.Point(-122.4194, 37.7749, crs=4326), resolution=7)[0]
>>> assert cell is not None
>>> neighbor = list(cell.neighbors)[0]
>>> assert neighbor is not None
>>> cell.is_neighbor(neighbor)
True
```

### local\_ij

```python
local_ij(origin: H3Cell | int | str) -> tuple[int, int]
```

Local `(i, j)` coordinates of this cell relative to `origin`
(the H3 local-IJ indexing space, for grid algebra around an anchor).

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `origin` | `H3Cell, int, or str` | Anchor cell; must share this cell's resolution and be near it. | *required* |

Returns:

| Type | Description |
| --- | --- |
| `tuple of int` | The `(i, j)` coordinates. |

Raises:

| Type | Description |
| --- | --- |
| `GeometryError` | If the cells are too far apart for local IJ. |
| `ParseError` | If `origin` is not a valid H3 cell. |

Examples:

```pycon
>>> import gometry as gm
>>> cell = gm.h3_cover(gm.Point(-122.4194, 37.7749, crs=4326), resolution=7)[0]
>>> assert cell is not None
>>> cell.local_ij(cell)
(160, 88)
```

### parent

```python
parent(resolution: int | None = None) -> H3Cell
```

Parent cell at a coarser resolution.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `resolution` | `int` | Target resolution; must not be finer than this cell's. Defaults to one coarser than this cell's resolution. | `None` |

Returns:

| Type | Description |
| --- | --- |
| `H3Cell` | The ancestor cell. |

Raises:

| Type | Description |
| --- | --- |
| `GeometryError` | If the target depth is invalid for this cell. |

Examples:

```pycon
>>> import gometry as gm
>>> cell = gm.h3_cover(gm.Point(-122.4194, 37.7749, crs=4326), resolution=7)[0]
>>> assert cell is not None
>>> cell.parent(resolution=6).token
'86283082fffffff'
```

## H3Vertex

Accepted call forms

```python
H3Vertex(value: H3Vertex | (int | integer[Any] | ndarray[tuple[()], dtype[signedinteger[Any] | unsignedinteger[Any]]]) | str) -> H3Vertex
```

A canonical H3 topological vertex.

Vertexes carry shared identity: adjacent cells yield *equal* vertex
objects for their shared corners, so they deduplicate across cell sets
(`{v for cell in cells for v in cell.vertices}`). Obtained from
`H3Cell.vertices`; convert with `int(vertex)` or `vertex.token`.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `value` | `H3Vertex \| (int \| integer[Any] \| ndarray[tuple[()], dtype[signedinteger[Any] \| unsignedinteger[Any]]]) \| str` | An existing vertex, its 64-bit id, or its token.  The vertex, its 64-bit id, or its token. | *required* |

One H3 vertex from an existing `H3Vertex`, a 64-bit id, or a token.

Returns:

| Type | Description |
| --- | --- |
| `H3Vertex` |  |

Raises:

| Type | Description |
| --- | --- |
| `ParseError` | If `value` is not a valid H3 vertex id or token. |
| `TypeError` | If `value` is not an `H3Vertex`, int, or str. |

### id `property`

```python
id: int
```

The vertex's 64-bit H3 index.

Returns:

| Type | Description |
| --- | --- |
| `int` |  |

### nbytes `property`

```python
nbytes: int
```

Raw vertex id payload in bytes.

Returns:

| Type | Description |
| --- | --- |
| `int` |  |

### point `property`

```python
point: Point
```

The vertex's location.

Returns:

| Type | Description |
| --- | --- |
| `Point` | Longitude/latitude point tagged `OGC:CRS84`. |

### token `property`

```python
token: str
```

The vertex's hexadecimal token.

Returns:

| Type | Description |
| --- | --- |
| `str` |  |

## H3VertexArray

Accepted call forms

```python
H3VertexArray(values: ndarray[tuple[()], dtype[signedinteger[Any] | unsignedinteger[Any]]] | ndarray[tuple[int], dtype[signedinteger[Any] | unsignedinteger[Any]]] | Buffer | Iterable[H3Vertex | (int | integer[Any] | ndarray[tuple[()], dtype[signedinteger[Any] | unsignedinteger[Any]]]) | str]) -> H3VertexArray
```

An immutable array of H3 topological vertex ids.

Index with an integer for an `H3Vertex`; slice or mask for another
`H3VertexArray`. The id column is exposed as read-only `uint64` data.

Build an array of H3 vertices from vertex objects, ids, or tokens.

Iterables may mix index objects, integer ids, and tokens. Integer NumPy
arrays with zero or one dimension and unsigned 64-bit buffers are also
accepted. Wrap one token in a one-item iterable.
`None` is not a missing row.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `values` | `ndarray[tuple[()], dtype[signedinteger[Any] \| unsignedinteger[Any]]] \| ndarray[tuple[int], dtype[signedinteger[Any] \| unsignedinteger[Any]]] \| Buffer \| Iterable[H3Vertex \| (int \| integer[Any] \| ndarray[tuple[()], dtype[signedinteger[Any] \| unsignedinteger[Any]]]) \| str]` | An iterable of H3Vertex objects, non-negative H3 ids, and/or vertex tokens. Integer NumPy arrays and uint64 buffers must contain valid H3 vertex ids. Byte strings and byte-formatted buffers are not collections. | *required* |

Returns:

| Type | Description |
| --- | --- |
| `H3VertexArray` | An immutable array in input order with an owned, read-only `uint64` id column. |

Raises:

| Type | Description |
| --- | --- |
| `TypeError` | If a value is not an H3 vertex, integer id, or token, or if an array has unsupported dimensions. |
| `ParseError` | If an id or token does not identify a valid H3 vertex. |

### nbytes `property`

```python
nbytes: int
```

Logical id payload in bytes (`len * 8`).

Returns:

| Type | Description |
| --- | --- |
| `int` |  |

### point `property`

```python
point: GeometryArray[Point]
```

The location of every vertex.

Returns:

| Type | Description |
| --- | --- |
| `GeometryArray` | One `Point` (lon/lat, `OGC:CRS84`) per vertex. |

### token `property`

```python
token: list[str]
```

Hexadecimal token of every row.

Returns:

| Type | Description |
| --- | --- |
| `list of str` |  |

### \_\_bool\_\_

```python
__bool__() -> bool
```

`False` only when the array is empty.

Returns:

| Type | Description |
| --- | --- |
| `bool` |  |

### \_\_contains\_\_

```python
__contains__(value: object, /) -> bool
```

Whether an edge/vertex id appears in the array.

Returns:

| Type | Description |
| --- | --- |
| `bool` |  |

### \_\_getitem\_\_

Accepted call forms

```python
__getitem__(index: ndarray[tuple[()], dtype[signedinteger[Any] | unsignedinteger[Any]]], /) -> H3Vertex
```

```python
__getitem__(index: ndarray[tuple[int], dtype[signedinteger[Any] | unsignedinteger[Any]]], /) -> H3VertexArray
```

```python
__getitem__(index: ndarray[tuple[int], dtype[bool_]], /) -> H3VertexArray
```

```python
__getitem__(index: ndarray[tuple[Any, ...], dtype[signedinteger[Any] | unsignedinteger[Any]]], /) -> H3Vertex | H3VertexArray
```

```python
__getitem__(index: SupportsIndex, /) -> H3Vertex
```

```python
__getitem__(index: slice, /) -> H3VertexArray
```

```python
__getitem__(index: Sequence[bool], /) -> H3VertexArray
```

```python
__getitem__(index: Sequence[SupportsIndex] | ndarray[tuple[int], dtype[signedinteger[Any] | unsignedinteger[Any]]] | Buffer, /) -> H3VertexArray
```

```python
__getitem__(index: SupportsIndex | slice | ndarray[tuple[int], dtype[bool_]] | Sequence[bool] | (Sequence[SupportsIndex] | ndarray[tuple[int], dtype[signedinteger[Any] | unsignedinteger[Any]]] | Buffer) | ndarray[tuple[()], dtype[signedinteger[Any] | unsignedinteger[Any]]] | ndarray[tuple[int], dtype[signedinteger[Any] | unsignedinteger[Any]]] | ndarray[tuple[Any, ...], dtype[signedinteger[Any] | unsignedinteger[Any]]], /) -> H3Vertex | H3VertexArray
```

Select by integer, slice, or fancy index.

An `int` returns one edge/vertex. A `slice` or fancy index
returns an array of the same type.

Returns:

| Type | Description |
| --- | --- |
| `H3Edge or H3Vertex or H3EdgeArray or H3VertexArray` |  |

### \_\_iter\_\_

```python
__iter__() -> H3VertexArrayIterator
```

Iterate elements in row order.

Returns:

| Type | Description |
| --- | --- |
| `iterator` |  |

### \_\_len\_\_

```python
__len__() -> int
```

Number of edges or vertices.

Returns:

| Type | Description |
| --- | --- |
| `int` |  |

### \_\_reversed\_\_

```python
__reversed__() -> H3VertexArrayIterator
```

Iterate elements in reverse row order.

Returns:

| Type | Description |
| --- | --- |
| `iterator` |  |

### count

```python
count(value: object) -> int
```

Number of elements with the same id.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `value` | `H3 value or int id` | The element to count. | *required* |

Returns:

| Type | Description |
| --- | --- |
| `int` |  |

### factorize

```python
factorize() -> tuple[ndarray[tuple[int], dtype[int64]], H3VertexArray]
```

Factorize values into dense integer codes and first-seen uniques.

Returns:

| Type | Description |
| --- | --- |
| `tuple` | `(codes, unique_values)`. |

Examples:

```pycon
>>> import gometry as gm
>>> cell = gm.h3_cover(gm.Point(-122.4194, 37.7749, crs=4326), resolution=7)[0]
>>> assert cell is not None
>>> edges = cell.edges
>>> codes, unique = edges.factorize()
>>> len(codes) == len(edges)
True
```

### index

```python
index(value: object, start: int = 0, stop: int | None = None) -> int
```

First index of an equal id in `[start, stop)`.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `value` | `H3 value or int id` | The element to locate. | *required* |
| `start` | `int` | First position searched. | `0` |
| `stop` | `int` | One past the last position searched. | `None` |

Returns:

| Type | Description |
| --- | --- |
| `int` |  |

### to\_numpy

```python
to_numpy() -> NDArray[uint64]
```

Return a read-only `uint64` ndarray view of the id column.

Contiguous selections are zero-copy; gathered selections
materialize the logical id order.

Returns:

| Type | Description |
| --- | --- |
| `ndarray` |  |

Examples:

```pycon
>>> import gometry as gm
>>> cell = gm.h3_cover(gm.Point(-122.4194, 37.7749, crs=4326), resolution=7)[0]
>>> assert cell is not None
>>> edges = cell.edges
>>> type(edges.to_numpy()).__name__
'ndarray'
```

### value\_counts

```python
value_counts() -> tuple[H3VertexArray, ndarray[tuple[int], dtype[int64]]]
```

Unique values and counts, ordered by descending count, with
first appearance breaking ties.

Returns:

| Type | Description |
| --- | --- |
| `tuple` | `(unique_values, counts)` with read-only `int64` counts. |

Examples:

```pycon
>>> import gometry as gm
>>> cell = gm.h3_cover(gm.Point(-122.4194, 37.7749, crs=4326), resolution=7)[0]
>>> assert cell is not None
>>> edges = cell.edges
>>> unique, counts = edges.value_counts()
>>> counts.tolist()
[1, 1, 1, 1, 1, 1]
```

## H3Edge

Accepted call forms

```python
H3Edge(value: H3Edge | (int | integer[Any] | ndarray[tuple[()], dtype[signedinteger[Any] | unsignedinteger[Any]]]) | str) -> H3Edge
```

One directed H3 edge: the shared boundary between an origin cell and a
neighboring destination cell, with its own 64-bit H3 index.

Obtained from `H3Cell.edge` / `H3Cell.edges`; convert with
`int(edge)` or `edge.token`, and rebuild with `H3Edge(token)`.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `value` | `H3Edge \| (int \| integer[Any] \| ndarray[tuple[()], dtype[signedinteger[Any] \| unsignedinteger[Any]]]) \| str` | An existing edge, its 64-bit id, or its token.  The edge, its 64-bit id, or its token. | *required* |

One H3 directed edge from an existing `H3Edge`, a 64-bit id, or a token.

Returns:

| Type | Description |
| --- | --- |
| `H3Edge` |  |

Raises:

| Type | Description |
| --- | --- |
| `ParseError` | If `value` is not a valid H3 directed-edge id or token. |
| `TypeError` | If `value` is not an `H3Edge`, int, or str. |

### destination `property`

```python
destination: H3Cell
```

The cell this directed edge enters.

Returns:

| Type | Description |
| --- | --- |
| `H3Cell` |  |

### id `property`

```python
id: int
```

The edge's 64-bit H3 index.

Returns:

| Type | Description |
| --- | --- |
| `int` |  |

### length `property`

```python
length: float
```

Length of the edge in meters (spherical, like `H3Cell.area`).

Returns:

| Type | Description |
| --- | --- |
| `float` |  |

Examples:

```pycon
>>> import gometry as gm
>>> cell = gm.H3Cell(13.4, 52.5, resolution=7)
>>> neighbor = cell.neighbors[0]
>>> assert neighbor is not None
>>> edge = cell.edge(neighbor)
>>> 1000 < edge.length < 3000
True
```

### line `property`

```python
line: LineString
```

The edge's linework along the shared cell boundary.

Returns:

| Type | Description |
| --- | --- |
| `LineString` | Longitude/latitude line tagged `OGC:CRS84`. |

### nbytes `property`

```python
nbytes: int
```

Raw directed-edge id payload in bytes.

Returns:

| Type | Description |
| --- | --- |
| `int` |  |

### origin `property`

```python
origin: H3Cell
```

The cell this directed edge leaves.

Returns:

| Type | Description |
| --- | --- |
| `H3Cell` |  |

### token `property`

```python
token: str
```

The edge's hexadecimal token.

Returns:

| Type | Description |
| --- | --- |
| `str` |  |

### reverse

```python
reverse() -> H3Edge
```

Reverse this directed edge from `destination` back to `origin`.

Returns:

| Type | Description |
| --- | --- |
| `H3Edge` |  |

Examples:

```pycon
>>> import gometry as gm
>>> cell = gm.h3_cover(gm.Point(-122.4194, 37.7749, crs=4326), resolution=7)[0]
>>> assert cell is not None
>>> neighbor = list(cell.neighbors)[0]
>>> assert neighbor is not None
>>> edge = cell.edge(neighbor)
>>> edge.reverse().token
'137283082cffffff'
```

## H3EdgeArray

Accepted call forms

```python
H3EdgeArray(values: ndarray[tuple[()], dtype[signedinteger[Any] | unsignedinteger[Any]]] | ndarray[tuple[int], dtype[signedinteger[Any] | unsignedinteger[Any]]] | Buffer | Iterable[H3Edge | (int | integer[Any] | ndarray[tuple[()], dtype[signedinteger[Any] | unsignedinteger[Any]]]) | str]) -> H3EdgeArray
```

An immutable array of H3 directed-edge ids.

Index with an integer for an `H3Edge`; slice or mask for another
`H3EdgeArray`. The id column is exposed as read-only `uint64` data.

Build an array of H3 directed edges from edge objects, ids, or tokens.

Iterables may mix index objects, integer ids, and tokens. Integer NumPy
arrays with zero or one dimension and unsigned 64-bit buffers are also
accepted. Wrap one token in a one-item iterable.
`None` is not a missing row.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `values` | `ndarray[tuple[()], dtype[signedinteger[Any] \| unsignedinteger[Any]]] \| ndarray[tuple[int], dtype[signedinteger[Any] \| unsignedinteger[Any]]] \| Buffer \| Iterable[H3Edge \| (int \| integer[Any] \| ndarray[tuple[()], dtype[signedinteger[Any] \| unsignedinteger[Any]]]) \| str]` | An iterable of H3Edge objects, non-negative H3 ids, and/or edge tokens. Integer NumPy arrays and uint64 buffers must contain valid directed-edge ids. Byte strings and byte-formatted buffers are not collections. | *required* |

Returns:

| Type | Description |
| --- | --- |
| `H3EdgeArray` | An immutable array in input order with an owned, read-only `uint64` id column. |

Raises:

| Type | Description |
| --- | --- |
| `TypeError` | If a value is not an H3 edge, integer id, or token, or if an array has unsupported dimensions. |
| `ParseError` | If an id or token does not identify a valid H3 directed edge. |

### destination `property`

```python
destination: CellArray[H3Cell]
```

The cells these directed edges enter.

Returns:

| Type | Description |
| --- | --- |
| `CellArray` | One destination H3Cell per edge. |

### length `property`

```python
length: NDArray[float64]
```

Length of every edge in meters (spherical, like `H3Cell.area`).

Returns:

| Type | Description |
| --- | --- |
| `ndarray` | One `float64` length per edge. |

### line `property`

```python
line: GeometryArray[LineString]
```

Edge linework along each shared cell boundary.

Returns:

| Type | Description |
| --- | --- |
| `GeometryArray` | One `LineString` (lon/lat, `OGC:CRS84`) per edge. |

### nbytes `property`

```python
nbytes: int
```

Logical id payload in bytes (`len * 8`).

Returns:

| Type | Description |
| --- | --- |
| `int` |  |

### origin `property`

```python
origin: CellArray[H3Cell]
```

The cells these directed edges leave.

Returns:

| Type | Description |
| --- | --- |
| `CellArray` | One origin H3Cell per edge. |

### token `property`

```python
token: list[str]
```

Hexadecimal token of every row.

Returns:

| Type | Description |
| --- | --- |
| `list of str` |  |

### \_\_bool\_\_

```python
__bool__() -> bool
```

`False` only when the array is empty.

Returns:

| Type | Description |
| --- | --- |
| `bool` |  |

### \_\_contains\_\_

```python
__contains__(value: object, /) -> bool
```

Whether an edge/vertex id appears in the array.

Returns:

| Type | Description |
| --- | --- |
| `bool` |  |

### \_\_getitem\_\_

Accepted call forms

```python
__getitem__(index: ndarray[tuple[()], dtype[signedinteger[Any] | unsignedinteger[Any]]], /) -> H3Edge
```

```python
__getitem__(index: ndarray[tuple[int], dtype[signedinteger[Any] | unsignedinteger[Any]]], /) -> H3EdgeArray
```

```python
__getitem__(index: ndarray[tuple[int], dtype[bool_]], /) -> H3EdgeArray
```

```python
__getitem__(index: ndarray[tuple[Any, ...], dtype[signedinteger[Any] | unsignedinteger[Any]]], /) -> H3Edge | H3EdgeArray
```

```python
__getitem__(index: SupportsIndex, /) -> H3Edge
```

```python
__getitem__(index: slice, /) -> H3EdgeArray
```

```python
__getitem__(index: Sequence[bool], /) -> H3EdgeArray
```

```python
__getitem__(index: Sequence[SupportsIndex] | ndarray[tuple[int], dtype[signedinteger[Any] | unsignedinteger[Any]]] | Buffer, /) -> H3EdgeArray
```

```python
__getitem__(index: SupportsIndex | slice | ndarray[tuple[int], dtype[bool_]] | Sequence[bool] | (Sequence[SupportsIndex] | ndarray[tuple[int], dtype[signedinteger[Any] | unsignedinteger[Any]]] | Buffer) | ndarray[tuple[()], dtype[signedinteger[Any] | unsignedinteger[Any]]] | ndarray[tuple[int], dtype[signedinteger[Any] | unsignedinteger[Any]]] | ndarray[tuple[Any, ...], dtype[signedinteger[Any] | unsignedinteger[Any]]], /) -> H3Edge | H3EdgeArray
```

Select by integer, slice, or fancy index.

An `int` returns one edge/vertex. A `slice` or fancy index
returns an array of the same type.

Returns:

| Type | Description |
| --- | --- |
| `H3Edge or H3Vertex or H3EdgeArray or H3VertexArray` |  |

### \_\_iter\_\_

```python
__iter__() -> H3EdgeArrayIterator
```

Iterate elements in row order.

Returns:

| Type | Description |
| --- | --- |
| `iterator` |  |

### \_\_len\_\_

```python
__len__() -> int
```

Number of edges or vertices.

Returns:

| Type | Description |
| --- | --- |
| `int` |  |

### \_\_reversed\_\_

```python
__reversed__() -> H3EdgeArrayIterator
```

Iterate elements in reverse row order.

Returns:

| Type | Description |
| --- | --- |
| `iterator` |  |

### count

```python
count(value: object) -> int
```

Number of elements with the same id.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `value` | `H3 value or int id` | The element to count. | *required* |

Returns:

| Type | Description |
| --- | --- |
| `int` |  |

### factorize

```python
factorize() -> tuple[ndarray[tuple[int], dtype[int64]], H3EdgeArray]
```

Factorize values into dense integer codes and first-seen uniques.

Returns:

| Type | Description |
| --- | --- |
| `tuple` | `(codes, unique_values)`. |

Examples:

```pycon
>>> import gometry as gm
>>> cell = gm.h3_cover(gm.Point(-122.4194, 37.7749, crs=4326), resolution=7)[0]
>>> assert cell is not None
>>> edges = cell.edges
>>> codes, unique = edges.factorize()
>>> len(codes) == len(edges)
True
```

### index

```python
index(value: object, start: int = 0, stop: int | None = None) -> int
```

First index of an equal id in `[start, stop)`.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `value` | `H3 value or int id` | The element to locate. | *required* |
| `start` | `int` | First position searched. | `0` |
| `stop` | `int` | One past the last position searched. | `None` |

Returns:

| Type | Description |
| --- | --- |
| `int` |  |

### reverse

```python
reverse() -> H3EdgeArray
```

Reverse every directed edge from its destination back to its origin.

Returns:

| Type | Description |
| --- | --- |
| `H3EdgeArray` |  |

Examples:

```pycon
>>> import gometry as gm
>>> cell = gm.h3_cover(gm.Point(-122.4194, 37.7749, crs=4326), resolution=7)[0]
>>> assert cell is not None
>>> edges = cell.edges
>>> edges.reverse()[0].token
'1672830829ffffff'
```

### to\_numpy

```python
to_numpy() -> NDArray[uint64]
```

Return a read-only `uint64` ndarray view of the id column.

Contiguous selections are zero-copy; gathered selections
materialize the logical id order.

Returns:

| Type | Description |
| --- | --- |
| `ndarray` |  |

Examples:

```pycon
>>> import gometry as gm
>>> cell = gm.h3_cover(gm.Point(-122.4194, 37.7749, crs=4326), resolution=7)[0]
>>> assert cell is not None
>>> edges = cell.edges
>>> type(edges.to_numpy()).__name__
'ndarray'
```

### value\_counts

```python
value_counts() -> tuple[H3EdgeArray, ndarray[tuple[int], dtype[int64]]]
```

Unique values and counts, ordered by descending count, with
first appearance breaking ties.

Returns:

| Type | Description |
| --- | --- |
| `tuple` | `(unique_values, counts)` with read-only `int64` counts. |

Examples:

```pycon
>>> import gometry as gm
>>> cell = gm.h3_cover(gm.Point(-122.4194, 37.7749, crs=4326), resolution=7)[0]
>>> assert cell is not None
>>> edges = cell.edges
>>> unique, counts = edges.value_counts()
>>> counts.tolist()
[1, 1, 1, 1, 1, 1]
```

## Functions

## h3\_base\_cells

```python
h3_base_cells() -> CellArray[H3Cell]
```

Return the 122 resolution-0 H3 base cells.

Returns:

| Type | Description |
| --- | --- |
| `CellArray of H3Cell` |  |

Examples:

```pycon
>>> import gometry as gm
>>> len(gm.h3_base_cells())
122
```

## h3\_bounding\_cell

```python
h3_bounding_cell(value: Geometry | GeometryArray[Geometry | None] | Iterable[float]) -> H3Cell
```

Return the deepest single H3 cell containing a geometry or lon/lat bounds.

Walks a necessary ancestor path, then proves the complete region against
every ordered native H3 edge. Vertex ownership is not a containment proof;
when the finest candidate cannot be proved, a coarser proven ancestor is
returned.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `value` | `Geometry, GeometryArray, or sequence of float` | A geometry/array (non-WGS84 frames reproject), or a bare lon/lat `(minx, miny, maxx, maxy)` bounds. | *required* |

Returns:

| Type | Description |
| --- | --- |
| `H3Cell` | The deepest cell whose region contains the whole bounds. |

Raises:

| Type | Description |
| --- | --- |
| `InvalidGeometryError` | If the geometry is empty or coordinates leave the lon/lat domain. |
| `GeometryError` | If no single H3 cell contains the bounds, or bare bounds are not ordered min <= max. |

Examples:

```pycon
>>> import gometry as gm
>>> berlin = gm.box(13.3, 52.4, 13.5, 52.6, crs=4326)
>>> gm.h3_bounding_cell(berlin).resolution
2
```

## h3\_cells

Accepted call forms

```python
h3_cells(values: GeometryArray[Point] | Iterable[Point] | (Sequence[Sequence[float]] | ndarray[tuple[int, int], dtype[floating[Any] | signedinteger[Any] | unsignedinteger[Any] | bool_]]) | FloatInput, lat: FloatInput | None = None, *, resolution: int | integer[Any] | ndarray[tuple[()], dtype[signedinteger[Any] | unsignedinteger[Any]]] | ndarray[tuple[int], dtype[signedinteger[Any] | unsignedinteger[Any]]] | Iterable[int] | Buffer) -> CellArray[H3Cell]
```

```python
h3_cells(values: GeometryArray[Point | None] | Iterable[Point | None], lat: None = None, *, resolution: int | integer[Any] | ndarray[tuple[()], dtype[signedinteger[Any] | unsignedinteger[Any]]] | ndarray[tuple[int], dtype[signedinteger[Any] | unsignedinteger[Any]]] | Iterable[int] | Buffer) -> CellArray[H3Cell | None]
```

Build H3 cells from points, coordinate rows, or parallel lon/lat columns.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `values` | `GeometryArray of Point, iterable of Point or None, coordinate matrix, or float` | Point geometries (`None` makes a missing cell), a coordinate matrix with at least two columns, or WGS84 longitudes. Iterable points must share one CRS and epoch; projected point inputs are reprojected to WGS84. Coordinate matrices use only X and Y, ignoring extra ordinates. | *required* |
| `lat` | `float or sequence of float` | WGS84 latitude per row when `values` supplies longitudes. Coordinate columns broadcast numpy-style; at least one must be a sequence. | `None` |
| `resolution` | `int or sequence of int` | H3 resolution (0-15; finer at higher values). A scalar broadcasts to every row; an array supplies one resolution per row. | *required* |

Returns:

| Type | Description |
| --- | --- |
| `CellArray of H3Cell` | One cell per input coordinate. |

Raises:

| Type | Description |
| --- | --- |
| `GeometryError` | If `resolution` is out of range or every argument is scalar. |
| `InvalidGeometryError` | If a coordinate is non-finite or coordinate columns differ in length. |

See Also

[H3Cell](https://gometry.monicz.dev/api/h3/#gometry.H3Cell "H3Cell") : Build a single cell.
[h3\_cover](https://gometry.monicz.dev/api/h3/#gometry.h3_cover "h3_cover") : Cover a geometry with H3 cells.

Examples:

```pycon
>>> import gometry as gm
>>> cells = gm.h3_cells([-122.4, -122.3], [37.8, 37.7], resolution=7)
>>> cell = cells[0]
>>> assert cell is not None
>>> (len(cells), cell.token)
(2, '87283080cffffff')
```

## h3\_cover

Accepted call forms

```python
h3_cover(geom: GeometryArray[Geometry] | Iterable[Geometry], resolution: int, *, cell_rule: Literal['center', 'within', 'overlap', 'bbox'] = 'overlap', max_cells: int | None = 1000000) -> Groups[CellArray[H3Cell]]
```

```python
h3_cover(geom: GeometryArray[Geometry | None] | Iterable[Geometry | None], resolution: int, *, cell_rule: Literal['center', 'within', 'overlap', 'bbox'] = 'overlap', max_cells: int | None = 1000000) -> Groups[CellArray[H3Cell] | None]
```

```python
h3_cover(geom: Geometry, resolution: int, *, cell_rule: Literal['center', 'within', 'overlap', 'bbox'] = 'overlap', max_cells: int | None = 1000000) -> CellArray[H3Cell]
```

Cover a geometry with H3 cells at `resolution`.

The result is a `CellArray` of cells satisfying `cell_rule`. Keep the
source geometry separately and use the free `gm.*` predicates for exact
geometry questions.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `geom` | `Geometry, GeometryArray, or iterable of Geometry or None` | Geometry to cover (WGS84 lon/lat or projected). An array or iterable returns one group per input row; `None` produces a missing group and a present empty geometry produces an empty group. | *required* |
| `resolution` | `int` | H3 resolution (`0`-`15`; finer at higher values). | *required* |
| `cell_rule` | `('within', 'center', 'overlap', 'bbox')` | Which cells to materialize, strictest to loosest. `'within'`: only cells entirely inside — cells the area fully owns. `'center'`: cells whose center is inside — unique assignment, balanced point binning. `'overlap'`: every cell touching the geometry — a complete-coverage superset, the safe default for candidate keys. `'bbox'`: every cell meeting the geometry's envelope, one window per part and split at the antimeridian — loosest and fastest. The rule never affects the exact predicates. | `'within'` |
| `max_cells` | `int or None` | Hard cap on returned cells and retained result allocation. Discarded candidates do not consume it; array calls apply it cumulatively across groups. Pass `None` for unlimited output (bounded only by memory). | `1000000` |

Returns:

| Type | Description |
| --- | --- |
| `CellArray or Groups of CellArray` | A scalar returns its coverage; an array returns one cell group per row. |

Raises:

| Type | Description |
| --- | --- |
| `GeometryError` | If the geometry, depth, or a coverage parameter is invalid, or if the covering would exceed `max_cells`. |
| `InvalidGeometryError` | If the geometry is empty or coordinates leave the lon/lat domain. |

See Also

[h3\_cells](https://gometry.monicz.dev/api/h3/#gometry.h3_cells "h3_cells") : Build H3 cells from lon/lat columns.

Examples:

```pycon
>>> import gometry as gm
>>> p = gm.Point(-122.4194, 37.7749, crs=4326)
>>> cov = gm.h3_cover(p, resolution=7)
>>> cell = cov[0]
>>> assert cell is not None
>>> (len(cov), cell.token)
(1, '872830828ffffff')
```

## h3\_difference

```python
h3_difference(left: H3Cell | (int | integer[Any] | ndarray[tuple[()], dtype[signedinteger[Any] | unsignedinteger[Any]]]) | str | Iterable[H3Cell | (int | integer[Any] | ndarray[tuple[()], dtype[signedinteger[Any] | unsignedinteger[Any]]]) | str | None], right: H3Cell | (int | integer[Any] | ndarray[tuple[()], dtype[signedinteger[Any] | unsignedinteger[Any]]]) | str | Iterable[H3Cell | (int | integer[Any] | ndarray[tuple[()], dtype[signedinteger[Any] | unsignedinteger[Any]]]) | str | None]) -> CellArray[H3Cell]
```

Hierarchy-aware difference of two H3 cell sets.

Cells of `left` partially covered by `right` split into children
until the remainder is exact; the result is normalized in the grid's
public identity order.
This is cell-ID algebra (the `compact` contract): an H3 child's *geometry* does not nest exactly inside its parent, but its id does.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `left` | `H3Cell, int, str, or iterable of those with missing values skipped` | The two cell sets (any mix of cell objects, ids, or tokens). | *required* |
| `right` | `H3Cell, int, str, or iterable of those with missing values skipped` | The two cell sets (any mix of cell objects, ids, or tokens). | *required* |

Returns:

| Type | Description |
| --- | --- |
| `CellArray of H3Cell` |  |

Raises:

| Type | Description |
| --- | --- |
| `ParseError` | If an id or token is not a valid H3 cell. |

Examples:

```pycon
>>> import gometry as gm
>>> p = gm.Point(-122.4194, 37.7749, crs=4326)
>>> cover = gm.h3_cover(p, resolution=7)
>>> cell = cover[0]
>>> assert cell is not None
>>> neighbors = cell.neighbors
>>> nbr = neighbors[0]
>>> assert nbr is not None
>>> cells = [item for item in cover if item is not None]
>>> len(gm.h3_difference(cells + [nbr], [item for item in neighbors if item is not None][:1]))
1
```

## h3\_intersection

```python
h3_intersection(left: H3Cell | (int | integer[Any] | ndarray[tuple[()], dtype[signedinteger[Any] | unsignedinteger[Any]]]) | str | Iterable[H3Cell | (int | integer[Any] | ndarray[tuple[()], dtype[signedinteger[Any] | unsignedinteger[Any]]]) | str | None], right: H3Cell | (int | integer[Any] | ndarray[tuple[()], dtype[signedinteger[Any] | unsignedinteger[Any]]]) | str | Iterable[H3Cell | (int | integer[Any] | ndarray[tuple[()], dtype[signedinteger[Any] | unsignedinteger[Any]]]) | str | None]) -> CellArray[H3Cell]
```

Hierarchy-aware intersection of two H3 cell sets.

A cell survives where the two sets overlap; ancestor/descendant overlap
keeps the finer cell.
This is cell-ID algebra (the `compact` contract): an H3 child's *geometry* does not nest exactly inside its parent, but its id does.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `left` | `H3Cell, int, str, or iterable of those with missing values skipped` | The two cell sets (any mix of cell objects, ids, or tokens). | *required* |
| `right` | `H3Cell, int, str, or iterable of those with missing values skipped` | The two cell sets (any mix of cell objects, ids, or tokens). | *required* |

Returns:

| Type | Description |
| --- | --- |
| `CellArray of H3Cell` |  |

Raises:

| Type | Description |
| --- | --- |
| `ParseError` | If an id or token is not a valid H3 cell. |

Examples:

```pycon
>>> import gometry as gm
>>> p = gm.Point(-122.4194, 37.7749, crs=4326)
>>> cover = gm.h3_cover(p, resolution=7)
>>> cell = cover[0]
>>> assert cell is not None
>>> neighbors = cell.neighbors
>>> nbr = neighbors[0]
>>> assert nbr is not None
>>> cells = [item for item in cover if item is not None]
>>> len(gm.h3_intersection(cells + [nbr], [item for item in neighbors if item is not None][:1]))
1
```

## h3\_pentagons

```python
h3_pentagons(resolution: int) -> CellArray[H3Cell]
```

All pentagon cells at an H3 resolution (twelve per resolution).

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `resolution` | `int` | H3 resolution (`0`-`15`). | *required* |

Returns:

| Type | Description |
| --- | --- |
| `CellArray of H3Cell` |  |

Raises:

| Type | Description |
| --- | --- |
| `GeometryError` | If `resolution` is out of range. |

Examples:

```pycon
>>> import gometry as gm
>>> len(gm.h3_pentagons(7))
12
```

## h3\_union

```python
h3_union(left: H3Cell | (int | integer[Any] | ndarray[tuple[()], dtype[signedinteger[Any] | unsignedinteger[Any]]]) | str | Iterable[H3Cell | (int | integer[Any] | ndarray[tuple[()], dtype[signedinteger[Any] | unsignedinteger[Any]]]) | str | None], right: H3Cell | (int | integer[Any] | ndarray[tuple[()], dtype[signedinteger[Any] | unsignedinteger[Any]]]) | str | Iterable[H3Cell | (int | integer[Any] | ndarray[tuple[()], dtype[signedinteger[Any] | unsignedinteger[Any]]]) | str | None]) -> CellArray[H3Cell]
```

Hierarchy-aware union of two H3 cell sets.

Returns the normalized cell union in the grid's public identity
order: contained cells are absorbed by their ancestors and complete
sibling groups are merged into parents.
This is cell-ID algebra (the `compact` contract): an H3 child's *geometry* does not nest exactly inside its parent, but its id does.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `left` | `H3Cell, int, str, or iterable of those with missing values skipped` | A single cell identity or a collection on either side (any accepted mix of cell objects and identity values for this grid). | *required* |
| `right` | `H3Cell, int, str, or iterable of those with missing values skipped` | A single cell identity or a collection on either side (any accepted mix of cell objects and identity values for this grid). | *required* |

Returns:

| Type | Description |
| --- | --- |
| `CellArray of H3Cell` |  |

Raises:

| Type | Description |
| --- | --- |
| `ParseError` | If an id or token is not a valid H3 cell. |

Examples:

```pycon
>>> import gometry as gm
>>> p = gm.Point(-122.4194, 37.7749, crs=4326)
>>> cover = gm.h3_cover(p, resolution=7)
>>> cell = cover[0]
>>> assert cell is not None
>>> neighbors = cell.neighbors
>>> nbr = neighbors[0]
>>> assert nbr is not None
>>> cells = [item for item in cover if item is not None]
>>> len(gm.h3_union(cells, [item for item in neighbors if item is not None][:1]))
2
```
