17
17
18
18
T = TypeVar ("T" , pystac .Collection , pystac .Item , pystac .Asset )
19
19
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"
21
21
22
22
PREFIX : str = "cube:"
23
23
DIMENSIONS_PROP = PREFIX + "dimensions"
24
+ VARIABLES_PROP = PREFIX + "variables"
24
25
25
26
# Dimension properties
26
27
DIM_TYPE_PROP = "type"
32
33
DIM_REF_SYS_PROP = "reference_system"
33
34
DIM_UNIT_PROP = "unit"
34
35
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
+
35
44
36
45
class DimensionType (str , Enum ):
37
46
"""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
398
407
self .properties [DIM_REF_SYS_PROP ] = v
399
408
400
409
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
+
401
506
class DatacubeExtension (
402
507
Generic [T ],
403
508
PropertiesExtension ,
@@ -423,8 +528,6 @@ def apply(self, dimensions: Dict[str, Dimension]) -> None:
423
528
:class:`~pystac.Collection`, :class:`~pystac.Item` or :class:`~pystac.Asset`.
424
529
425
530
Args:
426
- bands : A list of available bands where each item is a :class:`~Band`
427
- object. If given, requires at least one band.
428
531
dimensions : Dictionary mapping dimension name to a :class:`Dimension`
429
532
object.
430
533
"""
@@ -442,6 +545,15 @@ def dimensions(self) -> Dict[str, Dimension]:
442
545
def dimensions (self , v : Dict [str , Dimension ]) -> None :
443
546
self ._set_property (DIMENSIONS_PROP , {k : dim .to_dict () for k , dim in v .items ()})
444
547
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
+
445
557
@classmethod
446
558
def get_schema_uri (cls ) -> str :
447
559
return SCHEMA_URI
0 commit comments