eotdl 2023.11.2.post5__py3-none-any.whl → 2023.11.3.post2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. eotdl/__init__.py +1 -1
  2. eotdl/access/__init__.py +6 -3
  3. eotdl/access/airbus/__init__.py +5 -1
  4. eotdl/access/airbus/client.py +356 -338
  5. eotdl/access/airbus/parameters.py +19 -4
  6. eotdl/access/airbus/utils.py +26 -21
  7. eotdl/access/download.py +30 -14
  8. eotdl/access/search.py +17 -6
  9. eotdl/access/sentinelhub/__init__.py +5 -1
  10. eotdl/access/sentinelhub/client.py +57 -54
  11. eotdl/access/sentinelhub/evalscripts.py +38 -39
  12. eotdl/access/sentinelhub/parameters.py +43 -23
  13. eotdl/access/sentinelhub/utils.py +38 -28
  14. eotdl/auth/errors.py +2 -1
  15. eotdl/commands/auth.py +3 -3
  16. eotdl/curation/__init__.py +5 -1
  17. eotdl/curation/stac/__init__.py +5 -1
  18. eotdl/curation/stac/assets.py +55 -32
  19. eotdl/curation/stac/dataframe.py +20 -14
  20. eotdl/curation/stac/dataframe_bck.py +2 -2
  21. eotdl/curation/stac/dataframe_labeling.py +15 -12
  22. eotdl/curation/stac/extensions/__init__.py +6 -2
  23. eotdl/curation/stac/extensions/base.py +8 -4
  24. eotdl/curation/stac/extensions/dem.py +6 -3
  25. eotdl/curation/stac/extensions/eo.py +10 -6
  26. eotdl/curation/stac/extensions/label/__init__.py +5 -1
  27. eotdl/curation/stac/extensions/label/base.py +40 -26
  28. eotdl/curation/stac/extensions/label/image_name_labeler.py +64 -43
  29. eotdl/curation/stac/extensions/label/scaneo.py +59 -56
  30. eotdl/curation/stac/extensions/ml_dataset.py +154 -56
  31. eotdl/curation/stac/extensions/projection.py +11 -9
  32. eotdl/curation/stac/extensions/raster.py +22 -14
  33. eotdl/curation/stac/extensions/sar.py +12 -7
  34. eotdl/curation/stac/extent.py +67 -40
  35. eotdl/curation/stac/parsers.py +18 -10
  36. eotdl/curation/stac/stac.py +81 -62
  37. eotdl/datasets/__init__.py +1 -1
  38. eotdl/datasets/download.py +42 -55
  39. eotdl/datasets/ingest.py +68 -11
  40. eotdl/files/__init__.py +1 -1
  41. eotdl/files/ingest.py +3 -1
  42. eotdl/models/download.py +1 -1
  43. eotdl/repos/AuthAPIRepo.py +0 -1
  44. eotdl/repos/DatasetsAPIRepo.py +22 -146
  45. eotdl/repos/FilesAPIRepo.py +7 -92
  46. eotdl/repos/ModelsAPIRepo.py +0 -1
  47. eotdl/tools/__init__.py +5 -1
  48. eotdl/tools/geo_utils.py +78 -48
  49. eotdl/tools/metadata.py +13 -11
  50. eotdl/tools/paths.py +14 -14
  51. eotdl/tools/stac.py +36 -31
  52. eotdl/tools/time_utils.py +53 -26
  53. eotdl/tools/tools.py +84 -50
  54. {eotdl-2023.11.2.post5.dist-info → eotdl-2023.11.3.post2.dist-info}/METADATA +5 -3
  55. eotdl-2023.11.3.post2.dist-info/RECORD +84 -0
  56. eotdl-2023.11.2.post5.dist-info/RECORD +0 -84
  57. {eotdl-2023.11.2.post5.dist-info → eotdl-2023.11.3.post2.dist-info}/WHEEL +0 -0
  58. {eotdl-2023.11.2.post5.dist-info → eotdl-2023.11.3.post2.dist-info}/entry_points.txt +0 -0
