Grids & cells¶
Grid-generic cells and the shared columnar CellArray container.
Related: Grids & geocodes
Cell
¶
One cell of a discrete global grid — the uniform surface every cell
class (H3Cell, S2Cell, ...) satisfies structurally, without
inheriting it. Annotate grid-system-agnostic code with this protocol::
import gometry as gm
def ring_area(cell: gm.Cell) -> float:
return sum(neighbor.area for neighbor in cell.neighbors)
Each system keeps its own named depth property (resolution,
level) next to this shared surface; parent/children accept
the depth positionally, defaulting to one step coarser/finer.
contains/intersects are typed to accept a cell or its token.
Numeric-id systems also accept int ids on the concrete classes; the
protocol leaves that out so token-based systems satisfy it too.
area
property
¶
area: float
Area of the cell in square meters, using its grid's area model.
H3 and S2 use an authalic sphere; geohash and tile use the WGS 84 ellipsoidal area of their lon/lat rectangle.
Returns:
| Type | Description |
|---|---|
float
|
Area in square meters. |
center
property
¶
center: Point
Cell center as a WGS 84 Point (lon/lat).
Returns:
| Type | Description |
|---|---|
Point
|
The center in longitude/latitude coordinates. |
neighbors
property
¶
neighbors: CellArray[Self]
The edge-adjacent cells at this cell's depth.
How many there are is system-specific, and can vary with position: six around an H3 hexagon but five around a pentagon, four for S2, eight for geohash away from the poles.
Returns:
| Type | Description |
|---|---|
CellArray[Self]
|
The edge-adjacent cells at the same depth. |
polygon
property
¶
polygon: Polygon
The cell as a filled WGS 84 Polygon (lon/lat).
H3 and S2 emit planar chord proxies for their true spherical edges.
Returns:
| Type | Description |
|---|---|
Polygon
|
The filled cell boundary in longitude/latitude coordinates. |
token
property
¶
token: str
The cell id in its system's canonical lowercase text form.
Returns:
| Type | Description |
|---|---|
str
|
Canonical text for this cell. |
children
¶
children(depth: int | None = None, /) -> CellArray[Self]
Child cells at a finer depth, one step finer by default.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
depth
|
int or None
|
Requested child depth; |
None
|
Returns:
| Type | Description |
|---|---|
CellArray[Self]
|
The cells at the requested depth. |
children_count
¶
children_count(depth: int | None = None, /) -> int
Count descendants at a finer depth without materializing them.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
depth
|
int or None
|
Requested child depth; |
None
|
Returns:
| Type | Description |
|---|---|
int
|
Number of cells at the requested depth. |
contains
¶
contains(other: Self | str) -> bool
Whether this cell is, or is an ancestor of, other.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
other
|
Self or str
|
A cell or its canonical token. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
Whether |
intersects
¶
intersects(other: Self | str) -> bool
Whether this cell and other share any area.
Hierarchy cells cannot partially overlap, so this holds exactly when one of the two contains the other.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
other
|
Self or str
|
A cell or its canonical token. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
Whether the two cells overlap hierarchically. |
parent
¶
parent(depth: int | None = None, /) -> Self
Parent cell at a coarser depth, one step coarser by default.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
depth
|
int or None
|
Requested parent depth; |
None
|
Returns:
| Type | Description |
|---|---|
Self
|
The ancestor at the requested depth. |
CellArray
¶
Accepted call forms
CellArray(values: Iterable[GeohashCell], *, type: None = None) -> CellArray[GeohashCell]
CellArray(values: Iterable[GeohashCell | None], *, type: None = None) -> CellArray[GeohashCell | None]
CellArray(values: Iterable[GeohashCell | str], *, type: type[GeohashCell]) -> CellArray[GeohashCell]
CellArray(values: Iterable[GeohashCell | str | None], *, type: type[GeohashCell]) -> CellArray[GeohashCell | None]
CellArray(values: ndarray[tuple[()], dtype[signedinteger[Any] | unsignedinteger[Any]]] | ndarray[tuple[int], dtype[signedinteger[Any] | unsignedinteger[Any]]] | Buffer | Iterable[H3Cell | (int | integer[Any] | ndarray[tuple[()], dtype[signedinteger[Any] | unsignedinteger[Any]]]) | str], *, type: type[H3Cell]) -> CellArray[H3Cell]
CellArray(values: Iterable[H3Cell | (int | integer[Any] | ndarray[tuple[()], dtype[signedinteger[Any] | unsignedinteger[Any]]]) | str | None], *, type: type[H3Cell]) -> CellArray[H3Cell | None]
CellArray(values: ndarray[tuple[()], dtype[signedinteger[Any] | unsignedinteger[Any]]] | ndarray[tuple[int], dtype[signedinteger[Any] | unsignedinteger[Any]]] | Buffer | Iterable[S2Cell | (int | integer[Any] | ndarray[tuple[()], dtype[signedinteger[Any] | unsignedinteger[Any]]]) | str], *, type: type[S2Cell]) -> CellArray[S2Cell]
CellArray(values: Iterable[S2Cell | (int | integer[Any] | ndarray[tuple[()], dtype[signedinteger[Any] | unsignedinteger[Any]]]) | str | None], *, type: type[S2Cell]) -> CellArray[S2Cell | None]
CellArray(values: ndarray[tuple[()], dtype[signedinteger[Any] | unsignedinteger[Any]]] | ndarray[tuple[int], dtype[signedinteger[Any] | unsignedinteger[Any]]] | Buffer | Iterable[Tile | (int | integer[Any] | ndarray[tuple[()], dtype[signedinteger[Any] | unsignedinteger[Any]]]) | str], *, type: type[Tile]) -> CellArray[Tile]
An immutable array of one grid cell type backed by a shared uint64 id
column.
Index with an integer for the typed cell object or None for a missing row;
slice or mask for a new CellArray.
Build from an iterable containing
typed cell objects and None; the grid is inferred from the first concrete
cell. Raw ids for H3, S2, and Tile and tokens for any grid may accompany a
typed cell of the same grid. Geohash cells use tokens, not integer ids. For
raw-only values, numeric arrays or buffers, empty input, or all-missing
input, pass type= explicitly; every id and token is validated.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
values
|
Iterable[H3Cell] | Iterable[S2Cell] | Iterable[GeohashCell] | Iterable[Tile] | Iterable[H3Cell | None] | Iterable[S2Cell | None] | Iterable[GeohashCell | None] | Iterable[Tile | None] | Iterable[GeohashCell | str] | Iterable[GeohashCell | str | None] | (ndarray[tuple[()], dtype[signedinteger[Any] | unsignedinteger[Any]]] | ndarray[tuple[int], dtype[signedinteger[Any] | unsignedinteger[Any]]] | Buffer | Iterable[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] | (ndarray[tuple[()], dtype[signedinteger[Any] | unsignedinteger[Any]]] | ndarray[tuple[int], dtype[signedinteger[Any] | unsignedinteger[Any]]] | Buffer | Iterable[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] | (ndarray[tuple[()], dtype[signedinteger[Any] | unsignedinteger[Any]]] | ndarray[tuple[int], dtype[signedinteger[Any] | unsignedinteger[Any]]] | Buffer | Iterable[Tile | (int | integer[Any] | ndarray[tuple[()], dtype[signedinteger[Any] | unsignedinteger[Any]]]) | str]) | Iterable[Tile | (int | integer[Any] | ndarray[tuple[()], dtype[signedinteger[Any] | unsignedinteger[Any]]]) | str | None]
|
Typed cell objects and Typed cells and |
required |
type
|
None | type[GeohashCell] | type[H3Cell] | type[S2Cell] | type[Tile]
|
Native cell class. Inferred from a concrete typed cell when present. One of the native |
varies by call form
|
Construct a cell array from typed cells, ids, or tokens.
The grid is inferred from a typed cell when type=None. H3, S2, and
Tile ids and any grid's tokens may accompany a typed cell from the same
grid; Geohash cells accept tokens, not integer ids. Supply type= for
raw-only values, numeric arrays or buffers, empty input, or input
containing only None. Wrap a single cell or supported id in an
iterable; a bare token string is ambiguous, so wrap one token in a
one-item iterable.
Returns:
| Type | Description |
|---|---|
CellArray
|
An immutable array in input order; |
Raises:
| Type | Description |
|---|---|
TypeError
|
If the grid cannot be inferred, |
ParseError
|
If an id or token is invalid for the selected grid. |
area
property
¶
area: NDArray[float64]
Cell areas in square meters, using each grid's area model.
H3 and S2 use an authalic-sphere model. Geohash and tile use the WGS 84 ellipsoidal area of their lon/lat rectangle.
Returns:
| Type | Description |
|---|---|
ndarray
|
One |
Examples:
>>> import gometry as gm
>>> arr = gm.CellArray([gm.Tile(x=0, y=0, zoom=0)])
>>> float(arr.area[0]) > 1e14
True
center
property
readonly
¶
center: GeometryArray[Point | None]
Center points of every cell, as a packed WGS84 point array.
Computes each center from its cell id and allocates a packed point coordinate column.
Returns:
| Type | Description |
|---|---|
GeometryArray
|
Dense cells yield one |
Examples:
>>> import gometry as gm
>>> arr = gm.CellArray([gm.Tile(x=0, y=0, zoom=1)])
>>> arr.center.to_wkt()[0]
'POINT (-90 42.5255643899033)'
grid
property
¶
grid: Literal['h3', 's2', 'tile', 'geohash']
Grid-system token for the stored cell type.
Returns:
| Type | Description |
|---|---|
str
|
|
is_missing
property
¶
is_missing: NDArray[bool_]
Per-row missing mask as a read-only boolean NumPy array.
Bulk cell factories set a missing row when the corresponding geometry
was missing; dense constructions return all-False.
Returns:
| Type | Description |
|---|---|
numpy.ndarray of bool
|
|
neighbors
property
readonly
¶
neighbors: Groups[CellArray[Cell] | None]
The edge-adjacent cells of every cell, as ragged rows.
Returns:
| Type | Description |
|---|---|
Groups of CellArray
|
One row of neighbors per input cell, in input order. Neighbor
counts vary, so the result is a Groups, not a rectangular
CellArray. Missing input rows yield |
polygon
property
readonly
¶
polygon: GeometryArray[Polygon | None]
Filled WGS84 polygon of every cell, as a geometry array.
Returns:
| Type | Description |
|---|---|
GeometryArray
|
Dense cells yield one polygon per row. Missing rows in a nullable
|
token
property
readonly
¶
token: list[str] | list[str | None]
Canonical string token of every cell, in order.
For H3, S2, and tiles this is the text form of the numeric id exposed
by to_numpy(). For Geohash it is the public string identity itself;
Geohash to_numpy() instead returns typed GeohashCell objects.
Returns:
| Type | Description |
|---|---|
list of str or None
|
One canonical token per logical row (H3 hex, S2 token, geohash, or
tile quadkey); |
Examples:
>>> import gometry as gm
>>> gm.CellArray([gm.GeohashCell('u33d')]).token
['u33d']
__contains__
¶
__contains__(value: object, /) -> bool
Whether a cell id / cell object appears in the array.
Returns:
| Type | Description |
|---|---|
bool
|
|
__getitem__
¶
Accepted call forms
__getitem__(index: ndarray[tuple[()], dtype[signedinteger[Any] | unsignedinteger[Any]]], /) -> CellT_co
__getitem__(index: ndarray[tuple[int], dtype[signedinteger[Any] | unsignedinteger[Any]]], /) -> CellArray[CellT_co]
__getitem__(index: ndarray[tuple[int], dtype[bool_]], /) -> CellArray[CellT_co]
__getitem__(index: ndarray[tuple[Any, ...], dtype[signedinteger[Any] | unsignedinteger[Any]]], /) -> CellT_co | CellArray[CellT_co]
__getitem__(index: SupportsIndex, /) -> CellT_co
__getitem__(index: slice, /) -> CellArray[CellT_co]
__getitem__(index: Sequence[bool], /) -> CellArray[CellT_co]
__getitem__(index: Sequence[SupportsIndex] | ndarray[tuple[int], dtype[signedinteger[Any] | unsignedinteger[Any]]] | Buffer, /) -> CellArray[CellT_co]
__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]]], /) -> CellT_co | CellArray[CellT_co]
Select logical rows by integer, slice, or fancy index.
An int returns one cell object or None for a missing row. A
slice or fancy index returns a CellArray of the same cell kind.
Returns:
| Type | Description |
|---|---|
Cell, None, or CellArray
|
|
__iter__
¶
__iter__() -> CellArrayIterator[CellT_co]
Iterate logical rows in row order, yielding cells or None.
Returns:
| Type | Description |
|---|---|
iterator of Cell or None
|
|
__len__
¶
__len__() -> int
Number of logical rows, including missing rows.
Returns:
| Type | Description |
|---|---|
int
|
|
__reversed__
¶
__reversed__() -> CellArrayIterator[CellT_co]
Iterate cells in reverse row order.
Returns:
| Type | Description |
|---|---|
iterator of Cell
|
|
children
¶
Accepted call forms
Return the child cells of every cell at a finer depth, as ragged rows.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
depth
|
int
|
Target depth; must not be coarser than any input cell. Defaults to one finer than each cell's own depth. |
None
|
Returns:
| Type | Description |
|---|---|
Groups of CellArray
|
One row of children per input cell, in input order. Missing input
rows yield |
Examples:
>>> import gometry as gm
>>> p = gm.Point(-122.4194, 37.7749, crs=4326)
>>> cell = gm.h3_cover(p, resolution=7)[0]
>>> assert cell is not None
>>> children = gm.CellArray([cell]).children(8)[0]
>>> assert children is not None
>>> len(children)
7
children_count
¶
children_count(depth: int | None = None, /) -> NDArray[float64]
Number of descendant cells each cell has at depth.
The columnar mirror of the scalar children_count — the count only,
without materializing the children (which children does, as ragged
rows). Present-row counts are integer-valued but are represented as
float64; they are exact only when within float64's integer precision.
Missing rows are represented by NaN to preserve row alignment.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
depth
|
int
|
Target depth (resolution / level / precision / zoom). Omitted means one step finer than each cell. |
None
|
Returns:
| Type | Description |
|---|---|
ndarray
|
Read-only |
Raises:
| Type | Description |
|---|---|
GeometryError
|
If |
See Also
children : The descendant cells themselves, as ragged rows.
Examples:
>>> import gometry as gm
>>> p = gm.Point(-122.4194, 37.7749, crs=4326)
>>> cell = gm.h3_cover(p, resolution=7)[0]
>>> assert cell is not None
>>> neighbor = list(cell.neighbors)[0]
>>> assert neighbor is not None
>>> cells = gm.CellArray([cell, neighbor])
>>> cells.children_count(9).tolist()
[49.0, 49.0]
compact
¶
compact(depth: int | None = None, /) -> CellArray[CellT]
Compact this cell set to the coarsest exact covering, returned in the
grid's public identity order. Duplicates and descendants are absorbed;
complete sibling groups merge recursively, stopping at depth.
Missing rows are skipped; this is a set operation over present cells.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
depth
|
int
|
Coarsest depth allowed. |
None
|
Returns:
| Type | Description |
|---|---|
CellArray
|
|
Examples:
>>> import gometry as gm
>>> p = gm.Point(-122.4194, 37.7749, crs=4326)
>>> cell = gm.h3_cover(p, resolution=7)[0]
>>> assert cell is not None
>>> neighbor = list(cell.neighbors)[0]
>>> assert neighbor is not None
>>> cells = gm.CellArray([cell, neighbor])
>>> len(cells.compact(5))
2
contains
¶
Accepted call forms
contains(other: H3Cell | (int | integer[Any] | ndarray[tuple[()], dtype[signedinteger[Any] | unsignedinteger[Any]]]) | str | CellArray[H3Cell | None]) -> NDArray[bool_]
contains(other: S2Cell | (int | integer[Any] | ndarray[tuple[()], dtype[signedinteger[Any] | unsignedinteger[Any]]]) | str | CellArray[S2Cell | None]) -> NDArray[bool_]
contains(other: GeohashCell | str | CellArray[GeohashCell | None]) -> NDArray[bool_]
Test whether every row hierarchically contains the paired cell.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
other
|
same-grid cell, integer id, string token, or CellArray
|
One identity broadcast to every row, or a same-length array. |
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
One read-only boolean per row. |
Examples:
>>> import gometry as gm
>>> p = gm.Point(-122.4194, 37.7749, crs=4326)
>>> cell = gm.h3_cover(p, resolution=7)[0]
>>> assert cell is not None
>>> neighbor = list(cell.neighbors)[0]
>>> assert neighbor is not None
>>> gm.CellArray([cell, neighbor]).contains(cell).tolist()
[True, False]
count
¶
count(value: object) -> int
Number of elements with the same cell id.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
value
|
cell object or int id
|
The element to count. |
required |
Returns:
| Type | Description |
|---|---|
int
|
|
factorize
¶
factorize() -> tuple[ndarray[tuple[int], dtype[int64]], CellArray[CellT]]
Factorize cells into dense integer codes and first-seen uniques (pandas factorize parity).
Returns:
| Type | Description |
|---|---|
tuple
|
|
Examples:
>>> import gometry as gm
>>> p = gm.Point(-122.4194, 37.7749, crs=4326)
>>> cell = gm.h3_cover(p, resolution=7)[0]
>>> assert cell is not None
>>> neighbor = list(cell.neighbors)[0]
>>> assert neighbor is not None
>>> codes, unique = gm.CellArray([cell, neighbor]).factorize()
>>> codes.tolist()
[0, 1]
index
¶
index(value: object, start: int = 0, stop: int | None = None) -> int
First index of an equal cell id in [start, stop).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
value
|
cell object or int id
|
The element to locate. |
required |
start
|
int
|
First position searched. |
0
|
stop
|
int
|
One past the last position searched (the array length when omitted). |
None
|
Returns:
| Type | Description |
|---|---|
int
|
The first matching position. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If no element in the window equals |
intersects
¶
Accepted call forms
intersects(other: H3Cell | (int | integer[Any] | ndarray[tuple[()], dtype[signedinteger[Any] | unsignedinteger[Any]]]) | str | CellArray[H3Cell | None]) -> NDArray[bool_]
intersects(other: S2Cell | (int | integer[Any] | ndarray[tuple[()], dtype[signedinteger[Any] | unsignedinteger[Any]]]) | str | CellArray[S2Cell | None]) -> NDArray[bool_]
intersects(other: GeohashCell | str | CellArray[GeohashCell | None]) -> NDArray[bool_]
Test whether every row hierarchically intersects the paired cell.
Two cells intersect when either is an ancestor of the other.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
other
|
same-grid cell, integer id, string token, or CellArray
|
One identity broadcast to every row, or a same-length array. |
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
One read-only boolean per row. |
Examples:
>>> import gometry as gm
>>> p = gm.Point(-122.4194, 37.7749, crs=4326)
>>> cell = gm.h3_cover(p, resolution=7)[0]
>>> assert cell is not None
>>> neighbor = list(cell.neighbors)[0]
>>> assert neighbor is not None
>>> gm.CellArray([cell, neighbor]).intersects(cell).tolist()
[True, False]
parent
¶
parent(depth: int | None = None, /) -> CellArray[CellT_co]
Parent cell of every input cell.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
depth
|
int
|
Target depth; defaults to one coarser than each row. |
None
|
Returns:
| Type | Description |
|---|---|
CellArray
|
|
Examples:
>>> import gometry as gm
>>> p = gm.Point(-122.4194, 37.7749, crs=4326)
>>> cell = gm.h3_cover(p, resolution=7)[0]
>>> assert cell is not None
>>> neighbor = list(cell.neighbors)[0]
>>> assert neighbor is not None
>>> cells = gm.CellArray([cell, neighbor])
>>> parent = cells.parent(6)[0]
>>> assert parent is not None
>>> parent.token
'86283082fffffff'
to_numpy
¶
Accepted call forms
to_numpy() -> NDArray[object_]
to_numpy() -> NDArray[uint64]
to_numpy() -> NDArray[uint64] | NDArray[object_]
Return a read-only NumPy identity column.
H3, S2, and tile arrays expose their validated ids as uint64 (zero-copy for contiguous selections). Geohash has no public numeric id, so it returns an object array of typed GeohashCell values.
Returns:
| Type | Description |
|---|---|
ndarray
|
|
Examples:
>>> import gometry as gm
>>> p = gm.Point(-122.4194, 37.7749, crs=4326)
>>> cell = gm.h3_cover(p, resolution=7)[0]
>>> assert cell is not None
>>> type(gm.CellArray([cell]).to_numpy()).__name__
'ndarray'
to_polygon
¶
to_polygon() -> Polygon | MultiPolygon
Dissolve this cell set into one WGS 84 longitude/latitude outline. Missing rows are skipped; this is a set operation over present cells. A seam-crossing outline preserves support on both sides of ±180° rather than filling through the map's middle; its chart-cut edge is not part of the represented cell boundary.
Returns:
| Type | Description |
|---|---|
Polygon or MultiPolygon
|
|
Examples:
>>> import gometry as gm
>>> p = gm.Point(-122.4194, 37.7749, crs=4326)
>>> cell = gm.h3_cover(p, resolution=7)[0]
>>> assert cell is not None
>>> gm.CellArray([cell]).to_polygon().geometry_type
'Polygon'
uncompact
¶
uncompact(depth: int, /) -> CellArray[CellT]
Expand this cell set to a uniform depth, returned in the grid's public identity order. Expansion is bounded only by checked size arithmetic and allocator capacity; it has no fixed cell-count limit. Missing rows are skipped; this is a set operation over present cells.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
depth
|
int
|
Target depth; no coarser than any row. |
required |
Returns:
| Type | Description |
|---|---|
CellArray
|
|
Examples:
>>> import gometry as gm
>>> p = gm.Point(-122.4194, 37.7749, crs=4326)
>>> cell = gm.h3_cover(p, resolution=7)[0]
>>> assert cell is not None
>>> len(gm.CellArray([cell]).uncompact(8))
7
value_counts
¶
value_counts() -> tuple[CellArray[CellT], ndarray[tuple[int], dtype[int64]]]
Unique cells and counts, ordered by descending count (pandas value_counts parity), with first appearance breaking ties.
Returns:
| Type | Description |
|---|---|
tuple
|
|
Examples:
>>> import gometry as gm
>>> p = gm.Point(-122.4194, 37.7749, crs=4326)
>>> cell = gm.h3_cover(p, resolution=7)[0]
>>> assert cell is not None
>>> unique, counts = gm.CellArray([cell, cell]).value_counts()
>>> counts.tolist()
[2]