|
18 | 18 |
|
19 | 19 | from openeo.metadata import CollectionMetadata
|
20 | 20 | from openeo.util import ensure_dir, str_truncate
|
| 21 | +import openeo.udf |
21 | 22 | from openeo_driver.datastructs import SarBackscatterArgs, ResolutionMergeArgs, StacAsset
|
22 | 23 | from openeo_driver.errors import FeatureUnsupportedException, InternalException
|
23 | 24 | from openeo_driver.util.geometry import GeometryBufferer, validate_geojson_coordinates
|
24 | 25 | from openeo_driver.util.ioformats import IOFORMATS
|
| 26 | +from openeo_driver.util.pgparsing import SingleRunUDFProcessGraph |
25 | 27 | from openeo_driver.util.utm import area_in_square_meters
|
26 | 28 | from openeo_driver.utils import EvalEnv
|
27 |
| -from openeogeotrellis.backend import SingleNodeUDFProcessGraphVisitor |
28 | 29 |
|
29 | 30 | log = logging.getLogger(__name__)
|
30 | 31 |
|
@@ -248,38 +249,6 @@ def with_cube(self, cube: xarray.DataArray, flatten_prefix: str = FLATTEN_PREFIX
|
248 | 249 | geometries=self._geometries, cube=cube, flatten_prefix=flatten_prefix
|
249 | 250 | )
|
250 | 251 |
|
251 |
| - def apply_dimension( |
252 |
| - self, |
253 |
| - process: dict, |
254 |
| - *, |
255 |
| - dimension: str, |
256 |
| - target_dimension: Optional[str] = None, |
257 |
| - context: Optional[dict] = None, |
258 |
| - env: EvalEnv, |
259 |
| - ) -> "DriverVectorCube": |
260 |
| - if dimension == "bands" and target_dimension == None and len(process) == 1 and next(iter(process.values())).get('process_id') == 'run_udf': |
261 |
| - visitor = SingleNodeUDFProcessGraphVisitor().accept_process_graph(process) |
262 |
| - udf = visitor.udf_args.get('udf', None) |
263 |
| - |
264 |
| - from openeo.udf import FeatureCollection, UdfData |
265 |
| - collection = FeatureCollection(id='VectorCollection', data=self._as_geopandas_df()) |
266 |
| - data = UdfData( |
267 |
| - proj={"EPSG": self._geometries.crs.to_epsg()}, feature_collection_list=[collection], user_context=context |
268 |
| - ) |
269 |
| - |
270 |
| - log.info(f"[run_udf] Running UDF {str_truncate(udf, width=256)!r} on {data!r}") |
271 |
| - result_data = env.backend_implementation.processing.run_udf(udf, data) |
272 |
| - log.info(f"[run_udf] UDF resulted in {result_data!r}") |
273 |
| - |
274 |
| - if isinstance(result_data, UdfData): |
275 |
| - if(result_data.get_feature_collection_list() is not None and len(result_data.get_feature_collection_list()) == 1): |
276 |
| - return DriverVectorCube(geometries=result_data.get_feature_collection_list()[0].data) |
277 |
| - |
278 |
| - raise ValueError(f"Could not handle UDF result: {result_data}") |
279 |
| - |
280 |
| - else: |
281 |
| - raise FeatureUnsupportedException() |
282 |
| - |
283 | 252 | @classmethod
|
284 | 253 | def from_fiona(
|
285 | 254 | cls,
|
@@ -537,6 +506,44 @@ def buffer_points(self, distance: float = 10) -> "DriverVectorCube":
|
537 | 506 | ]
|
538 | 507 | )
|
539 | 508 |
|
| 509 | + def apply_dimension( |
| 510 | + self, |
| 511 | + process: dict, |
| 512 | + *, |
| 513 | + dimension: str, |
| 514 | + target_dimension: Optional[str] = None, |
| 515 | + context: Optional[dict] = None, |
| 516 | + env: EvalEnv, |
| 517 | + ) -> "DriverVectorCube": |
| 518 | + single_run_udf = SingleRunUDFProcessGraph.parse_or_none(process) |
| 519 | + |
| 520 | + if single_run_udf: |
| 521 | + # Process with single "run_udf" node |
| 522 | + if self._cube is None and dimension == self.DIM_GEOMETRIES and target_dimension is None: |
| 523 | + log.warning( |
| 524 | + f"Using experimental feature: DriverVectorCube.apply_dimension along dim {dimension} and empty cube" |
| 525 | + ) |
| 526 | + # TODO: this is non-standard special case: vector cube with only geometries, but no "cube" data |
| 527 | + gdf = self._as_geopandas_df() |
| 528 | + feature_collection = openeo.udf.FeatureCollection(id="_", data=gdf) |
| 529 | + udf_data = openeo.udf.UdfData( |
| 530 | + proj={"EPSG": self._geometries.crs.to_epsg()}, |
| 531 | + feature_collection_list=[feature_collection], |
| 532 | + user_context=context, |
| 533 | + ) |
| 534 | + log.info(f"[run_udf] Running UDF {str_truncate(single_run_udf.udf, width=256)!r} on {udf_data!r}") |
| 535 | + result_data = env.backend_implementation.processing.run_udf(udf=single_run_udf.udf, data=udf_data) |
| 536 | + log.info(f"[run_udf] UDF resulted in {result_data!r}") |
| 537 | + |
| 538 | + if isinstance(result_data, openeo.udf.UdfData): |
| 539 | + result_features = result_data.get_feature_collection_list() |
| 540 | + if result_features and len(result_features) == 1: |
| 541 | + return DriverVectorCube(geometries=result_features[0].data) |
| 542 | + raise ValueError(f"Could not handle UDF result: {result_data}") |
| 543 | + |
| 544 | + raise FeatureUnsupportedException() |
| 545 | + |
| 546 | + |
540 | 547 |
|
541 | 548 | class DriverMlModel:
|
542 | 549 | """Base class for driver-side 'ml-model' data structures"""
|
|
0 commit comments