@@ -1,26 +1,32 @@
1
- '''
1
+ """
2
2
  Module for the STAC label extension base object
3
- '''
3
+ """
4
+
5
+ from typing import List, Union
4
6
 
5
7
  import pystac
8
+ from pystac.extensions.label import (
9
+ LabelClasses,
10
+ LabelExtension,
11
+ SummariesLabelExtension,
12
+ )
6
13
 
7
- from typing import List, Union
8
14
  from ..base import STACExtensionObject
9
- from pystac.extensions.label import (LabelClasses, LabelExtension, SummariesLabelExtension)
10
15
 
11
16
 
12
17
  class LabelExtensionObject(STACExtensionObject):
18
+ """
19
+ STAC Label extension base object in EOTDL
20
+ """
13
21
  def __init__(self) -> None:
14
22
  super().__init__()
15
23
 
16
24
  @classmethod
17
- def generate_stac_labels(
18
- self
19
- ) -> None:
25
+ def generate_stac_labels(cls) -> None:
20
26
  """
21
27
  Generate a labels collection from a STAC dataframe.
22
28
  """
23
- pass
29
+ return
24
30
 
25
31
  def add_extension_to_item(
26
32
  self,
@@ -46,13 +52,14 @@ class LabelExtensionObject(STACExtensionObject):
46
52
 
47
53
  :return: the item with the label extension
48
54
  """
49
- label_item = pystac.Item(id=obj.id,
50
- geometry=obj.geometry,
51
- bbox=obj.bbox,
52
- properties=dict(),
53
- datetime=obj.datetime
54
- )
55
-
55
+ label_item = pystac.Item(
56
+ id=obj.id,
57
+ geometry=obj.geometry,
58
+ bbox=obj.bbox,
59
+ properties={},
60
+ datetime=obj.datetime,
61
+ )
62
+
56
63
  # Add the label extension to the item
57
64
  LabelExtension.add_to(label_item)
58
65
 
@@ -72,22 +79,30 @@ class LabelExtensionObject(STACExtensionObject):
72
79
  # Add the label type
73
80
  label_ext.label_type = label_type
74
81
  # Add the label properties, if any
75
- label_ext.label_properties = kwargs.get('label_properties') if kwargs.get('label_properties', None) else label_names
82
+ label_ext.label_properties = (
83
+ kwargs.get("label_properties")
84
+ if kwargs.get("label_properties", None)
85
+ else label_names
86
+ )
76
87
  # Add the label methods, if any
77
- label_ext.label_methods = kwargs.get('label_methods') if kwargs.get('label_methods', None) else None
88
+ label_ext.label_methods = (
89
+ kwargs.get("label_methods") if kwargs.get("label_methods", None) else None
90
+ )
78
91
  # Add the label tasks, if any
79
- label_ext.label_tasks = kwargs.get('label_tasks') if kwargs.get('label_tasks', None) else None
92
+ label_ext.label_tasks = (
93
+ kwargs.get("label_tasks") if kwargs.get("label_tasks", None) else None
94
+ )
80
95
  # Add the source
81
96
  label_ext.add_source(obj)
82
97
 
83
98
  return label_item
84
99
 
85
100
  def add_extension_to_collection(
86
- self,
87
- obj: pystac.Collection,
88
- label_names: List[str],
89
- label_classes: List[Union[list, tuple]],
90
- label_type: str
101
+ self,
102
+ obj: pystac.Collection,
103
+ label_names: List[str],
104
+ label_classes: List[Union[list, tuple]],
105
+ label_type: str,
91
106
  ) -> None:
92
107
  """
93
108
  Add the label extension to the given collection
@@ -113,10 +128,9 @@ class LabelExtensionObject(STACExtensionObject):
113
128
  # Add the label type
114
129
  label_ext.label_type = label_type
115
130
 
116
- def add_geojson_to_items(self
117
- ) -> None:
131
+ def add_geojson_to_items(self) -> None:
118
132
  """
119
133
  Add a GeoJSON FeatureCollection to every label item, as recommended by the spec
120
134
  https://github.com/stac-extensions/label#assets
121
135
  """
122
- pass
136
+ return
@@ -1,20 +1,24 @@
1
- '''
1
+ """
2
2
  Module for the STAC label extension ImageNameLabeler object
