S2¶
S2 spherical cells, fixed-level and adaptive covers, and hierarchical cell sets.
Related: Grid-generic API
Types¶
S2Cell
¶
Accepted call forms
One S2 cell: a level-addressed quadrilateral tile on the sphere.
Wraps the 64-bit cell id with typed accessors (cell.level,
cell.token, cell.polygon, cell.center) and hierarchy
moves (parent/children/neighbors). Convert via
S2Cell(...), and back with int(cell).
One S2 cell from an id, token, lon/lat pair, or point geometry.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
value
|
S2Cell | (int | integer[Any] | ndarray[tuple[()], dtype[signedinteger[Any] | unsignedinteger[Any]]]) | str | Point | (FloatScalar | ScalarFloatArray)
|
An existing cell, id, token, longitude of a |
required |
level
|
int | integer[Any]
|
S2 level ( |
varies by call form
|
lat
|
FloatScalar | ScalarFloatArray
|
Latitude when |
varies by call form
|
Returns:
| Type | Description |
|---|---|
S2Cell
|
|
Raises:
| Type | Description |
|---|---|
ParseError
|
If |
GeometryError
|
If |
InvalidGeometryError
|
If a scalar coordinate is non-finite or out of range. |
children
¶
Child cells at a finer level.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
level
|
int
|
Target level; must not be coarser than this cell's. Defaults to one finer than this cell's level; a maximum-depth cell has no children and yields an empty CellArray. |
None
|
Returns:
| Type | Description |
|---|---|
CellArray of S2Cell
|
The descendant cells in the grid's public identity order. |
Raises:
| Type | Description |
|---|---|
GeometryError
|
If the target depth is invalid for this cell. |
Examples:
>>> import gometry as gm
>>> cell = gm.s2_cover(gm.Point(-122.4194, 37.7749, crs=4326), level=12)[0]
>>> assert cell is not None
>>> len(cell.children(13))
4
children_count
¶
children_count(level: int | None = None) -> int
Number of descendant cells at a finer level, counted closed-form without materializing them.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
level
|
int
|
Target level; must not be coarser than this cell's.
Defaults to one finer than this cell's level;
a maximum-depth cell has no children and returns |
None
|
Returns:
| Type | Description |
|---|---|
int
|
The exact descendant count. |
Raises:
| Type | Description |
|---|---|
GeometryError
|
If the target depth is coarser than this cell's, or invalid. |
Examples:
>>> import gometry as gm
>>> cell = gm.s2_cover(gm.Point(-122.4194, 37.7749, crs=4326), level=12)[0]
>>> assert cell is not None
>>> cell.children_count(13)
4
parent
¶
parent(level: int | None = None) -> S2Cell
Parent cell at a coarser level.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
level
|
int
|
Target level; must not be finer than this cell's. Defaults to one coarser than this cell's level. |
None
|
Returns:
| Type | Description |
|---|---|
S2Cell
|
The ancestor cell. |
Raises:
| Type | Description |
|---|---|
GeometryError
|
If the target depth is invalid for this cell. |
Examples:
>>> import gometry as gm
>>> cell = gm.s2_cover(gm.Point(-122.4194, 37.7749, crs=4326), level=12)[0]
>>> assert cell is not None
>>> cell.parent(10).token
'808581'
Functions¶
s2_bounding_cell
¶
s2_bounding_cell(value: Geometry | GeometryArray[Geometry | None] | Iterable[float]) -> S2Cell
Return the deepest S2 cell that provably contains a geometry's lon/lat bounding box.
Sibling-consistent with geohash_bounding_cell / tile_bounding_cell /
h3_bounding_cell: non-point inputs collapse to their lon/lat envelope,
then the deepest cell that can be proven to cover that rectangle is returned.
Near cell boundaries the result may be one level coarser than the theoretical
deepest (always containing). A single point yields its exact level-30 leaf;
a multipoint uses its bounding box (same path as any multi-vertex region —
not a leaf-LCA of the vertices alone). Regions that span multiple cube faces
have no single containing cell and raise.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
value
|
Geometry, GeometryArray, or sequence of float
|
A geometry/array (non-WGS84 frames reproject), or a bare lon/lat
|
required |
Returns:
| Type | Description |
|---|---|
S2Cell
|
The deepest cell that provably contains the geometry's bounding box; near boundaries may be coarser than theoretical deepest (always containing). |
Raises:
| Type | Description |
|---|---|
InvalidGeometryError
|
If the geometry is empty or coordinates leave the lon/lat domain. |
GeometryError
|
If no single S2 cell contains the bounds, or bare bounds are not ordered min <= max. |
Examples:
>>> import gometry as gm
>>> berlin = gm.box(13.3, 52.4, 13.5, 52.6, crs=4326)
>>> gm.s2_bounding_cell(berlin).level
8
s2_cells
¶
Accepted call forms
s2_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, *, level: int | integer[Any] | ndarray[tuple[()], dtype[signedinteger[Any] | unsignedinteger[Any]]] | ndarray[tuple[int], dtype[signedinteger[Any] | unsignedinteger[Any]]] | Iterable[int] | Buffer) -> CellArray[S2Cell]
s2_cells(values: GeometryArray[Point | None] | Iterable[Point | None], lat: None = None, *, level: int | integer[Any] | ndarray[tuple[()], dtype[signedinteger[Any] | unsignedinteger[Any]]] | ndarray[tuple[int], dtype[signedinteger[Any] | unsignedinteger[Any]]] | Iterable[int] | Buffer) -> CellArray[S2Cell | None]
Build S2 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 ( |
required |
lat
|
float or sequence of float
|
WGS84 latitude per row when |
None
|
level
|
int or sequence of int
|
S2 cell level (0-30; finer at higher values). A scalar broadcasts to every row; an array supplies one level per row. |
required |
Returns:
| Type | Description |
|---|---|
CellArray of S2Cell
|
One cell per input coordinate. |
Raises:
| Type | Description |
|---|---|
GeometryError
|
If |
InvalidGeometryError
|
If a coordinate is non-finite or columns differ in length. |
Examples:
>>> import gometry as gm
>>> len(gm.s2_cells([21.0, 22.0], [52.0, 53.0], level=10))
2
s2_cover
¶
Accepted call forms
s2_cover(geom: GeometryArray[Geometry] | Iterable[Geometry], level: int | None = None, *, target_cells: int = 8, min_level: int | None = None, max_level: int | None = None, level_mod: Literal[1, 2, 3] = 1, cell_rule: Literal['center', 'within', 'overlap', 'bbox'] = 'overlap', max_cells: int | None = 1000000) -> Groups[CellArray[S2Cell]]
s2_cover(geom: GeometryArray[Geometry | None] | Iterable[Geometry | None], level: int | None = None, *, target_cells: int = 8, min_level: int | None = None, max_level: int | None = None, level_mod: Literal[1, 2, 3] = 1, cell_rule: Literal['center', 'within', 'overlap', 'bbox'] = 'overlap', max_cells: int | None = 1000000) -> Groups[CellArray[S2Cell] | None]
Cover a geometry with fixed-level or adaptively refined S2 cells.
Omit level to adapt refinement to target_cells and the optional
level range. Supplying level fixes the output depth; non-default
adaptive controls cannot be combined with it. 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; |
required |
level
|
int
|
Fixed S2 cell level ( |
None
|
target_cells
|
int
|
Approximate adaptive refinement target; the minimum admissible cover can exceed this value. |
8
|
min_level
|
int or None
|
Coarsest adaptive S2 level allowed; omission uses level |
None
|
max_level
|
int or None
|
Finest adaptive S2 level allowed; omission uses level |
None
|
level_mod
|
(1, 2, 3)
|
Restrict adaptive output levels to increments from |
1
|
cell_rule
|
('within', 'center', 'overlap', 'bbox')
|
Which cells to materialize, strictest to loosest. |
'within'
|
max_cells
|
int or None
|
Hard cap on returned cells, applied cumulatively across array groups.
In fixed-level mode an insufficient cap raises; adaptive mode may
coarsen only within its requested level range. Pass |
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, level, or a coverage parameter is invalid, if fixed
and non-default adaptive controls are combined, or if the cover exceeds
|
InvalidGeometryError
|
If a scalar geometry is empty or coordinates leave the lon/lat domain. |
See Also
s2_cells : Build S2 cells from lon/lat columns. s2_cover : Cover with fixed or adaptive levels.
Examples:
>>> import gometry as gm
>>> p = gm.Point(-122.4194, 37.7749, crs=4326)
>>> cov = gm.s2_cover(p, level=12)
>>> cell = cov[0]
>>> assert cell is not None
>>> (len(cov), cell.token)
(1, '8085809')
s2_difference
¶
s2_difference(left: S2Cell | (int | integer[Any] | ndarray[tuple[()], dtype[signedinteger[Any] | unsignedinteger[Any]]]) | str | Iterable[S2Cell | (int | integer[Any] | ndarray[tuple[()], dtype[signedinteger[Any] | unsignedinteger[Any]]]) | str | None], right: S2Cell | (int | integer[Any] | ndarray[tuple[()], dtype[signedinteger[Any] | unsignedinteger[Any]]]) | str | Iterable[S2Cell | (int | integer[Any] | ndarray[tuple[()], dtype[signedinteger[Any] | unsignedinteger[Any]]]) | str | None]) -> CellArray[S2Cell]
Hierarchy-aware difference of two S2 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.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
left
|
S2Cell, int, str, or iterable of those with missing values skipped
|
The two cell sets (any mix of cell objects, ids, or tokens). |
required |
right
|
S2Cell, 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 S2Cell
|
|
Raises:
| Type | Description |
|---|---|
ParseError
|
If an id or token is not a valid S2 cell. |
Examples:
>>> import gometry as gm
>>> p = gm.Point(-122.4194, 37.7749, crs=4326)
>>> cells = [cell for cell in gm.s2_cover(p, level=12) if cell is not None]
>>> len(gm.s2_difference(cells, []))
1
s2_intersection
¶
s2_intersection(left: S2Cell | (int | integer[Any] | ndarray[tuple[()], dtype[signedinteger[Any] | unsignedinteger[Any]]]) | str | Iterable[S2Cell | (int | integer[Any] | ndarray[tuple[()], dtype[signedinteger[Any] | unsignedinteger[Any]]]) | str | None], right: S2Cell | (int | integer[Any] | ndarray[tuple[()], dtype[signedinteger[Any] | unsignedinteger[Any]]]) | str | Iterable[S2Cell | (int | integer[Any] | ndarray[tuple[()], dtype[signedinteger[Any] | unsignedinteger[Any]]]) | str | None]) -> CellArray[S2Cell]
Hierarchy-aware intersection of two S2 cell sets.
A cell survives where the two sets overlap; ancestor/descendant overlap keeps the finer cell.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
left
|
S2Cell, int, str, or iterable of those with missing values skipped
|
The two cell sets (any mix of cell objects, ids, or tokens). |
required |
right
|
S2Cell, 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 S2Cell
|
|
Raises:
| Type | Description |
|---|---|
ParseError
|
If an id or token is not a valid S2 cell. |
Examples:
>>> import gometry as gm
>>> p = gm.Point(-122.4194, 37.7749, crs=4326)
>>> cells = [cell for cell in gm.s2_cover(p, level=12) if cell is not None]
>>> len(gm.s2_intersection(cells, cells))
1
s2_union
¶
s2_union(left: S2Cell | (int | integer[Any] | ndarray[tuple[()], dtype[signedinteger[Any] | unsignedinteger[Any]]]) | str | Iterable[S2Cell | (int | integer[Any] | ndarray[tuple[()], dtype[signedinteger[Any] | unsignedinteger[Any]]]) | str | None], right: S2Cell | (int | integer[Any] | ndarray[tuple[()], dtype[signedinteger[Any] | unsignedinteger[Any]]]) | str | Iterable[S2Cell | (int | integer[Any] | ndarray[tuple[()], dtype[signedinteger[Any] | unsignedinteger[Any]]]) | str | None]) -> CellArray[S2Cell]
Hierarchy-aware union of two S2 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.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
left
|
S2Cell, 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
|
S2Cell, 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 S2Cell
|
|
Raises:
| Type | Description |
|---|---|
ParseError
|
If an id or token is not a valid S2 cell. |
Examples:
>>> import gometry as gm
>>> p = gm.Point(-122.4194, 37.7749, crs=4326)
>>> cells = [cell for cell in gm.s2_cover(p, level=12) if cell is not None]
>>> len(gm.s2_union(cells, cells))
1