|
15 | 15 | "T", pystac.Collection, pystac.Item, pystac.Asset, item_assets.AssetDefinition |
16 | 16 | ) |
17 | 17 |
|
18 | | -SCHEMA_URI = "https://stac-extensions.github.io/datacube/v2.0.0/schema.json" |
| 18 | +SCHEMA_URI = "https://stac-extensions.github.io/datacube/v2.2.0/schema.json" |
19 | 19 |
|
20 | 20 | PREFIX: str = "cube:" |
21 | 21 | DIMENSIONS_PROP = PREFIX + "dimensions" |
@@ -44,6 +44,7 @@ class DimensionType(StringEnum): |
44 | 44 | """Dimension object types for spatial and temporal Dimension Objects.""" |
45 | 45 |
|
46 | 46 | SPATIAL = "spatial" |
| 47 | + GEOMETRIES = "geometries" |
47 | 48 | TEMPORAL = "temporal" |
48 | 49 |
|
49 | 50 |
|
@@ -75,12 +76,16 @@ def __init__(self, properties: dict[str, Any]) -> None: |
75 | 76 |
|
76 | 77 | @property |
77 | 78 | def dim_type(self) -> DimensionType | str: |
78 | | - """The type of the dimension. Must be ``"spatial"`` for :stac-ext:`Horizontal |
79 | | - Spatial Dimension Objects <datacube#horizontal-spatial-dimension-object>` or |
| 79 | + """The type of the dimension. Must be ``"spatial"`` for |
| 80 | + :stac-ext:`Horizontal Spatial Dimension Objects |
| 81 | + <datacube#horizontal-raster-spatial-dimension-object>` or |
80 | 82 | :stac-ext:`Vertical Spatial Dimension Objects |
81 | | - <datacube#vertical-spatial-dimension-object>`, and ``"temporal"`` for |
82 | | - :stac-ext:`Temporal Dimension Objects <datacube#temporal-dimension-object>`. May |
83 | | - be an arbitrary string for :stac-ext:`Additional Dimension Objects |
| 83 | + <datacube#vertical-spatial-dimension-object>`, ``geometries`` for |
| 84 | + :stac-ext:`Spatial Vector Dimension Objects |
| 85 | + <datacube#spatial-vector-dimension-object>` ``"temporal"`` for |
| 86 | + :stac-ext:`Temporal Dimension Objects |
| 87 | + <datacube#temporal-dimension-object>`. May be an arbitrary string for |
| 88 | + :stac-ext:`Additional Dimension Objects |
84 | 89 | <datacube#additional-dimension-object>`.""" |
85 | 90 | return get_required( |
86 | 91 | self.properties.get(DIM_TYPE_PROP), "cube:dimension", DIM_TYPE_PROP |
@@ -119,6 +124,8 @@ def from_dict(d: dict[str, Any]) -> Dimension: |
119 | 124 | return VerticalSpatialDimension(d) |
120 | 125 | else: |
121 | 126 | return HorizontalSpatialDimension(d) |
| 127 | + elif dim_type == DimensionType.GEOMETRIES: |
| 128 | + return VectorSpatialDimension(d) |
122 | 129 | elif dim_type == DimensionType.TEMPORAL: |
123 | 130 | # The v1.0.0 spec says that AdditionalDimensions can have |
124 | 131 | # type 'temporal', but it is unclear how to differentiate that |
@@ -225,6 +232,68 @@ def unit(self, v: str | None) -> None: |
225 | 232 | self.properties[DIM_UNIT_PROP] = v |
226 | 233 |
|
227 | 234 |
|
| 235 | +class VectorSpatialDimension(Dimension): |
| 236 | + @property |
| 237 | + def axes(self) -> list[str] | None: |
| 238 | + """Axes of the vector dimension as an ordered set of `x`, `y` and `z`.""" |
| 239 | + return self.properties.get("axes") |
| 240 | + |
| 241 | + @axes.setter |
| 242 | + def axes(self, v: list[str]) -> None: |
| 243 | + if v is None: |
| 244 | + self.properties.pop("axes", None) |
| 245 | + else: |
| 246 | + self.properties["axes"] = v |
| 247 | + |
| 248 | + @property |
| 249 | + def bbox(self) -> list[float]: |
| 250 | + """A single bounding box of the geometries as defined for STAC |
| 251 | + Collections but not nested.""" |
| 252 | + return get_required(self.properties.get("bbox"), "cube:bbox", "bbox") |
| 253 | + |
| 254 | + @bbox.setter |
| 255 | + def bbox(self, v: list[float]) -> None: |
| 256 | + self.properties["bbox"] = v |
| 257 | + |
| 258 | + @property |
| 259 | + def values(self) -> list[str] | None: |
| 260 | + """Optionally, a representation of the geometries. This could be a list |
| 261 | + of WKT strings or other identifiers.""" |
| 262 | + return self.properties.get(DIM_VALUES_PROP) |
| 263 | + |
| 264 | + @values.setter |
| 265 | + def values(self, v: list[str] | None) -> None: |
| 266 | + if v is None: |
| 267 | + self.properties.pop(DIM_VALUES_PROP, None) |
| 268 | + else: |
| 269 | + self.properties[DIM_VALUES_PROP] = v |
| 270 | + |
| 271 | + @property |
| 272 | + def geometry_types(self) -> list[str] | None: |
| 273 | + """A set of geometry types. If not present, mixed geometry types must be |
| 274 | + assumed.""" |
| 275 | + return self.properties.get("geometry_types") |
| 276 | + |
| 277 | + @geometry_types.setter |
| 278 | + def geometry_types(self, v: list[str] | None) -> None: |
| 279 | + if v is None: |
| 280 | + self.properties.pop("geometry_types", None) |
| 281 | + else: |
| 282 | + self.properties["geometry_types"] = v |
| 283 | + |
| 284 | + @property |
| 285 | + def reference_system(self) -> str | float | dict[str, Any] | None: |
| 286 | + """The reference system for the data.""" |
| 287 | + return self.properties.get(DIM_REF_SYS_PROP) |
| 288 | + |
| 289 | + @reference_system.setter |
| 290 | + def reference_system(self, v: str | float | dict[str, Any] | None) -> None: |
| 291 | + if v is None: |
| 292 | + self.properties.pop(DIM_REF_SYS_PROP, None) |
| 293 | + else: |
| 294 | + self.properties[DIM_REF_SYS_PROP] = v |
| 295 | + |
| 296 | + |
228 | 297 | class TemporalDimension(Dimension): |
229 | 298 | @property |
230 | 299 | def extent(self) -> list[str | None] | None: |
@@ -636,6 +705,8 @@ class DatacubeExtensionHooks(ExtensionHooks): |
636 | 705 | prev_extension_ids = { |
637 | 706 | "datacube", |
638 | 707 | "https://stac-extensions.github.io/datacube/v1.0.0/schema.json", |
| 708 | + "https://stac-extensions.github.io/datacube/v2.0.0/schema.json", |
| 709 | + "https://stac-extensions.github.io/datacube/v2.1.0/schema.json", |
639 | 710 | } |
640 | 711 | stac_object_types = { |
641 | 712 | pystac.STACObjectType.COLLECTION, |
|
0 commit comments