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

disallow Points #356

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
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
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,11 @@ and start a new "In Progress" section above it.

## In progress

## 0.126.0

- Add STAC collections conformance class ([#195](https://github.com/Open-EO/openeo-python-driver/issues/195))
- update openeo_driver/specs/openeo-api/1.x submodule to tag `1.2.0` ([#195](https://github.com/Open-EO/openeo-python-driver/issues/195))
- `load_collection`/`load_stac`: `spatial_extent` requires a (Multi)Polygon geometry ([Open-EO/openeo-geopyspark-driver#996](https://github.com/Open-EO/openeo-geopyspark-driver/issues/996))


## 0.125.0
Expand Down
25 changes: 25 additions & 0 deletions openeo_driver/ProcessGraphDeserializer.py
Original file line number Diff line number Diff line change
Expand Up @@ -1460,13 +1460,22 @@ def filter_labels(args: ProcessArgs, env: EvalEnv) -> DriverDataCube:

def _extract_bbox_extent(args: dict, field="extent", process_id="filter_bbox", handle_geojson=False) -> dict:
extent = extract_arg(args, name=field, process_id=process_id)
# TODO #114: support vector cube
if handle_geojson and extent.get("type") in [
"Polygon",
"MultiPolygon",
"GeometryCollection", # TODO #71 #114: deprecate GeometryCollection
"GeometryCollection",
"Feature",
"FeatureCollection",
]:
if not _contains_polygon(extent):
raise ProcessParameterInvalidException(
parameter=field,
process=process_id,
reason="unsupported GeoJSON; requires at least one Polygon or MultiPolygon",
)

w, s, e, n = DriverVectorCube.from_geojson(extent).get_bounding_box()
# TODO: support (non-standard) CRS field in GeoJSON?
d = {"west": w, "south": s, "east": e, "north": n, "crs": "EPSG:4326"}
Expand All @@ -1482,6 +1491,22 @@ def _extract_bbox_extent(args: dict, field="extent", process_id="filter_bbox", h
return d


def _contains_polygon(geojson: dict) -> bool:
if geojson["type"] in ["Polygon", "MultiPolygon"]:
return True

if geojson["type"] == "Feature":
return _contains_polygon(geojson["geometry"])

if geojson["type"] == "FeatureCollection":
return any(_contains_polygon(feature) for feature in geojson["features"])

if geojson["type"] == "GeometryCollection":
return any(_contains_polygon(geometry) for geometry in geojson["geometries"])

return False


@process
def filter_bbox(args: ProcessArgs, env: EvalEnv) -> DriverDataCube:
cube: DriverDataCube = args.get_required("data", expected_type=DriverDataCube)
Expand Down
2 changes: 1 addition & 1 deletion openeo_driver/_version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "0.125.0a1"
__version__ = "0.126.0a1"
61 changes: 60 additions & 1 deletion tests/test_dry_run.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from contextlib import nullcontext
from pathlib import Path
from unittest import mock

Expand All @@ -18,7 +19,7 @@
ProcessType,
)
from openeo_driver.dummy.dummy_backend import DummyVectorCube
from openeo_driver.errors import OpenEOApiException
from openeo_driver.errors import OpenEOApiException, ProcessParameterInvalidException
from openeo_driver.ProcessGraphDeserializer import (
ENV_DRY_RUN_TRACER,
ENV_MAX_BUFFER,
Expand Down Expand Up @@ -1447,6 +1448,64 @@ def test_load_stac_properties(dry_run_env, dry_run_tracer):
]


@pytest.mark.parametrize(
["spatial_extent", "expectation"],
[
({"type": "Polygon", "coordinates": [[[0, 0], [1, 1], [1, 0]]]}, nullcontext()),
(
{
"type": "Feature",
"geometry": {"type": "MultiPolygon", "coordinates": [[[[0, 0], [1, 1], [1, 0]]]]},
"properties": {},
},
nullcontext(),
),
(
{"type": "Feature", "geometry": {"type": "Point", "coordinates": [5, 50]}},
pytest.raises(
ProcessParameterInvalidException,
match=r"unsupported GeoJSON; requires at least one Polygon or MultiPolygon$",
),
),
(
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {"type": "Point", "coordinates": [5, 50]},
}
],
},
pytest.raises(
ProcessParameterInvalidException,
match=r"unsupported GeoJSON; requires at least one Polygon or MultiPolygon$",
),
),
],
)
def test_load_stac_spatial_extent_requires_a_polygon(
dry_run_tracer, backend_implementation, spatial_extent, expectation
):
pg = {
"loadstac1": {
"process_id": "load_stac",
"arguments": {
"url": "https://stac.test",
"spatial_extent": spatial_extent,
},
"result": True,
}
}

dry_run_env = EvalEnv(
{ENV_DRY_RUN_TRACER: dry_run_tracer, "backend_implementation": backend_implementation, "version": "2.0.0"}
)

with expectation:
evaluate(pg, dry_run_env)


@pytest.mark.parametrize(
["arguments", "expected"],
[
Expand Down
7 changes: 0 additions & 7 deletions tests/test_views_execute.py
Original file line number Diff line number Diff line change
Expand Up @@ -352,13 +352,6 @@ def test_load_collection_filter(api):
),
{"west": 11, "south": 22, "east": 44, "north": 55, "crs": "EPSG:4326"},
),
(
as_geojson_feature_collection(
shapely.geometry.Point(2, 3),
shapely.geometry.Point(4, 5),
),
{"west": 2, "south": 3, "east": 4, "north": 5, "crs": "EPSG:4326"},
),
],
)
def test_load_collection_spatial_extent_geojson(api, spatial_extent, expected):
Expand Down