Skip to content

Commit

Permalink
Issue #197 add vector cube UDF test to filter out geometries
Browse files Browse the repository at this point in the history
  • Loading branch information
soxofaan committed Aug 4, 2023
1 parent 4b9c0ef commit 1af1fdf
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 4 deletions.
16 changes: 12 additions & 4 deletions openeo_driver/testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -533,7 +533,15 @@ def to_geojson_feature_collection(self) -> dict:


class ApproxGeoJSONByBounds:
"""pytest assert helper to build a matcher to check if a certain GeoJSON construct is within expected bounds"""
"""
pytest assert helper to build a matcher to check if a certain GeoJSON construct has expected bounds
Usage example:
>>> geometry = {"type": "Polygon", "coordinates": [...]}
# Check that this geometry has bounds (1, 2, 6, 5) with some absolute tolerance
>>> assert geometry == ApproxGeoJSONByBounds(1, 2, 6, 5, abs=0.1)
"""

def __init__(
self,
Expand All @@ -543,8 +551,9 @@ def __init__(
abs: Optional[float] = None,
):
bounds = args[0] if len(args) == 1 else args
assert isinstance(bounds, (list, tuple)) and len(bounds) == 4
self.expected_bounds = [float(b) for b in bounds]
bounds = [float(b) for b in bounds]
assert len(bounds) == 4
self.expected_bounds = bounds
self.rel = rel
self.abs = abs
self.expected_types = set(types)
Expand Down Expand Up @@ -572,7 +581,6 @@ def __repr__(self):
msg += "\n" + "\n".join(f" # {i}" for i in self.actual_info)
return msg


def caplog_with_custom_formatter(caplog: pytest.LogCaptureFixture, format: Union[str, logging.Formatter]):
"""
Context manager to set a custom formatter on the caplog fixture.
Expand Down
37 changes: 37 additions & 0 deletions tests/data/geojson/FeatureCollection10.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {"id": "first", "pop": 123},
"geometry": {
"type": "Polygon",
"coordinates": [[[1, 1], [3, 1], [2, 3], [1, 1]]]
}
},
{
"type": "Feature",
"properties": {"id": "second", "pop": 456},
"geometry": {
"type": "Polygon",
"coordinates": [[[4, 2], [5, 4], [3, 4], [4, 2]]]
}
},
{
"type": "Feature",
"properties": {"id": "third", "pop": 789},
"geometry": {
"type": "Polygon",
"coordinates": [[[6, 2], [10, 2], [12, 6], [8, 6], [6, 2]]]
}
},
{
"type": "Feature",
"properties": {"id": "fourth", "pop": 101112},
"geometry": {
"type": "Polygon",
"coordinates": [[[-2, 7], [5, 7], [5, 14], [-2, 14], [-2, 7]]]
}
}
]
}
68 changes: 68 additions & 0 deletions tests/test_views_execute.py
Original file line number Diff line number Diff line change
Expand Up @@ -3592,3 +3592,71 @@ def process_geometries(udf_data: UdfData) -> UdfData:
],
}
)

def test_apply_dimension_run_udf_filter_geometries_dimension_properties(self, api100):
"""
Test to use `apply_dimension(dimension="properties", process=UDF)` to filter out certain
entries from geometries dimension.
Note that, strictly speaking, this approach draws outside the lines of the openEO API spec
as apply_dimension only allows changing the cardinality of the provided dimension ("properties" in this case),
not any other dimension (like "geometries" in this case).
"""
udf_code = """
from openeo.udf import UdfData, FeatureCollection
import shapely.geometry
def process_geometries(udf_data: UdfData) -> UdfData:
[feature_collection] = udf_data.get_feature_collection_list()
gdf = feature_collection.data
to_intersect = shapely.geometry.box(4, 3, 8, 4)
gdf = gdf[gdf["geometry"].intersects(to_intersect)]
udf_data.set_feature_collection_list([
FeatureCollection(id="_", data=gdf),
])
"""
udf_code = textwrap.dedent(udf_code)
process_graph = {
"get_vector_data": {
"process_id": "load_uploaded_files",
"arguments": {"paths": [str(get_path("geojson/FeatureCollection10.json"))], "format": "GeoJSON"},
},
"apply_dimension": {
"process_id": "apply_dimension",
"arguments": {
"data": {"from_node": "get_vector_data"},
"dimension": "properties",
"process": {
"process_graph": {
"runudf1": {
"process_id": "run_udf",
"arguments": {
"data": {"from_node": "get_vector_data"},
"udf": udf_code,
"runtime": "Python",
},
"result": True,
}
},
},
},
"result": True,
},
}
resp = api100.check_result(process_graph)
assert resp.json == DictSubSet(
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": ApproxGeoJSONByBounds(3, 2, 5, 4, types=["Polygon"], abs=0.1),
"properties": {"id": "second", "pop": 456},
},
{
"type": "Feature",
"geometry": ApproxGeoJSONByBounds(6, 2, 12, 6, types=["Polygon"], abs=0.1),
"properties": {"id": "third", "pop": 789},
},
],
}
)

0 comments on commit 1af1fdf

Please sign in to comment.