Skip to content

Commit b5a6b4e

Browse files
Merge pull request #631 from Open-EO/881-apply_vectorcubegeometries-cube-udf-for-vectorcubes
add apply_vectorcube udf
2 parents bb4b448 + b62be1b commit b5a6b4e

File tree

4 files changed

+50
-2
lines changed

4 files changed

+50
-2
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1414
- Added `openeo.api.process.Parameter` helper to easily create a "spatial_extent" UDP parameter
1515
- Wrap OIDC token request failure in more descriptive `OidcException` (related to [#624](https://github.com/Open-EO/openeo-python-client/issues/624))
1616
- Added `auto_add_save_result` option (on by default) to disable automatic addition of `save_result` node on `download`/`create_job`/`execute_batch` ([#513](https://github.com/Open-EO/openeo-python-client/issues/513))
17+
- Add support for `apply_vectorcube` UDF signature in `run_udf_code` ([Open-EO/openeo-geopyspark-driver#881]https://github.com/Open-EO/openeo-geopyspark-driver/issues/811)
1718

1819
### Changed
1920

openeo/_version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "0.32.0a1"
1+
__version__ = "0.32.0a2"

openeo/udf/run_code.py

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,6 @@ def _annotation_is_data_array(annotation) -> bool:
8888
_get_annotation_str(xarray.DataArray)
8989
}
9090

91-
9291
def _annotation_is_udf_data(annotation) -> bool:
9392
return annotation is UdfData or _get_annotation_str(annotation) in {
9493
_get_annotation_str(UdfData),
@@ -196,6 +195,38 @@ def run_udf_code(code: str, data: UdfData) -> UdfData:
196195
result_cube: xarray.DataArray = func(cube=data.get_datacube_list()[0].get_array(), context=data.user_context)
197196
data.set_datacube_list([XarrayDataCube(result_cube)])
198197
return data
198+
elif (
199+
fn_name in ["apply_vectorcube"]
200+
and "geometries" in params
201+
and _get_annotation_str(params["geometries"].annotation) == "geopandas.geodataframe.GeoDataFrame"
202+
and "cube" in params
203+
and _annotation_is_data_array(params["cube"].annotation)
204+
):
205+
if data.get_feature_collection_list is None or data.get_datacube_list() is None:
206+
raise ValueError(
207+
"The provided UDF expects a FeatureCollection and a datacube, but received {f} and {c}".format(
208+
f=data.get_feature_collection_list(), c=data.get_datacube_list()
209+
)
210+
)
211+
if len(data.get_feature_collection_list()) != 1:
212+
raise ValueError(
213+
"The provided UDF expects exactly one FeatureCollection, but {c} were provided.".format(
214+
c=len(data.get_feature_collection_list())
215+
)
216+
)
217+
if len(data.get_datacube_list()) != 1:
218+
raise ValueError(
219+
"The provided UDF expects exactly one datacube, but {c} were provided.".format(
220+
c=len(data.get_datacube_list())
221+
)
222+
)
223+
# TODO: geopandas is optional dependency.
224+
input_geoms = data.get_feature_collection_list()[0].data
225+
input_cube = data.get_datacube_list()[0].get_array()
226+
result_geoms, result_cube = func(geometries=input_geoms, cube=input_cube, context=data.user_context)
227+
data.set_datacube_list([XarrayDataCube(result_cube)])
228+
data.set_feature_collection_list([FeatureCollection(id="udf_result", data=result_geoms)])
229+
return data
199230
elif len(params) == 1 and _annotation_is_udf_data(first_param.annotation):
200231
_log.info("Found generic UDF `{n}` {f!r}".format(n=fn_name, f=func))
201232
func(data)

openeo/udf/udf_signatures.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"""
77
# Note: this module was initially developed under the ``openeo-udf`` project (https://github.com/Open-EO/openeo-udf)
88

9+
import xarray
910
from pandas import Series
1011

1112
from openeo.metadata import CollectionMetadata
@@ -85,3 +86,18 @@ def apply_metadata(metadata: CollectionMetadata, context: dict) -> CollectionMet
8586
8687
"""
8788
pass
89+
90+
91+
def apply_vectorcube(
92+
geometries: "geopandas.geodataframe.GeoDataFrame", cube: xarray.DataArray, context: dict
93+
) -> ("geopandas.geodataframe.GeoDataFrame", xarray.DataArray):
94+
"""
95+
Map a vector cube to another vector cube.
96+
97+
:param geometries: input geometries as a geopandas.GeoDataFrame. This contains the actual shapely geometries and optional properties.
98+
:param cube: a data cube with dimensions (geometries, time, bands) where time and bands are optional.
99+
The coordinates for the geometry dimension are integers and match the index of the geometries in the geometries parameter.
100+
:param context: A dictionary containing user context.
101+
:return: output geometries, output data cube
102+
"""
103+
pass

0 commit comments

Comments
 (0)