Skip to content
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
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed

- Better error message when passing a bounding box with field typos in `Connection.load_collection()` and alike ([#910](https://github.com/Open-EO/openeo-python-client/issues/910))

- Preserve available band metadata when merging data cubes if one cube has no band dimension. ([#783](https://github.com/Open-EO/openeo-python-client/issues/783))

## [0.50.0] - 2026-05-18

Expand Down
20 changes: 9 additions & 11 deletions openeo/rest/datacube.py
Original file line number Diff line number Diff line change
Expand Up @@ -2183,18 +2183,16 @@ def merge_cubes(
arguments = {"cube1": self, "cube2": other}
if overlap_resolver:
arguments["overlap_resolver"] = build_child_callback(overlap_resolver, parent_parameters=["x", "y"])
if (
self.metadata
and self.metadata.has_band_dimension()
and isinstance(other, DataCube)
and other.metadata
and other.metadata.has_band_dimension()
):
# Minimal client side metadata merging
if self.metadata and isinstance(other, DataCube) and other.metadata:
# Minimal client-side metadata merging: preserve metadata when one or
# both cubes have no band dimension, and merge bands when both do.
merged_metadata = self.metadata
for b in other.metadata.band_dimension.bands:
if b not in merged_metadata.bands:
merged_metadata = merged_metadata.append_band(b)
if self.metadata.has_band_dimension() and other.metadata.has_band_dimension():
for b in other.metadata.band_dimension.bands:
if b not in merged_metadata.bands:
merged_metadata = merged_metadata.append_band(b)
elif other.metadata.has_band_dimension():
merged_metadata = other.metadata
else:
merged_metadata = None
# Overlapping bands without overlap resolver will give an error in the backend
Expand Down
26 changes: 26 additions & 0 deletions tests/rest/datacube/test_datacube100.py
Original file line number Diff line number Diff line change
Expand Up @@ -1185,6 +1185,32 @@ def test_merge_cubes_band_merging_with_overlap(con100, requests_mock, overlap_re
assert s4_f_m_s3_f.metadata.band_names == ["B6", "B5", "B8"]


def test_merge_cubes_band_metadata_one_sided(con100):
bands = con100.load_collection("S2")
no_bands = bands.ndvi()

assert bands.metadata.has_band_dimension()
assert not no_bands.metadata.has_band_dimension()
assert bands.merge_cubes(no_bands).metadata.band_names == ["B02", "B03", "B04", "B08"]
assert no_bands.merge_cubes(bands).metadata.band_names == ["B02", "B03", "B04", "B08"]


def test_merge_cubes_metadata_without_band_dimensions(con100):
no_bands = con100.load_collection("S2").ndvi()
merged = no_bands.merge_cubes(no_bands)

assert merged.metadata is no_bands.metadata
assert not merged.metadata.has_band_dimension()


def test_merge_cubes_missing_metadata(con100):
with_metadata = con100.load_collection("S2")
without_metadata = con100.load_collection("S2", fetch_metadata=False)

assert with_metadata.merge_cubes(without_metadata).metadata is None
assert without_metadata.merge_cubes(with_metadata).metadata is None


def test_resample_cube_spatial(con100: Connection):
data = con100.load_collection("S2")
target = con100.load_collection("MASK")
Expand Down