Skip to content

Commit 21e6151

Browse files
authored
#334 global extent buffer
* #334 reproject bbox before applying buffer, add resample to mask * #334 to_scl_dilation_mask should block resampling params * #334 test fixes * #334 add test * #334 fix test * #334 extra check on actual resampling * #334 test fixes
1 parent 122a18f commit 21e6151

File tree

5 files changed

+5807
-17
lines changed

5 files changed

+5807
-17
lines changed

openeo_driver/ProcessGraphDeserializer.py

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717

1818
import geopandas as gpd
1919
import numpy as np
20+
from pyproj import CRS
21+
from pyproj.exceptions import CRSError
2022

2123
import openeo.udf
2224
import openeo_processes
@@ -506,6 +508,15 @@ def extract_arg(args: ProcessArgs, name: str, process_id="n/a"):
506508
# TODO: eliminate this function, use `ProcessArgs.get_required()` directly
507509
return _as_process_args(args, process_id=process_id).get_required(name=name)
508510

511+
def _collection_crs(collection_id, env) -> str:
512+
metadata = None
513+
try:
514+
metadata = env.backend_implementation.catalog.get_collection_metadata(collection_id)
515+
except CollectionNotFoundException:
516+
return None
517+
crs = metadata.get('cube:dimensions', {}).get('x', {}).get('reference_system', None)
518+
return crs
519+
509520

510521
def _align_extent(extent,collection_id,env,target_resolution=None):
511522
metadata = None
@@ -593,18 +604,37 @@ def _extract_load_parameters(env: EvalEnv, source_id: tuple) -> LoadParameters:
593604
if "weak_spatial_extent" in constraint:
594605
extent = constraint["weak_spatial_extent"]
595606
if extent is not None:
607+
collection_crs = _collection_crs(collection_id[1][0], env)
608+
crs = constraint.get("resample", {}).get("target_crs", collection_crs)
609+
596610
if "pixel_buffer" in constraint:
597-
buffer = constraint["pixel_buffer"]["buffer_size"]
598-
extent = {
599-
"west": extent["west"] - buffer[0],
600-
"east": extent["east"] + buffer[0],
601-
"south": extent["south"] - buffer[1],
602-
"north": extent["north"] + buffer[1],
603-
"crs": extent["crs"]
604-
}
605611

612+
buffer = constraint["pixel_buffer"]["buffer_size"]
606613

607-
if "resample" not in constraint or not constraint["resample"].get("target_crs",None):
614+
if crs is not None:
615+
bbox = BoundingBox.from_dict(extent, default_crs=4326)
616+
extent = bbox.reproject(crs).as_dict()
617+
618+
extent = {
619+
"west": extent["west"] - buffer[0],
620+
"east": extent["east"] + buffer[0],
621+
"south": extent["south"] - buffer[1],
622+
"north": extent["north"] + buffer[1],
623+
"crs": extent["crs"]
624+
}
625+
else:
626+
_log.warning("Not applying buffer to extent because the target CRS is not known.")
627+
628+
no_resampling = "resample" not in constraint or crs == collection_crs
629+
if (not no_resampling) and collection_crs is not None and ("42001" in str(collection_crs)):
630+
#resampling auto utm to utm is still considered no resampling
631+
try:
632+
no_resampling = "UTM zone" in CRS.from_user_input(crs).to_wkt()
633+
except CRSError as e:
634+
pass
635+
636+
637+
if no_resampling:
608638
# Ensure that the extent that the user provided is aligned with the collection's native grid.
609639
target_resolution = constraint.get("resample",{}).get("resolution",None)
610640
extent = _align_extent(extent, collection_id[1][0], env,target_resolution)

openeo_driver/dry_run.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,7 @@ def get_source_constraints(self, merge=True) -> List[SourceConstraint]:
371371
# under the condition that no operations occur in between that may be affected
372372
for op in [
373373
"apply_kernel", "reduce_dimension", "apply", "apply_dimension",
374-
"apply_neighborhood", "reduce_dimension_binary", "mask"
374+
"apply_neighborhood", "reduce_dimension_binary", "mask", "to_scl_dilation_mask"
375375
]:
376376
args = resampling_op.get_arguments_by_operation(op)
377377
if args:
@@ -539,9 +539,10 @@ def filter_labels(self, condition: dict,dimension: str, context: Optional[dict]
539539
def mask(self, mask: 'DryRunDataCube', replacement=None) -> 'DryRunDataCube':
540540
# TODO: if mask cube has no temporal or bbox extent: copy from self?
541541
# TODO: or add reference to the self trace to the mask trace and vice versa?
542-
cube = self._process("mask", {"mask": mask})
542+
mask_resampled = mask._process("resample_cube_spatial", arguments={"target": self, "method": "near"})
543+
cube = self._process("mask", {"mask": mask_resampled})
543544
return DryRunDataCube(
544-
traces=cube._traces + mask._traces, data_tracer=cube._data_tracer,
545+
traces=cube._traces + mask_resampled._traces, data_tracer=cube._data_tracer,
545546
metadata=cube.metadata
546547
)
547548

@@ -783,6 +784,7 @@ def to_scl_dilation_mask(
783784
cube = self._process("process_type", [ProcessType.FOCAL_SPACE])
784785
size = kernel2_size
785786
cube = cube._process("pixel_buffer", arguments={"buffer_size": [size/2.0,size/2.0]})
787+
cube = cube._process("to_scl_dilation_mask", arguments={})
786788
return cube
787789

788790
def mask_l1c(self) -> 'DriverDataCube':

openeo_driver/util/geometry.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,7 @@ def __init__(
458458

459459
@staticmethod
460460
def normalize_crs(crs: Union[str, int]) -> str:
461-
if crs == "Auto42001":
461+
if crs == "Auto42001" or crs == "AUTO:42001":
462462
return crs
463463
proj_crs = CRS.from_user_input(crs)
464464
maybeEPSG = proj_crs.to_epsg()
@@ -547,6 +547,10 @@ def reproject(self, crs) -> "BoundingBox":
547547
"""
548548
self.assert_crs()
549549
crs = self.normalize_crs(crs)
550+
isUTM = crs == "AUTO:42001" or "Auto42001" in str(crs)
551+
if isUTM:
552+
return self.reproject_to_best_utm()
553+
550554
if crs == self.crs:
551555
return self
552556
transform = pyproj.Transformer.from_crs(

0 commit comments

Comments
 (0)