Skip to content

Commit b438128

Browse files
authored
Extension/datacube - added variable property (#645)
* Extension/datacube - added variable property * Extension/datacube - complied with pre-commit hooks * Extension/datacube - applied suggest changes from pr #645 * Extension/datacube - applied suggest changes from pr #645 Co-authored-by: Thomas Li Fredriksen <[email protected]>
1 parent 60c755e commit b438128

File tree

4 files changed

+133
-4
lines changed

4 files changed

+133
-4
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
for `mypy` ([#591](https://github.com/stac-utils/pystac/pull/591))
1616
- Links will get their `title` from their target if no `title` is provided ([#607](https://github.com/stac-utils/pystac/pull/607))
1717
- Relax typing on `LabelClasses` from `List` to `Sequence` ([#627](https://github.com/stac-utils/pystac/pull/627))
18+
- Upgraded datacube-extension to version 2.0.0 ([#645](https://github.com/stac-utils/pystac/pull/645))
1819

1920
### Fixed
2021

docs/api.rst

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,22 @@ AdditionalDimension
362362
:show-inheritance:
363363
:inherited-members:
364364

365+
VariableType
366+
~~~~~~~~~~~~
367+
368+
.. autoclass:: pystac.extensions.datacube.VariableType
369+
:members:
370+
:show-inheritance:
371+
:inherited-members:
372+
373+
Variable
374+
~~~~~~~~
375+
376+
.. autoclass:: pystac.extensions.datacube.Variable
377+
:members:
378+
:show-inheritance:
379+
:inherited-members:
380+
365381
DatacubeExtension
366382
~~~~~~~~~~~~~~~~~
367383

pystac/extensions/datacube.py

Lines changed: 115 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,11 @@
1717

1818
T = TypeVar("T", pystac.Collection, pystac.Item, pystac.Asset)
1919

20-
SCHEMA_URI = "https://stac-extensions.github.io/datacube/v1.0.0/schema.json"
20+
SCHEMA_URI = "https://stac-extensions.github.io/datacube/v2.0.0/schema.json"
2121

2222
PREFIX: str = "cube:"
2323
DIMENSIONS_PROP = PREFIX + "dimensions"
24+
VARIABLES_PROP = PREFIX + "variables"
2425

2526
# Dimension properties
2627
DIM_TYPE_PROP = "type"
@@ -32,6 +33,14 @@
3233
DIM_REF_SYS_PROP = "reference_system"
3334
DIM_UNIT_PROP = "unit"
3435

36+
# Variable properties
37+
VAR_TYPE_PROP = "type"
38+
VAR_DESC_PROP = "description"
39+
VAR_EXTENT_PROP = "extent"
40+
VAR_VALUES_PROP = "values"
41+
VAR_DIMENSIONS_PROP = "dimensions"
42+
VAR_UNIT_PROP = "unit"
43+
3544

3645
class DimensionType(str, Enum):
3746
"""Dimension object types for spatial and temporal Dimension Objects."""
@@ -398,6 +407,102 @@ def reference_system(self, v: Optional[Union[str, float, Dict[str, Any]]]) -> No
398407
self.properties[DIM_REF_SYS_PROP] = v
399408

400409

410+
class VariableType(str, Enum):
411+
"""Variable object types"""
412+
413+
DATA = "data"
414+
AUXILIARY = "auxiliary"
415+
416+
417+
class Variable:
418+
properties: Dict[str, Any]
419+
420+
def __init__(self, properties: Dict[str, Any]) -> None:
421+
self.properties = properties
422+
423+
@property
424+
def dimensions(self) -> List[str]:
425+
"""The dimensions of the variable. Should refer to keys in the ``cube:dimensions``
426+
object or be an empty list if the variable has no dimensions"""
427+
return get_required(
428+
self.properties.get(VAR_DIMENSIONS_PROP),
429+
"cube:variable",
430+
VAR_DIMENSIONS_PROP,
431+
)
432+
433+
@dimensions.setter
434+
def dimensions(self, v: List[str]) -> None:
435+
self.properties[VAR_DIMENSIONS_PROP] = v
436+
437+
@property
438+
def var_type(self) -> Union[VariableType, str]:
439+
"""Type of the variable, either ``data`` or ``auxiliary``"""
440+
return get_required(
441+
self.properties.get(VAR_TYPE_PROP), "cube:variable", VAR_TYPE_PROP
442+
)
443+
444+
@var_type.setter
445+
def var_type(self, v: Union[VariableType, str]) -> None:
446+
self.properties[VAR_TYPE_PROP] = v
447+
448+
@property
449+
def description(self) -> Optional[str]:
450+
"""Detailed multi-line description to explain the variable. `CommonMark 0.29
451+
<http://commonmark.org/>`__ syntax MAY be used for rich text representation."""
452+
return self.properties.get(VAR_DESC_PROP)
453+
454+
@description.setter
455+
def description(self, v: Optional[str]) -> None:
456+
if v is None:
457+
self.properties.pop(VAR_DESC_PROP, None)
458+
else:
459+
self.properties[VAR_DESC_PROP] = v
460+
461+
@property
462+
def extent(self) -> List[Union[float, str, None]]:
463+
"""If the variable consists of `ordinal values
464+
<https://en.wikipedia.org/wiki/Level_of_measurement#Ordinal_scale>`, the extent
465+
(lower and upper bounds) of the values as two-dimensional array. Use ``None``
466+
for open intervals"""
467+
return get_required(
468+
self.properties.get(VAR_EXTENT_PROP), "cube:variable", VAR_EXTENT_PROP
469+
)
470+
471+
@extent.setter
472+
def extent(self, v: List[Union[float, str, None]]) -> None:
473+
self.properties[VAR_EXTENT_PROP] = v
474+
475+
@property
476+
def values(self) -> Optional[List[Union[float, str]]]:
477+
"""A set of all potential values, especially useful for `nominal values
478+
<https://en.wikipedia.org/wiki/Level_of_measurement#Nominal_level>`."""
479+
return self.properties.get(VAR_VALUES_PROP)
480+
481+
@values.setter
482+
def values(self, v: Optional[List[Union[float, str]]]) -> None:
483+
if v is None:
484+
self.properties.pop(VAR_VALUES_PROP)
485+
else:
486+
self.properties[VAR_VALUES_PROP] = v
487+
488+
@property
489+
def unit(self) -> Optional[str]:
490+
"""The unit of measurement for the data, preferably compliant to `UDUNITS-2
491+
<https://ncics.org/portfolio/other-resources/udunits2/>` units (singular)"""
492+
return self.properties.get(VAR_UNIT_PROP)
493+
494+
@unit.setter
495+
def unit(self, v: Optional[str]) -> None:
496+
if v is None:
497+
self.properties.pop(VAR_UNIT_PROP)
498+
else:
499+
self.properties[VAR_UNIT_PROP] = v
500+
501+
@staticmethod
502+
def from_dict(d: Dict[str, Any]) -> "Variable":
503+
return Variable(d)
504+
505+
401506
class DatacubeExtension(
402507
Generic[T],
403508
PropertiesExtension,
@@ -423,8 +528,6 @@ def apply(self, dimensions: Dict[str, Dimension]) -> None:
423528
:class:`~pystac.Collection`, :class:`~pystac.Item` or :class:`~pystac.Asset`.
424529
425530
Args:
426-
bands : A list of available bands where each item is a :class:`~Band`
427-
object. If given, requires at least one band.
428531
dimensions : Dictionary mapping dimension name to a :class:`Dimension`
429532
object.
430533
"""
@@ -442,6 +545,15 @@ def dimensions(self) -> Dict[str, Dimension]:
442545
def dimensions(self, v: Dict[str, Dimension]) -> None:
443546
self._set_property(DIMENSIONS_PROP, {k: dim.to_dict() for k, dim in v.items()})
444547

548+
@property
549+
def variables(self) -> Optional[Dict[str, Variable]]:
550+
"""Dictionary mapping variable name to a :class:`Variable` object."""
551+
result = self._get_property(VARIABLES_PROP, Dict[str, Any])
552+
553+
if result is None:
554+
return None
555+
return {k: Variable.from_dict(v) for k, v in result.items()}
556+
445557
@classmethod
446558
def get_schema_uri(cls) -> str:
447559
return SCHEMA_URI

tests/data-files/datacube/item.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"stac_version": "1.0.0-rc.1",
33
"stac_extensions": [
4-
"https://stac-extensions.github.io/datacube/v1.0.0/schema.json"
4+
"https://stac-extensions.github.io/datacube/v2.0.0/schema.json"
55
],
66
"id": "datacube-123",
77
"type": "Feature",

0 commit comments

Comments
 (0)