|
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