3
- '''
3
+ """
4
+
5
+ import json
6
+ from os.path import join, dirname
7
+ from typing import List, Optional, Union
4
8
 
5
9
  import pystac
6
10
  import pandas as pd
7
- import json
8
11
 
9
12
  from tqdm import tqdm
10
- from os.path import join, dirname
11
- from typing import List, Optional, Union
13
+ from pystac.extensions.label import LabelExtension
12
14
  from ...extent import get_unknow_extent
13
15
  from .base import LabelExtensionObject
14
- from pystac.extensions.label import LabelExtension
15
16
 
16
17
 
17
18
  class ImageNameLabeler(LabelExtensionObject):
19
+ """
20
+ STAC label extension ImageNameLabeler object in EOTDL
21
+ """
18
22
  def __init__(self) -> None:
19
23
  super().__init__()
20
24
 
@@ -22,16 +26,16 @@ class ImageNameLabeler(LabelExtensionObject):
22
26
  self,
23
27
  catalog: Union[pystac.Catalog, str],
24
28
  stac_dataframe: Optional[pd.DataFrame] = None,
25
- collection: Optional[Union[pystac.Collection, str]] = 'source',
29
+ collection: Optional[Union[pystac.Collection, str]] = "source",
26
30
  label_description: Optional[str] = "Item label",
27
31
  label_type: Optional[str] = "vector",
28
32
  label_names: Optional[List[str]] = ["label"],
29
- **kwargs
33
+ **kwargs,
30
34
  ) -> None:
31
35
  """
32
- Generate a labels collection from a STAC dataframe.
36
+ Generate a labels collection from a STAC dataframe.
33
37
  This class uses the label column of the dataframe as the label names.
34
-
38
+
35
39
  :param catalog: catalog to add the labels collection to
36
40
  :param stac_dataframe: dataframe with the STAC metadata of a given directory containing the assets to generate metadata
37
41
  :param collection: collection to add the labels collection to
@@ -74,7 +78,7 @@ class ImageNameLabeler(LabelExtensionObject):
74
78
  print("Generating labels collection...")
75
79
  for source_item in tqdm(source_items):
76
80
  # There must be an item ID column in the STAC dataframe
77
- if not 'id' in stac_dataframe.columns:
81
+ if "id" not in stac_dataframe.columns:
78
82
  raise ValueError(
79
83
  "No item ID column found in the STAC dataframe, please provide a STAC dataframe with the item ID column"
80
84
  )
@@ -87,7 +91,7 @@ class ImageNameLabeler(LabelExtensionObject):
87
91
  label_type=label_type,
88
92
  label_names=[label_names],
89
93
  label_classes=[label_classes],
90
- **kwargs
94
+ **kwargs,
91
95
  )
92
96
  # Add the self href to the label item, following the Best Practices Layout
93
97
  # https://github.com/radiantearth/stac-spec/blob/master/best-practices.md
@@ -95,8 +99,8 @@ class ImageNameLabeler(LabelExtensionObject):
95
99
  join(
96
100
  dirname(collection.get_self_href()),
97
101
  label_item.id,
98
- f"{label_item.id}.json"
99
- )
102
+ f"{label_item.id}.json",
103
+ )
100
104
  )
101
105
  collection.add_item(label_item)
102
106
 
@@ -113,23 +117,23 @@ class ImageNameLabeler(LabelExtensionObject):
113
117
  # and then iterate over the items to add the geojson
114
118
  try:
115
119
  pystac.validation.validate(catalog)
116
- catalog.normalize_and_save(dirname(catalog.get_self_href()), pystac.CatalogType.SELF_CONTAINED)
120
+ catalog.normalize_and_save(
121
+ dirname(catalog.get_self_href()), pystac.CatalogType.SELF_CONTAINED
122
+ )
117
123
  except pystac.STACValidationError as e:
118
124
  raise pystac.STACError(f"Catalog validation error: {e}")
119
-
125
+
120
126
  # Add a GeoJSON FeatureCollection to every label item, as recommended by the spec
121
127
  # https://github.com/stac-extensions/label#assets
122
- self.add_geojson_to_items(collection,
123
- stac_dataframe,
124
- label_type=label_type)
125
- catalog.normalize_and_save(dirname(catalog.get_self_href()), pystac.CatalogType.SELF_CONTAINED)
126
- print('Success on labels generation!')
127
-
128
- def add_geojson_to_items(self,
129
- collection: pystac.Collection,
130
- df: pd.DataFrame,
131
- label_type: str
132
- ) -> None:
128
+ self.add_geojson_to_items(collection, stac_dataframe, label_type=label_type)
129
+ catalog.normalize_and_save(
130
+ dirname(catalog.get_self_href()), pystac.CatalogType.SELF_CONTAINED
131
+ )
132
+ print("Success on labels generation!")
133
+
134
+ def add_geojson_to_items(
135
+ self, collection: pystac.Collection, df: pd.DataFrame, label_type: str
136
+ ) -> None:
133
137
  """
134
138
  Add a GeoJSON FeatureCollection to every label item, as recommended by the spec
135
139
  https://github.com/stac-extensions/label#assets
@@ -139,33 +143,50 @@ class ImageNameLabeler(LabelExtensionObject):
139
143
  :param label_type: label type
140
144
  """
141
145
  for item in collection.get_all_items():
142
- geojson_path = join(dirname(item.get_self_href()), f'{item.id}.geojson')
146
+ geojson_path = join(dirname(item.get_self_href()), f"{item.id}.geojson")
143
147
 
144
- properties = {'roles': ['labels', f'labels-{label_type}']}
148
+ properties = {"roles": ["labels", f"labels-{label_type}"]}
145
149
 
146
150
  # TODO depending on the tasks, there must be extra fields
147
151
  # https://github.com/stac-extensions/label#assets
148
- if 'label:tasks' in item.properties:
149
- tasks = item.properties['label:tasks']
150
- if 'tile_regression' in tasks:
152
+ if "label:tasks" in item.properties:
153
+ tasks = item.properties["label:tasks"]
154
+ if "tile_regression" in tasks:
151
155
  pass
152
- elif any(task in tasks for task in ('tile_classification', 'object_detection', 'segmentation')):
156
+ elif any(
157
+ task in tasks
158
+ for task in (
159
+ "tile_classification",
160
+ "object_detection",
161
+ "segmentation",
162
+ )
163
+ ):
153
164
  pass
154
165
 
155
166
  label_ext = LabelExtension.ext(item)
156
- label_ext.add_geojson_labels(href=geojson_path,
157
- title='Label',
158
- properties=properties)
167
+ label_ext.add_geojson_labels(
168
+ href=geojson_path, title="Label", properties=properties
169
+ )
159
170
  item.make_asset_hrefs_relative()
160
-
171
+
161
172
  item_id = item.id
162
173
  geometry = item.geometry
163
- labels = [df[df['id'] == item_id]['label'].values[0]]
174
+ labels = [df[df["id"] == item_id]["label"].values[0]]
164
175
  # There is data like DEM data that does not have datetime but start and end datetime
165
- datetime = item.datetime.isoformat() if item.datetime else (item.properties.start_datetime.isoformat(),
166
- item.properties.end_datetime.isoformat())
167
- labels_properties = dict(zip(item.properties['label:properties'], labels)) if label_type == 'vector' else dict()
168
- labels_properties['datetime'] = datetime
176
+ datetime = (
177
+ item.datetime.isoformat()
178
+ if item.datetime
179
+ else (
180
+ item.properties.start_datetime.isoformat(),
181
+ item.properties.end_datetime.isoformat(),
182
+ )
183
+ )
184
+ labels_properties = (
185
+ dict(zip(item.properties["label:properties"], labels))
186
+ if label_type == "vector"
187
+ else {}
188
+ )
189
+ labels_properties["datetime"] = datetime
169
190
 
170
191
  geojson = {
171
192
  "type": "FeatureCollection",
@@ -178,5 +199,5 @@ class ImageNameLabeler(LabelExtensionObject):
178
199
  ],
179
200
  }
180
201
 
181
- with open(geojson_path, "w") as f:
202
+ with open(geojson_path, "w", encoding="utf-8") as f:
182
203
  json.dump(geojson, f)
@@ -1,15 +1,15 @@
1
- '''
1
+ """
2
2
  Module for the STAC label extension ScaneoLabeler object
3
- '''
3
+ """
4
4
 
