Skip to content

Commit 9f02cd2

Browse files
bossiejdries
authored andcommitted
spatial_extent: require (Multi)Polygons
* disallow Point Feature Open-EO/openeo-geopyspark-driver#996 * test FeatureCollection of Points Open-EO/openeo-geopyspark-driver#996 * test some supported geometries Open-EO/openeo-geopyspark-driver#996 * tune TODOs Open-EO/openeo-geopyspark-driver#996 * update version and CHANGELOG Open-EO/openeo-geopyspark-driver#996 * remove duplicate entry Open-EO/openeo-geopyspark-driver#996 Co-authored-by: Jeroen Dries <jeroen.dries@vito.be> * address review remarks - require _all_ (Multi)Polygons - drop support for deprecated GeometryCollection Open-EO/openeo-geopyspark-driver#996 --------- Co-authored-by: Jeroen Dries <jeroen.dries@vito.be>
1 parent a4fe263 commit 9f02cd2

File tree

5 files changed

+97
-11
lines changed

5 files changed

+97
-11
lines changed

CHANGELOG.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,15 @@ and start a new "In Progress" section above it.
2323

2424
- array_apply: sub-process should now work on all supported processes ([Open-EO/openeo-geopyspark-driver#1064](https://github.com/Open-EO/openeo-geopyspark-driver/issues/1064))
2525

26+
## 0.128.0
27+
28+
- `load_collection`/`load_stac`: `spatial_extent` requires (Multi)Polygon geometries ([Open-EO/openeo-geopyspark-driver#996](https://github.com/Open-EO/openeo-geopyspark-driver/issues/996))
29+
2630
## 0.127.0
2731

2832
- Add `simple_job_progress_estimation` config for simple job progress estimation ([Open-EO/openeo-geopyspark-driver#772](https://github.com/Open-EO/openeo-geopyspark-driver/issues/772))
2933
- `OpenEoBackendConfig`: be more forgiving about unknown config keys to better support use cases that involve backward/forward incompatible configurations ([#322](https://github.com/Open-EO/openeo-python-driver/issues/322))
3034

31-
3235
## 0.126.0
3336

3437
- Add STAC collections conformance class ([#195](https://github.com/Open-EO/openeo-python-driver/issues/195))

openeo_driver/ProcessGraphDeserializer.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1461,13 +1461,21 @@ def filter_labels(args: ProcessArgs, env: EvalEnv) -> DriverDataCube:
14611461

14621462
def _extract_bbox_extent(args: dict, field="extent", process_id="filter_bbox", handle_geojson=False) -> dict:
14631463
extent = extract_arg(args, name=field, process_id=process_id)
1464+
# TODO #114: support vector cube
14641465
if handle_geojson and extent.get("type") in [
14651466
"Polygon",
14661467
"MultiPolygon",
1467-
"GeometryCollection",
1468+
"GeometryCollection", # TODO #71 #114: deprecate GeometryCollection
14681469
"Feature",
14691470
"FeatureCollection",
14701471
]:
1472+
if not _contains_only_polygons(extent):
1473+
raise ProcessParameterInvalidException(
1474+
parameter=field,
1475+
process=process_id,
1476+
reason="unsupported GeoJSON; requires at least one Polygon or MultiPolygon",
1477+
)
1478+
14711479
w, s, e, n = DriverVectorCube.from_geojson(extent).get_bounding_box()
14721480
# TODO: support (non-standard) CRS field in GeoJSON?
14731481
d = {"west": w, "south": s, "east": e, "north": n, "crs": "EPSG:4326"}
@@ -1483,6 +1491,19 @@ def _extract_bbox_extent(args: dict, field="extent", process_id="filter_bbox", h
14831491
return d
14841492

14851493

1494+
def _contains_only_polygons(geojson: dict) -> bool:
1495+
if geojson["type"] in ["Polygon", "MultiPolygon"]:
1496+
return True
1497+
1498+
if geojson["type"] == "Feature":
1499+
return _contains_only_polygons(geojson["geometry"])
1500+
1501+
if geojson["type"] == "FeatureCollection":
1502+
return all(_contains_only_polygons(feature) for feature in geojson["features"])
1503+
1504+
return False
1505+
1506+
14861507
@process
14871508
def filter_bbox(args: ProcessArgs, env: EvalEnv) -> DriverDataCube:
14881509
cube: DriverDataCube = args.get_required("data", expected_type=DriverDataCube)

openeo_driver/_version.py

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

tests/test_dry_run.py

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from contextlib import nullcontext
12
from pathlib import Path
23
from unittest import mock
34

@@ -18,7 +19,7 @@
1819
ProcessType,
1920
)
2021
from openeo_driver.dummy.dummy_backend import DummyVectorCube
21-
from openeo_driver.errors import OpenEOApiException
22+
from openeo_driver.errors import OpenEOApiException, ProcessParameterInvalidException
2223
from openeo_driver.ProcessGraphDeserializer import (
2324
ENV_DRY_RUN_TRACER,
2425
ENV_MAX_BUFFER,
@@ -1447,6 +1448,74 @@ def test_load_stac_properties(dry_run_env, dry_run_tracer):
14471448
]
14481449

14491450

1451+
@pytest.mark.parametrize(
1452+
["spatial_extent", "expectation"],
1453+
[
1454+
({"type": "Polygon", "coordinates": [[[0, 0], [1, 1], [1, 0]]]}, nullcontext()),
1455+
(
1456+
{
1457+
"type": "Feature",
1458+
"geometry": {"type": "MultiPolygon", "coordinates": [[[[0, 0], [1, 1], [1, 0]]]]},
1459+
"properties": {},
1460+
},
1461+
nullcontext(),
1462+
),
1463+
(
1464+
{
1465+
"type": "Feature",
1466+
"geometry": {"type": "Point", "coordinates": [5, 50]},
1467+
"properties": {},
1468+
},
1469+
pytest.raises(
1470+
ProcessParameterInvalidException,
1471+
match=r"unsupported GeoJSON; requires at least one Polygon or MultiPolygon$",
1472+
),
1473+
),
1474+
(
1475+
{
1476+
"type": "FeatureCollection",
1477+
"features": [
1478+
{
1479+
"type": "Feature",
1480+
"geometry": {"type": "Point", "coordinates": [5, 50]},
1481+
"properties": {},
1482+
},
1483+
{
1484+
"type": "Feature",
1485+
"geometry": {"type": "Polygon", "coordinates": [[[0, 0], [1, 1], [1, 0]]]},
1486+
"properties": {},
1487+
},
1488+
],
1489+
},
1490+
pytest.raises(
1491+
ProcessParameterInvalidException,
1492+
match=r"unsupported GeoJSON; requires at least one Polygon or MultiPolygon$",
1493+
),
1494+
),
1495+
],
1496+
)
1497+
def test_load_stac_spatial_extent_requires_a_polygon(
1498+
dry_run_tracer, backend_implementation, spatial_extent, expectation
1499+
):
1500+
pg = {
1501+
"loadstac1": {
1502+
"process_id": "load_stac",
1503+
"arguments": {
1504+
"url": "https://stac.test",
1505+
"spatial_extent": spatial_extent,
1506+
},
1507+
"result": True,
1508+
}
1509+
}
1510+
1511+
dry_run_env = EvalEnv(
1512+
{ENV_DRY_RUN_TRACER: dry_run_tracer, "backend_implementation": backend_implementation, "version": "2.0.0"}
1513+
)
1514+
1515+
with expectation:
1516+
evaluate(pg, dry_run_env)
1517+
1518+
14501519
@pytest.mark.parametrize(
14511520
["arguments", "expected"],
14521521
[

tests/test_views_execute.py

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -353,13 +353,6 @@ def test_load_collection_filter(api):
353353
),
354354
{"west": 11, "south": 22, "east": 44, "north": 55, "crs": "EPSG:4326"},
355355
),
356-
(
357-
as_geojson_feature_collection(
358-
shapely.geometry.Point(2, 3),
359-
shapely.geometry.Point(4, 5),
360-
),
361-
{"west": 2, "south": 3, "east": 4, "north": 5, "crs": "EPSG:4326"},
362-
),
363356
],
364357
)
365358
def test_load_collection_spatial_extent_geojson(api, spatial_extent, expected):

0 commit comments

Comments
 (0)