Skip to content

Commit e765e8c

Browse files
committed
Make Grid.geometry_type an argument, not derived
This means that users can check the geometry type before building the geometry, which can help with resource usage in some cases.
1 parent e75e7e1 commit e765e8c

File tree

5 files changed

+38
-9
lines changed

5 files changed

+38
-9
lines changed

src/emsarray/conventions/_base.py

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@ class Grid[GridKind, Index](abc.ABC):
6262
#: The :type:`GridKind` this grid represents
6363
grid_kind: GridKind
6464

65+
#: A Shapely geometry class such as :class:`shapely.Polygon` or :class:`shapely.Point`.
66+
geometry_type: type[BaseGeometry]
67+
6568
@property
6669
@abc.abstractmethod
6770
def size(self) -> int:
@@ -87,13 +90,6 @@ def geometry(self) -> numpy.ndarray:
8790
"""
8891
return self.convention.make_geometry(self.grid_kind)
8992

90-
@cached_property
91-
def geometry_type(self) -> type[BaseGeometry]:
92-
"""
93-
A Shapely geometry class, such as :class:`shapely.Polygon` or :class:`shapely.Point`.
94-
"""
95-
return type(next(shape for shape in self.geometry if shape is not None))
96-
9793
@cached_property
9894
def strtree(self) -> STRtree:
9995
"""
@@ -2186,7 +2182,9 @@ class DimensionConvention[GridKind](Convention[GridKind, DimensionIndex[GridKind
21862182
are always defined on unique sets of dimension.
21872183
This covers most conventions.
21882184
2189-
This subclass adds the abstract property :attr:`.grid_dimensions` that subclasses must define.
2185+
This subclass adds the abstract properties
2186+
:attr:`.grid_dimensions` and :attr:`.geometry_types`
2187+
that subclasses must define.
21902188
21912189
Default implementations are provided for all abstract :class:`Grid` methods
21922190
using :class:`DimensionGrid`.
@@ -2199,6 +2197,7 @@ def grids(self) -> dict[GridKind, Grid[GridKind, DimensionIndex[GridKind]]]:
21992197
convention=self,
22002198
grid_kind=grid_kind,
22012199
dimensions=self.grid_dimensions[grid_kind],
2200+
geometry_type=self.geometry_types[grid_kind],
22022201
)
22032202
for grid_kind in self.grid_kinds
22042203
}
@@ -2222,6 +2221,21 @@ def grid_dimensions(self) -> dict[GridKind, Sequence[Hashable]]:
22222221
"""
22232222
pass
22242223

2224+
@property
2225+
@abc.abstractmethod
2226+
def geometry_types(self) -> dict[GridKind, type[BaseGeometry]]:
2227+
"""
2228+
The geometry type associated with a particular grid kind.
2229+
2230+
This is a mapping between :type:`grid kinds <GridKind>`
2231+
and shapely geometry types such as
2232+
:class:`~shapely.Polygon` and :class:`~shapely.Point`.
2233+
2234+
Users should use :attr:`Grid.geometry_type` instead of this property,
2235+
this is only used to construct the grids.
2236+
"""
2237+
pass
2238+
22252239
@property
22262240
@utils.deprecated(
22272241
"DimensionConvention.grid_shape[grid_kind] is deprecated. "

src/emsarray/conventions/arakawa_c.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,12 @@ class ArakawaC(DimensionConvention[ArakawaCGridKind]):
158158
"""
159159
grid_kinds = frozenset(ArakawaCGridKind)
160160
default_grid_kind = ArakawaCGridKind.face
161+
geometry_types = {
162+
ArakawaCGridKind.face: shapely.Polygon,
163+
ArakawaCGridKind.left: shapely.LineString,
164+
ArakawaCGridKind.back: shapely.LineString,
165+
ArakawaCGridKind.node: shapely.Point,
166+
}
161167

162168
coordinate_names: ArakawaCCoordinates
163169

src/emsarray/conventions/grid.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,10 @@ class CFGrid[Topology: CFGridTopology](DimensionConvention[CFGridKind]):
192192

193193
grid_kinds = frozenset(CFGridKind)
194194
default_grid_kind = CFGridKind.face
195+
geometry_types = {
196+
CFGridKind.face: shapely.Polygon,
197+
}
198+
195199
topology_class: type[Topology]
196200

197201
def __init__(

src/emsarray/conventions/ugrid.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1039,6 +1039,11 @@ class UGrid(DimensionConvention[UGridKind]):
10391039
"""
10401040

10411041
default_grid_kind = UGridKind.face
1042+
geometry_types = {
1043+
UGridKind.face: shapely.Polygon,
1044+
UGridKind.edge: shapely.LineString,
1045+
UGridKind.node: shapely.Point,
1046+
}
10421047

10431048
@classmethod
10441049
def check_dataset(cls, dataset: xarray.Dataset) -> int | None:

tests/conventions/test_base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ def shape(self) -> tuple[int, int]:
104104

105105
@cached_property
106106
def grids(self) -> dict[SimpleGridKind, Grid[SimpleGridKind, SimpleGridIndex]]:
107-
return {SimpleGridKind.face: SimpleGrid(self, SimpleGridKind.face)}
107+
return {SimpleGridKind.face: SimpleGrid(self, SimpleGridKind.face, Polygon)}
108108

109109
def get_grid_kind(self, data_array: xarray.DataArray) -> SimpleGridKind:
110110
if set(data_array.dims) >= {'x', 'y'}:

0 commit comments

Comments
 (0)