5
- import pystac
6
- import pandas as pd
7
5
  import json
8
-
9
- from glob import glob
10
- from tqdm import tqdm
11
6
  from os.path import join, dirname, exists, splitext, basename, abspath
12
7
  from typing import List, Optional, Union
8
+ from glob import glob
9
+
10
+ import pystac
11
+
12
+ from tqdm import tqdm
13
13
  from pystac.extensions.label import LabelExtension
14
14
 
15
15
  from .base import LabelExtensionObject
@@ -17,6 +17,9 @@ from ...extent import get_unknow_extent
17
17
 
18
18
 
19
19
  class ScaneoLabeler(LabelExtensionObject):
20
+ """
21
+ STAC label extension ScaneoLabeler object in EOTDL
22
+ """
20
23
  def __init__(self) -> None:
21
24
  super().__init__()
22
25
 
@@ -24,17 +27,17 @@ class ScaneoLabeler(LabelExtensionObject):
24
27
  self,
25
28
  catalog: Union[pystac.Catalog, str],
26
29
  root_folder: str,
27
- collection: Optional[Union[pystac.Collection, str]] = 'source',
30
+ collection: Optional[Union[pystac.Collection, str]] = "source",
28
31
  label_description: Optional[str] = "Item label",
29
32
  label_type: Optional[str] = "vector",
