Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add apply_vectorcube udf #631

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Added `openeo.api.process.Parameter` helper to easily create a "spatial_extent" UDP parameter
- Wrap OIDC token request failure in more descriptive `OidcException` (related to [#624](https://github.com/Open-EO/openeo-python-client/issues/624))
- 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))
- 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)

### Changed

Expand Down
2 changes: 1 addition & 1 deletion openeo/_version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "0.32.0a1"
__version__ = "0.32.0a2"
33 changes: 32 additions & 1 deletion openeo/udf/run_code.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@ def _annotation_is_data_array(annotation) -> bool:
_get_annotation_str(xarray.DataArray)
}


def _annotation_is_udf_data(annotation) -> bool:
return annotation is UdfData or _get_annotation_str(annotation) in {
_get_annotation_str(UdfData),
Expand Down Expand Up @@ -196,6 +195,38 @@ def run_udf_code(code: str, data: UdfData) -> UdfData:
result_cube: xarray.DataArray = func(cube=data.get_datacube_list()[0].get_array(), context=data.user_context)
data.set_datacube_list([XarrayDataCube(result_cube)])
return data
elif (
fn_name in ["apply_vectorcube"]
and "geometries" in params
and _get_annotation_str(params["geometries"].annotation) == "geopandas.geodataframe.GeoDataFrame"
and "cube" in params
and _annotation_is_data_array(params["cube"].annotation)
):
if data.get_feature_collection_list is None or data.get_datacube_list() is None:
raise ValueError(
"The provided UDF expects a FeatureCollection and a datacube, but received {f} and {c}".format(
f=data.get_feature_collection_list(), c=data.get_datacube_list()
)
)
if len(data.get_feature_collection_list()) != 1:
raise ValueError(
"The provided UDF expects exactly one FeatureCollection, but {c} were provided.".format(
c=len(data.get_feature_collection_list())
)
)
if len(data.get_datacube_list()) != 1:
raise ValueError(
"The provided UDF expects exactly one datacube, but {c} were provided.".format(
c=len(data.get_datacube_list())
)
)
# TODO: geopandas is optional dependency.
JeroenVerstraelen marked this conversation as resolved.
Show resolved Hide resolved
input_geoms = data.get_feature_collection_list()[0].data
input_cube = data.get_datacube_list()[0].get_array()
result_geoms, result_cube = func(geometries=input_geoms, cube=input_cube, context=data.user_context)
data.set_datacube_list([XarrayDataCube(result_cube)])
data.set_feature_collection_list([FeatureCollection(id="udf_result", data=result_geoms)])
return data
elif len(params) == 1 and _annotation_is_udf_data(first_param.annotation):
_log.info("Found generic UDF `{n}` {f!r}".format(n=fn_name, f=func))
func(data)
Expand Down
16 changes: 16 additions & 0 deletions openeo/udf/udf_signatures.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"""
# Note: this module was initially developed under the ``openeo-udf`` project (https://github.com/Open-EO/openeo-udf)

import xarray
from pandas import Series

from openeo.metadata import CollectionMetadata
Expand Down Expand Up @@ -85,3 +86,18 @@ def apply_metadata(metadata: CollectionMetadata, context: dict) -> CollectionMet

"""
pass


def apply_vectorcube(
geometries: "geopandas.geodataframe.GeoDataFrame", cube: xarray.DataArray, context: dict
) -> ("geopandas.geodataframe.GeoDataFrame", xarray.DataArray):
"""
Map a vector cube to another vector cube.

:param geometries: input geometries as a geopandas.GeoDataFrame. This contains the actual shapely geometries and optional properties.
:param cube: a data cube with dimensions (geometries, time, bands) where time and bands are optional.
The coordinates for the geometry dimension are integers and match the index of the geometries in the geometries parameter.
:param context: A dictionary containing user context.
:return: output geometries, output data cube
"""
pass
Loading