Skip to content

Commit a7b7b92

Browse files
committed
Issue #197 add more UDF on vector cube tests
1 parent 99f51aa commit a7b7b92

File tree

1 file changed

+164
-9
lines changed

1 file changed

+164
-9
lines changed

tests/test_views_execute.py

+164-9
Original file line numberDiff line numberDiff line change
@@ -3628,7 +3628,14 @@ class TestVectorCubeRunUDF:
36283628
- https://github.com/Open-EO/openeo-geopyspark-driver/issues/437
36293629
"""
36303630

3631-
def test_apply_dimension_run_udf_change_geometry(self, api100):
3631+
@pytest.mark.parametrize(
3632+
"dimension",
3633+
[
3634+
"properties",
3635+
"geometries",
3636+
],
3637+
)
3638+
def test_apply_dimension_run_udf_change_geometry(self, api100, dimension):
36323639
udf_code = """
36333640
from openeo.udf import UdfData, FeatureCollection
36343641
def process_geometries(udf_data: UdfData) -> UdfData:
@@ -3649,7 +3656,7 @@ def process_geometries(udf_data: UdfData) -> UdfData:
36493656
"process_id": "apply_dimension",
36503657
"arguments": {
36513658
"data": {"from_node": "get_vector_data"},
3652-
"dimension": "properties",
3659+
"dimension": dimension,
36533660
"process": {
36543661
"process_graph": {
36553662
"runudf1": {
@@ -3689,19 +3696,17 @@ def process_geometries(udf_data: UdfData) -> UdfData:
36893696
@pytest.mark.parametrize(
36903697
"dimension",
36913698
[
3699+
# TODO: this "dimension="properties" use case does not strictly follow the openEO API spec
3700+
# `apply_dimension` only allows changing the cardinality of the provided dimension ("properties"),
3701+
# not any other dimension ("geometries" here).
36923702
"properties",
36933703
"geometries",
36943704
],
36953705
)
3696-
def test_apply_dimension_run_udf_filter_geometries_dimension_properties(self, api100, dimension):
3706+
def test_apply_dimension_run_udf_filter_on_geometries(self, api100, dimension):
36973707
"""
36983708
Test to use `apply_dimension(dimension="...", process=UDF)` to filter out certain
3699-
entries from geometries dimension.
3700-
3701-
Note in case of dimension="properties":
3702-
strictly speaking, this approach draws outside the lines of the openEO API spec
3703-
as apply_dimension only allows changing the cardinality of the provided dimension ("properties" in this case),
3704-
not any other dimension (like "geometries" in this case).
3709+
entries from geometries dimension based on geometry (e.g. intersection with another geometry)
37053710
"""
37063711
udf_code = """
37073712
from openeo.udf import UdfData, FeatureCollection
@@ -3761,3 +3766,153 @@ def process_geometries(udf_data: UdfData) -> UdfData:
37613766
],
37623767
}
37633768
)
3769+
3770+
@pytest.mark.parametrize(
3771+
"dimension",
3772+
[
3773+
# TODO: this "dimension="properties" use case does not strictly follow the openEO API spec
3774+
# `apply_dimension` only allows changing the cardinality of the provided dimension ("properties"),
3775+
# not any other dimension ("geometries" here).
3776+
"properties",
3777+
"geometries",
3778+
],
3779+
)
3780+
def test_apply_dimension_run_udf_filter_on_properties(self, api100, dimension):
3781+
"""
3782+
Test to use `apply_dimension(dimension="...", process=UDF)` to filter out certain
3783+
entries from geometries dimension, based on feature properties
3784+
3785+
Note in case of dimension="properties":
3786+
strictly speaking, this approach draws outside the lines of the openEO API spec
3787+
as apply_dimension only allows changing the cardinality of the provided dimension ("properties" in this case),
3788+
not any other dimension (like "geometries" in this case).
3789+
"""
3790+
udf_code = """
3791+
from openeo.udf import UdfData, FeatureCollection
3792+
import shapely.geometry
3793+
def process_geometries(udf_data: UdfData) -> UdfData:
3794+
[feature_collection] = udf_data.get_feature_collection_list()
3795+
gdf = feature_collection.data
3796+
gdf = gdf[gdf["pop"] > 500]
3797+
udf_data.set_feature_collection_list([
3798+
FeatureCollection(id="_", data=gdf),
3799+
])
3800+
"""
3801+
udf_code = textwrap.dedent(udf_code)
3802+
process_graph = {
3803+
"get_vector_data": {
3804+
"process_id": "load_uploaded_files",
3805+
"arguments": {"paths": [str(get_path("geojson/FeatureCollection10.json"))], "format": "GeoJSON"},
3806+
},
3807+
"apply_dimension": {
3808+
"process_id": "apply_dimension",
3809+
"arguments": {
3810+
"data": {"from_node": "get_vector_data"},
3811+
"dimension": dimension,
3812+
"process": {
3813+
"process_graph": {
3814+
"runudf1": {
3815+
"process_id": "run_udf",
3816+
"arguments": {
3817+
"data": {"from_node": "get_vector_data"},
3818+
"udf": udf_code,
3819+
"runtime": "Python",
3820+
},
3821+
"result": True,
3822+
}
3823+
},
3824+
},
3825+
},
3826+
"result": True,
3827+
},
3828+
}
3829+
resp = api100.check_result(process_graph)
3830+
assert resp.json == DictSubSet(
3831+
{
3832+
"type": "FeatureCollection",
3833+
"features": [
3834+
{
3835+
"type": "Feature",
3836+
"geometry": ApproxGeoJSONByBounds(6.0, 2.0, 12.0, 6.0, types=["Polygon"], abs=0.1),
3837+
"properties": {"id": "third", "pop": 789},
3838+
},
3839+
{
3840+
"type": "Feature",
3841+
"geometry": ApproxGeoJSONByBounds(-2.0, 7.0, 5.0, 14.0, types=["Polygon"], abs=0.1),
3842+
"properties": {"id": "fourth", "pop": 101112},
3843+
},
3844+
],
3845+
}
3846+
)
3847+
3848+
@pytest.mark.parametrize(
3849+
"dimension",
3850+
[
3851+
"properties",
3852+
# TODO: this "dimension="geometries" use case does not strictly follow the openEO API spec
3853+
# `apply_dimension` only allows changing the cardinality of the provided dimension ("geometries"),
3854+
# not any other dimension ("properties" here).
3855+
"geometries",
3856+
],
3857+
)
3858+
def test_apply_dimension_run_udf_add_properties(self, api100, dimension):
3859+
"""
3860+
Test to use `apply_dimension(dimension="...", process=UDF)` to add properties
3861+
"""
3862+
udf_code = """
3863+
from openeo.udf import UdfData, FeatureCollection
3864+
import shapely.geometry
3865+
def process_geometries(udf_data: UdfData) -> UdfData:
3866+
[feature_collection] = udf_data.get_feature_collection_list()
3867+
gdf = feature_collection.data
3868+
gdf["poppop"] = gdf["pop"] ** 2
3869+
udf_data.set_feature_collection_list([
3870+
FeatureCollection(id="_", data=gdf),
3871+
])
3872+
"""
3873+
udf_code = textwrap.dedent(udf_code)
3874+
process_graph = {
3875+
"get_vector_data": {
3876+
"process_id": "load_uploaded_files",
3877+
"arguments": {"paths": [str(get_path("geojson/FeatureCollection02.json"))], "format": "GeoJSON"},
3878+
},
3879+
"apply_dimension": {
3880+
"process_id": "apply_dimension",
3881+
"arguments": {
3882+
"data": {"from_node": "get_vector_data"},
3883+
"dimension": dimension,
3884+
"process": {
3885+
"process_graph": {
3886+
"runudf1": {
3887+
"process_id": "run_udf",
3888+
"arguments": {
3889+
"data": {"from_node": "get_vector_data"},
3890+
"udf": udf_code,
3891+
"runtime": "Python",
3892+
},
3893+
"result": True,
3894+
}
3895+
},
3896+
},
3897+
},
3898+
"result": True,
3899+
},
3900+
}
3901+
resp = api100.check_result(process_graph)
3902+
assert resp.json == DictSubSet(
3903+
{
3904+
"type": "FeatureCollection",
3905+
"features": [
3906+
{
3907+
"type": "Feature",
3908+
"geometry": ApproxGeoJSONByBounds(1.0, 1.0, 3.0, 3.0, types=["Polygon"], abs=0.1),
3909+
"properties": {"id": "first", "pop": 1234, "poppop": 1234 * 1234},
3910+
},
3911+
{
3912+
"type": "Feature",
3913+
"geometry": ApproxGeoJSONByBounds(3.0, 2.0, 5.0, 4.0, types=["Polygon"], abs=0.1),
3914+
"properties": {"id": "second", "pop": 5678, "poppop": 5678 * 5678},
3915+
},
3916+
],
3917+
}
3918+
)

0 commit comments

Comments
 (0)