30
33
  label_names: Optional[List[str]] = ["label"],
31
- **kwargs
34
+ **kwargs,
32
35
  ) -> None:
33
36
  """
34
- Generate a labels collection from a STAC dataframe.
37
+ Generate a labels collection from a STAC dataframe.
35
38
  This class should be used when the items have been labeled using SCANEO, as is implemented
36
39
  taking into account the SCANEO labeling format.
37
-
40
+
38
41
  :param catalog: catalog to add the labels collection to
39
42
  :param root_folder: root folder where are the images and the labels as GeoJSON files, following the SCANEO labeling format
40
43
  :param stac_dataframe: dataframe with the STAC metadata of a given directory containing the assets to generate metadata
@@ -84,9 +87,9 @@ class ScaneoLabeler(LabelExtensionObject):
84
87
  # Get the GeoJSON label of the item
85
88
  geojson_label = self.get_geojson_of_item(source_item, geojson_files)
86
89
  # Get the tasks from the GeoJSON label
87
- tasks = self.get_tasks_from_geojson(geojson_label)
90
+ tasks = self.get_tasks_from_geojson(geojson_label) if geojson_label else None
88
91
  # Add the tasks to the kwargs
89
- kwargs['label_tasks'] = tasks
92
+ kwargs["label_tasks"] = tasks
90
93
 
91
94
  # Create the label item
92
95
  label_item = self.add_extension_to_item(
@@ -95,7 +98,7 @@ class ScaneoLabeler(LabelExtensionObject):
95
98
  label_type=label_type,
96
99
  label_names=label_names,
97
100
  label_classes=label_classes,
98
- **kwargs
101
+ **kwargs,
99
102
  )
100
103
  # Add the self href to the label item, following the Best Practices Layout
101
104
  # https://github.com/radiantearth/stac-spec/blob/master/best-practices.md
@@ -103,11 +106,12 @@ class ScaneoLabeler(LabelExtensionObject):
103
106
  join(
104
107
  dirname(collection.get_self_href()),
105
108
  label_item.id,
106
- f"{label_item.id}.json"
107
- )
109
+ f"{label_item.id}.json",
110
+ )
108
111
  )
109
- # Match the GeoJSON label with the label item
110
- self.add_geojson_to_item(label_item, geojson_label, label_type)
112
+ # Match the GeoJSON label with the label item, if exists
113
+ if geojson_label and exists(geojson_label):
114
+ self.add_geojson_to_item(label_item, geojson_label, label_type)
111
115
  # Add the item to the collection
112
116
  collection.add_item(label_item)
113
117
 
@@ -124,16 +128,16 @@ class ScaneoLabeler(LabelExtensionObject):
124
128
  # and then iterate over the items to add the geojson
125
129
  try:
126
130
  pystac.validation.validate(catalog)
127
- catalog.normalize_and_save(dirname(catalog.get_self_href()), pystac.CatalogType.SELF_CONTAINED)
128
- print('Success on labels generation!')
131
+ catalog.normalize_and_save(
132
+ dirname(catalog.get_self_href()), pystac.CatalogType.SELF_CONTAINED
133
+ )
134
+ print("Success on labels generation!")
129
135
  except pystac.STACValidationError as e:
130
136
  raise pystac.STACError(f"Catalog validation error: {e}")
131
137
 
132
- def add_geojson_to_item(self,
133
- item: pystac.Item,
134
- geojson_path: str,
135
- label_type: str
136
- ) -> None:
138
+ def add_geojson_to_item(
139
+ self, item: pystac.Item, geojson_path: str, label_type: str
140
+ ) -> None:
137
141
  """
138
142
  Add a GeoJSON FeatureCollection to every label item, as recommended by the spec
139
143
  https://github.com/stac-extensions/label#assets
@@ -142,43 +146,41 @@ class ScaneoLabeler(LabelExtensionObject):
142
146
  :param df: dataframe with the STAC metadata of a given directory containing the assets to generate metadata
