Skip to content
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
23 changes: 23 additions & 0 deletions openeo_driver/dry_run.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
from openeo_driver.util.geometry import (
BoundingBox,
GeometryBufferer,
is_auto_utm_crs,
geojson_to_geometry, reproject_geometry,
)
import openeo_driver.stac.datacube
Expand Down Expand Up @@ -662,7 +663,29 @@ def filter_labels(
) -> "DryRunDataCube":
return self._process("filter_labels", arguments=dict(condition=condition, dimension=dimension, context=context))

@staticmethod
def _spatial_crs(cube: "DryRunDataCube") -> Optional[str]:
"""Normalized CRS of the cube's spatial dimensions, or None if unknown."""
if cube.metadata is None:
return None
for dim in cube.metadata.spatial_dimensions:
if dim.crs is not None:
try:
crs = BoundingBox.normalize_crs(dim.crs)
except Exception:
return None
# Auto UTM is resolved later, so it can't be compared yet
return None if is_auto_utm_crs(crs) else crs
return None

def mask(self, mask: "DryRunDataCube", replacement=None) -> "DryRunDataCube":
data_crs = self._spatial_crs(self)
mask_crs = self._spatial_crs(mask)
if data_crs is not None and mask_crs is not None and data_crs != mask_crs:
_log.warning(
f"Masking between cubes with different CRS: data cube has CRS {data_crs}, mask has CRS {mask_crs}."
" The mask will be resampled with nearest neighbour, which may give unexpected results."
)
# TODO: if mask cube has no temporal or bbox extent: copy from self?
# TODO: or add reference to the self trace to the mask trace and vice versa?
mask_resampled = mask._process("resample_cube_spatial", arguments={"target": self, "method": "near"})
Expand Down
28 changes: 28 additions & 0 deletions tests/test_dry_run.py
Original file line number Diff line number Diff line change
Expand Up @@ -607,6 +607,34 @@ def test_mask_polygon_and_filter_bbox(dry_run_env, dry_run_tracer, bbox_first):
}


def _load_collection_in_crs(collection_id: str, epsg: int) -> DataCube:
cube = DataCube(PGNode("load_collection", id=collection_id), connection=None)
return cube.resample_spatial(resolution=10, projection=epsg)


def test_mask_cubes_different_crs_warns(dry_run_env, dry_run_tracer, caplog):
"""https://github.com/Open-EO/openeo-python-driver/issues/436"""
cube = _load_collection_in_crs("S2_FOOBAR", epsg=32631)
mask = _load_collection_in_crs("S2_FOOBAR", epsg=3035)
pg = cube.mask(mask=mask).flat_graph()

caplog.set_level(logging.WARNING)
evaluate(pg, env=dry_run_env, do_dry_run=False)

assert "Masking between cubes with different CRS: data cube has CRS EPSG:32631, mask has CRS EPSG:3035" in caplog.text


def test_mask_cubes_same_crs_ok(dry_run_env, dry_run_tracer, caplog):
cube = _load_collection_in_crs("S2_FOOBAR", epsg=32631)
mask = _load_collection_in_crs("S2_FOOBAR", epsg=32631)
pg = cube.mask(mask=mask).flat_graph()

caplog.set_level(logging.WARNING)
evaluate(pg, env=dry_run_env, do_dry_run=False)

assert "different CRS" not in caplog.text


def test_aggregate_spatial_only(dry_run_env, dry_run_tracer):
polygon = {"type": "Polygon", "coordinates": [[(0, 0), (3, 5), (8, 2), (0, 0)]]}
pg = {
Expand Down
Loading