44"""
55
66from enum import Enum
7- from pystac .extensions .base import ExtensionManagementMixin
7+ from pystac .extensions .base import ExtensionManagementMixin , SummariesExtension
88from typing import Any , Dict , Iterable , List , Optional , Set , Union , cast
99
1010import pystac
1111from pystac .serialization .identify import STACJSONDescription , STACVersionID
1212from pystac .extensions .hooks import ExtensionHooks
13- from pystac .utils import get_required
13+ from pystac .utils import get_required , map_opt
1414
1515SCHEMA_URI = "https://stac-extensions.github.io/label/v1.0.0/schema.json"
1616
@@ -52,6 +52,28 @@ def __str__(self) -> str:
5252 """Convenience attribute for checking if values are valid label types"""
5353
5454
55+ class LabelTask (str , Enum ):
56+ """Enumerates recommended values for "label:tasks" field."""
57+
58+ def __str__ (self ) -> str :
59+ return str (self .value )
60+
61+ REGRESSION = "regression"
62+ CLASSIFICATION = "classification"
63+ DETECTION = "detection"
64+ SEGMENTATION = "segmentation"
65+
66+
67+ class LabelMethod (str , Enum ):
68+ """Enumerates recommended values for "label:methods" field."""
69+
70+ def __str__ (self ) -> str :
71+ return str (self .value )
72+
73+ AUTOMATED = "automated"
74+ MANUAL = "manual"
75+
76+
5577class LabelClasses :
5678 """Defines the list of possible class names (e.g., tree, building, car, hippo).
5779
@@ -121,6 +143,15 @@ def __repr__(self) -> str:
121143 "," .join ([str (x ) for x in self .classes ])
122144 )
123145
146+ def __eq__ (self , o : object ) -> bool :
147+ if isinstance (o , LabelClasses ):
148+ o = o .to_dict ()
149+
150+ if not isinstance (o , dict ):
151+ return NotImplemented
152+
153+ return self .to_dict () == o
154+
124155 def to_dict (self ) -> Dict [str , Any ]:
125156 """Returns the dictionary representing the JSON of this instance."""
126157 return self .properties
@@ -180,6 +211,15 @@ def to_dict(self) -> Dict[str, Any]:
180211 """Returns the dictionary representing the JSON of this instance."""
181212 return self .properties
182213
214+ def __eq__ (self , o : object ) -> bool :
215+ if isinstance (o , LabelCount ):
216+ o = o .to_dict ()
217+
218+ if not isinstance (o , dict ):
219+ return NotImplemented
220+
221+ return self .to_dict () == o
222+
183223
184224class LabelStatistics :
185225 """Contains statistics for regression/continuous numeric value data.
@@ -234,6 +274,15 @@ def to_dict(self) -> Dict[str, Any]:
234274 """Returns the dictionary representing the JSON of this LabelStatistics."""
235275 return self .properties
236276
277+ def __eq__ (self , o : object ) -> bool :
278+ if isinstance (o , LabelStatistics ):
279+ o = o .to_dict ()
280+
281+ if not isinstance (o , dict ):
282+ return NotImplemented
283+
284+ return self .to_dict () == o
285+
237286
238287class LabelOverview :
239288 """Stores counts (for classification-type data) or summary statistics (for
@@ -379,6 +428,15 @@ def to_dict(self) -> Dict[str, Any]:
379428 """Returns the dictionary representing the JSON of this LabelOverview."""
380429 return self .properties
381430
431+ def __eq__ (self , o : object ) -> bool :
432+ if isinstance (o , LabelOverview ):
433+ o = o .to_dict ()
434+
435+ if not isinstance (o , dict ):
436+ return NotImplemented
437+
438+ return self .to_dict () == o
439+
382440
383441class LabelExtension (ExtensionManagementMixin [pystac .Item ]):
384442 """A class that can be used to extend the properties of an
@@ -403,8 +461,8 @@ def apply(
403461 label_type : LabelType ,
404462 label_properties : Optional [List [str ]] = None ,
405463 label_classes : Optional [List [LabelClasses ]] = None ,
406- label_tasks : Optional [List [str ]] = None ,
407- label_methods : Optional [List [str ]] = None ,
464+ label_tasks : Optional [List [Union [ LabelTask , str ] ]] = None ,
465+ label_methods : Optional [List [Union [ LabelMethod , str ] ]] = None ,
408466 label_overviews : Optional [List [LabelOverview ]] = None ,
409467 ) -> None :
410468 """Applies label extension properties to the extended Item.
@@ -499,28 +557,28 @@ def label_classes(self, v: Optional[List[LabelClasses]]) -> None:
499557 self .obj .properties [CLASSES_PROP ] = classes
500558
501559 @property
502- def label_tasks (self ) -> Optional [List [str ]]:
560+ def label_tasks (self ) -> Optional [List [Union [ LabelTask , str ] ]]:
503561 """Gets or set a list of tasks these labels apply to. Usually a subset of 'regression',
504562 'classification', 'detection', or 'segmentation', but may be arbitrary
505563 values."""
506564 return self .obj .properties .get (TASKS_PROP )
507565
508566 @label_tasks .setter
509- def label_tasks (self , v : Optional [List [str ]]) -> None :
567+ def label_tasks (self , v : Optional [List [Union [ LabelTask , str ] ]]) -> None :
510568 if v is None :
511569 self .obj .properties .pop (TASKS_PROP , None )
512570 else :
513571 self .obj .properties [TASKS_PROP ] = v
514572
515573 @property
516- def label_methods (self ) -> Optional [List [str ]]:
574+ def label_methods (self ) -> Optional [List [Union [ LabelMethod , str ] ]]:
517575 """Gets or set a list of methods used for labeling.
518576
519577 Usually a subset of 'automated' or 'manual', but may be arbitrary values."""
520578 return self .obj .properties .get ("label:methods" )
521579
522580 @label_methods .setter
523- def label_methods (self , v : Optional [List [str ]]) -> None :
581+ def label_methods (self , v : Optional [List [Union [ LabelMethod , str ] ]]) -> None :
524582 if v is None :
525583 self .obj .properties .pop ("label:methods" , None )
526584 else :
@@ -655,6 +713,83 @@ def ext(cls, obj: pystac.Item, add_if_missing: bool = False) -> "LabelExtension"
655713 f"Label extension does not apply to type { type (obj )} "
656714 )
657715
716+ @staticmethod
717+ def summaries (obj : pystac .Collection ) -> "SummariesLabelExtension" :
718+ """Returns the extended summaries object for the given collection."""
719+ return SummariesLabelExtension (obj )
720+
721+
722+ class SummariesLabelExtension (SummariesExtension ):
723+ """A concrete implementation of :class:`~SummariesExtension` that extends
724+ the ``summaries`` field of a :class:`~pystac.Collection` to include properties
725+ defined in the :stac-ext:`Label Extension <label>`.
726+ """
727+
728+ @property
729+ def label_properties (self ) -> Optional [List [str ]]:
730+ """Get or sets the summary of :attr:`LabelExtension.label_properties` values
731+ for this Collection.
732+ """
733+
734+ return self .summaries .get_list (PROPERTIES_PROP )
735+
736+ @label_properties .setter
737+ def label_properties (self , v : Optional [List [LabelClasses ]]) -> None :
738+ self ._set_summary (PROPERTIES_PROP , v )
739+
740+ @property
741+ def label_classes (self ) -> Optional [List [LabelClasses ]]:
742+ """Get or sets the summary of :attr:`LabelExtension.label_classes` values
743+ for this Collection.
744+ """
745+
746+ return map_opt (
747+ lambda classes : [LabelClasses (c ) for c in classes ],
748+ self .summaries .get_list (CLASSES_PROP ),
749+ )
750+
751+ @label_classes .setter
752+ def label_classes (self , v : Optional [List [LabelClasses ]]) -> None :
753+ self ._set_summary (
754+ CLASSES_PROP , map_opt (lambda classes : [c .to_dict () for c in classes ], v )
755+ )
756+
757+ @property
758+ def label_type (self ) -> Optional [List [LabelType ]]:
759+ """Get or sets the summary of :attr:`LabelExtension.label_type` values
760+ for this Collection.
761+ """
762+
763+ return self .summaries .get_list (TYPE_PROP )
764+
765+ @label_type .setter
766+ def label_type (self , v : Optional [List [LabelType ]]) -> None :
767+ self ._set_summary (TYPE_PROP , v )
768+
769+ @property
770+ def label_tasks (self ) -> Optional [List [Union [LabelTask , str ]]]:
771+ """Get or sets the summary of :attr:`LabelExtension.label_tasks` values
772+ for this Collection.
773+ """
774+
775+ return self .summaries .get_list (TASKS_PROP )
776+
777+ @label_tasks .setter
778+ def label_tasks (self , v : Optional [List [Union [LabelTask , str ]]]) -> None :
779+ self ._set_summary (TASKS_PROP , v )
780+
781+ @property
782+ def label_methods (self ) -> Optional [List [Union [LabelMethod , str ]]]:
783+ """Get or sets the summary of :attr:`LabelExtension.label_methods` values
784+ for this Collection.
785+ """
786+
787+ return self .summaries .get_list (METHODS_PROP )
788+
789+ @label_methods .setter
790+ def label_methods (self , v : Optional [List [Union [LabelMethod , str ]]]) -> None :
791+ self ._set_summary (METHODS_PROP , v )
792+
658793
659794class LabelExtensionHooks (ExtensionHooks ):
660795 schema_uri : str = SCHEMA_URI
0 commit comments