143
147
  :param label_type: label type
144
148
  """
145
- properties = {'roles': ['labels', f'labels-{label_type}']}
149
+ properties = {"roles": ["labels", f"labels-{label_type}"]}
146
150
 
147
151
  label_ext = LabelExtension.ext(item, add_if_missing=True)
148
152
  item.make_asset_hrefs_absolute()
149
- label_ext.add_geojson_labels(href=abspath(geojson_path),
150
- title='Label',
151
- properties=properties)
153
+ label_ext.add_geojson_labels(
154
+ href=abspath(geojson_path), title="Label", properties=properties
155
+ )
152
156
  item.make_asset_hrefs_relative()
153
-
154
- def get_label_classes(self,
155
- root_folder: str,
156
- geojsons: List[str]
157
- ) -> List[str]:
157
+
158
+ def get_label_classes(self, root_folder: str, geojsons: List[str]) -> List[str]:
158
159
  """
159
160
  Get the label classes from the labels.json file if exists, or from the GeoJSON files instead
160
161
  """
161
- label_classes = list()
162
+ label_classes = []
162
163
 
163
164
  labels_json = glob(join(root_folder, "labels.json"))[0]
164
165
  if exists(labels_json):
165
- with open(labels_json, 'r') as f:
166
+ with open(labels_json, "r", encoding="utf-8") as f:
166
167
  labels = json.load(f)
167
- for value in labels['labels']:
168
- label_classes.append(value['name']) if value['name'] not in label_classes else None
168
+ for value in labels["labels"]:
169
+ label_classes.append(value["name"]) if value[
170
+ "name"
171
+ ] not in label_classes else None
169
172
  else:
170
173
  for geojson in geojsons:
171
- with open(geojson, 'r') as f:
174
+ with open(geojson, "r", encoding="utf-8") as f:
172
175
  labels = json.load(f)
173
- for value in labels['features']:
174
- label_classes.append(value['properties']['labels']) if value['properties']['labels'] not in label_classes else None
176
+ for value in labels["features"]:
177
+ label_classes.append(value["properties"]["labels"]) if value[
178
+ "properties"
179
+ ]["labels"] not in label_classes else None
175
180
 
176
181
  return [label_classes]
177
182
 
178
- def get_geojson_of_item(self,
179
- item: pystac.Item,
180
- geojsons: List[str]
181
- ) -> str:
183
+ def get_geojson_of_item(self, item: pystac.Item, geojsons: List[str]) -> str:
182
184
  """
183
185
  Get the GeoJSON label of the item from a list of GeoJSON files
184
186
 
@@ -188,16 +190,17 @@ class ScaneoLabeler(LabelExtensionObject):
188
190
  :return: path to the GeoJSON label of the item
189
191
  """
190
192
  item_id = item.id
193
+ geojson_name = f"{item_id}_labels"
191
194
  # Get a dict with <geojson_filename>: <geojson_path>, as the geojson_filename
192
195
  # must match the item ID
193
- geojsons_dict = dict(zip([splitext(basename(geojson))[0] for geojson in geojsons], geojsons))
194
- geojson_path = geojsons_dict.get(item_id)
195
-
196
+ geojsons_dict = dict(
197
+ zip([splitext(basename(geojson))[0] for geojson in geojsons], geojsons)
198
+ )
199
+ geojson_path = geojsons_dict.get(geojson_name)
200
+
196
201
  return geojson_path
197
202
 
198
- def get_tasks_from_geojson(self,
199
- geojson_path: str
200
- ) -> List[str]:
203
+ def get_tasks_from_geojson(self, geojson_path: str) -> List[str]:
201
204
  """
202
205
  Get the tasks from the GeoJSON label
203
206
 
@@ -205,11 +208,11 @@ class ScaneoLabeler(LabelExtensionObject):
205
208
 
206
209
  :return: list of tasks
207
210
  """
208
- with open(geojson_path, 'r') as f:
211
+ with open(geojson_path, "r", encoding="utf-8") as f:
209
212
  geojson = json.load(f)
210
- tasks = list()
211
- for feature in geojson['features']:
212
- for task in feature['properties']['tasks']:
213
+ tasks = []
214
+ for feature in geojson["features"]:
215
+ for task in feature["properties"]["tasks"]:
213
216
  tasks.append(task) if task not in tasks else None
214
-
217
+
215
218
  return tasks