Skip to content

Commit 9c4cbd4

Browse files
committed
Issue #401 WIP
1 parent fa3a4d2 commit 9c4cbd4

File tree

4 files changed

+66
-10
lines changed

4 files changed

+66
-10
lines changed

openeo/rest/_datacube.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,55 @@ def _repr_html_(self):
151151
}
152152
return render_component("model-builder", data=process, parameters=parameters)
153153

154+
def execute(self) -> dict:
155+
"""Executes the process graph."""
156+
return self._connection.execute(self.flat_graph())
157+
158+
159+
class _Cube(_ProcessGraphAbstraction):
160+
"""Common base class for raster and vector data cubes."""
161+
162+
_DEFAULT_OUTPUT_FORMAT = None
163+
164+
def _ensure_save_result(
165+
self,
166+
format: Optional[str] = None,
167+
options: Optional[dict] = None,
168+
) -> "_Cube":
169+
"""
170+
Make sure there is a (final) `save_result` node in the process graph.
171+
If there is already one: check if it is consistent with the given format/options (if any)
172+
and add a new one otherwise.
173+
174+
:param format: (optional) desired `save_result` file format
175+
:param options: (optional) desired `save_result` file format parameters
176+
:return:
177+
"""
178+
# TODO: move to generic data cube parent class (not only for raster cubes, but also vector cubes)
179+
result_node = self.result_node()
180+
if result_node.process_id == "save_result":
181+
# There is already a `save_result` node:
182+
# check if it is consistent with given format/options (if any)
183+
args = result_node.arguments
184+
if format is not None and format.lower() != args["format"].lower():
185+
raise ValueError(
186+
f"Existing `save_result` node with different format {args['format']!r} != {format!r}"
187+
)
188+
if options is not None and options != args["options"]:
189+
raise ValueError(
190+
f"Existing `save_result` node with different options {args['options']!r} != {options!r}"
191+
)
192+
cube = self
193+
else:
194+
# No `save_result` node yet: automatically add it.
195+
# TODO: define `save_result` and or `process` methods on `_Cube`?
196+
cube = self.save_result(
197+
format=format or self._DEFAULT_OUTPUT_FORMAT, options=options
198+
)
199+
return cube
200+
201+
# TODO: define `create_job`, `execute_batch`, ... here too
202+
154203

155204
class UDF:
156205
"""

openeo/rest/datacube.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
from openeo.metadata import CollectionMetadata, Band, BandDimension, TemporalDimension, SpatialDimension
3131
from openeo.processes import ProcessBuilder
3232
from openeo.rest import BandMathException, OperatorException, OpenEoClientException
33-
from openeo.rest._datacube import _ProcessGraphAbstraction, THIS, UDF
33+
from openeo.rest._datacube import _ProcessGraphAbstraction, THIS, UDF, _Cube
3434
from openeo.rest.job import BatchJob
3535
from openeo.rest.mlmodel import MlModel
3636
from openeo.rest.service import Service
@@ -49,8 +49,7 @@
4949

5050

5151

52-
53-
class DataCube(_ProcessGraphAbstraction):
52+
class DataCube(_Cube):
5453
"""
5554
Class representing a openEO (raster) data cube.
5655
@@ -59,7 +58,7 @@ class DataCube(_ProcessGraphAbstraction):
5958
"""
6059

6160
# TODO: set this based on back-end or user preference?
62-
_DEFAULT_RASTER_FORMAT = "GTiff"
61+
_DEFAULT_OUTPUT_FORMAT = "GTiff"
6362

6463
def __init__(self, graph: PGNode, connection: 'openeo.Connection', metadata: CollectionMetadata = None):
6564
super().__init__(pgnode=graph, connection=connection)
@@ -1815,7 +1814,7 @@ def atmospheric_correction(
18151814
@openeo_process
18161815
def save_result(
18171816
self,
1818-
format: str = _DEFAULT_RASTER_FORMAT,
1817+
format: str = _DEFAULT_OUTPUT_FORMAT,
18191818
options: Optional[dict] = None,
18201819
) -> "DataCube":
18211820
formats = set(self._connection.list_output_formats().keys())
@@ -1864,7 +1863,7 @@ def _ensure_save_result(
18641863
else:
18651864
# No `save_result` node yet: automatically add it.
18661865
cube = self.save_result(
1867-
format=format or self._DEFAULT_RASTER_FORMAT, options=options
1866+
format=format or self._DEFAULT_OUTPUT_FORMAT, options=options
18681867
)
18691868
return cube
18701869

@@ -2009,8 +2008,9 @@ def save_user_defined_process(
20092008
)
20102009

20112010
def execute(self) -> dict:
2012-
"""Executes the process graph of the imagery. """
2013-
return self._connection.execute(self.flat_graph())
2011+
"""Executes the process graph."""
2012+
# TODO: still necessary to do this explicitly here?
2013+
return super().execute()
20142014

20152015
@staticmethod
20162016
@deprecated(reason="Use :py:func:`openeo.udf.run_code.execute_local_udf` instead", version="0.7.0")

openeo/rest/mlmodel.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ class MlModel(_ProcessGraphAbstraction):
2424
2525
.. versionadded:: 0.10.0
2626
"""
27+
28+
# TODO
2729
def __init__(self, graph: PGNode, connection: 'Connection'):
2830
super().__init__(pgnode=graph, connection=connection)
2931

openeo/rest/vectorcube.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from openeo.internal.graph_building import PGNode
77
from openeo.internal.warnings import legacy_alias
88
from openeo.metadata import CollectionMetadata
9-
from openeo.rest._datacube import _ProcessGraphAbstraction, UDF
9+
from openeo.rest._datacube import _ProcessGraphAbstraction, UDF, _Cube
1010
from openeo.rest.mlmodel import MlModel
1111
from openeo.rest.job import BatchJob
1212
from openeo.util import dict_no_none
@@ -16,7 +16,7 @@
1616
from openeo import Connection
1717

1818

19-
class VectorCube(_ProcessGraphAbstraction):
19+
class VectorCube(_Cube):
2020
"""
2121
A Vector Cube, or 'Vector Collection' is a data structure containing 'Features':
2222
https://www.w3.org/TR/sdw-bp/#dfn-feature
@@ -90,6 +90,10 @@ def run_udf(
9090

9191
@openeo_process
9292
def save_result(self, format: str = "GeoJson", options: dict = None):
93+
# TODO?
94+
# TODO: check format against supported formats
95+
# TODO: should not return a VectorCube again, but bool wrapper
96+
# TODO: should save_result also work on non-cube data types, e.g. arrays, scalars?
9397
return self.process(
9498
process_id="save_result",
9599
arguments={
@@ -105,6 +109,7 @@ def execute(self) -> dict:
105109

106110
def download(self, outputfile: str, format: str = "GeoJSON", options: dict = None):
107111
# TODO: only add save_result, when not already present (see DataCube.download)
112+
# TODO
108113
cube = self.save_result(format=format, options=options)
109114
return self._connection.download(cube.flat_graph(), outputfile)
110115

0 commit comments

Comments
 (0)