Skip to content

Commit 33d626b

Browse files
committed
saveRDDAllowAssetPerBand: handle items instead of files #1111
1 parent 7409ad1 commit 33d626b

File tree

2 files changed

+134
-16
lines changed

2 files changed

+134
-16
lines changed

openeogeotrellis/geopysparkdatacube.py

+33-14
Original file line numberDiff line numberDiff line change
@@ -2108,7 +2108,7 @@ def add_gdalinfo_objects(assets_original):
21082108
}
21092109
)
21102110
else:
2111-
paths_tuples = get_jvm().org.openeo.geotrellis.geotiff.package.saveRDDAllowAssetPerBand(
2111+
java_items = get_jvm().org.openeo.geotrellis.geotiff.package.saveRDDAllowAssetPerBand(
21122112
max_level_rdd,
21132113
band_count,
21142114
str(save_filename),
@@ -2117,21 +2117,40 @@ def add_gdalinfo_objects(assets_original):
21172117
gtiff_options,
21182118
)
21192119

2120-
assets = {}
2121-
for path, bbox, band_indices in map(to_tuple, paths_tuples):
2122-
file_name = str(pathlib.Path(path).relative_to(save_directory))
2123-
assets[file_name] = {
2124-
"href": str(path),
2125-
"type": "image/tiff; application=geotiff",
2126-
"roles": ["data"],
2127-
"bands": [band for i, band in enumerate(bands) if i in band_indices],
2128-
"nodata": nodata,
2120+
items = {}
2121+
for java_item in java_items:
2122+
assets = {}
2123+
2124+
bbox = java_item.bbox()
2125+
2126+
for asset_key, asset in java_item.assets().items():
2127+
path = asset.path()
2128+
band_indices = asset.bandIndices()
2129+
2130+
assets[asset_key] = {
2131+
"href": str(path),
2132+
"type": "image/tiff; application=geotiff",
2133+
"roles": ["data"],
2134+
"bands": [band for i, band in enumerate(bands) if i in band_indices],
2135+
"nodata": nodata,
2136+
}
2137+
if bbox:
2138+
assets[asset_key]["bbox"] = to_latlng_bbox(bbox)
2139+
assets[asset_key]["geometry"] = mapping(
2140+
Polygon.from_bounds(*to_latlng_bbox(bbox))
2141+
)
2142+
2143+
assets = add_gdalinfo_objects(assets)
2144+
item = {
2145+
"id": java_item.id(),
2146+
"geometry": mapping(Polygon.from_bounds(*to_latlng_bbox(bbox))),
2147+
"bbox": to_latlng_bbox(bbox),
2148+
"assets": assets,
21292149
}
2130-
if bbox:
2131-
assets[file_name]["bbox"] = to_latlng_bbox(bbox)
2132-
assets[file_name]["geometry"] = mapping(Polygon.from_bounds(*to_latlng_bbox(bbox)))
21332150

2134-
return add_gdalinfo_objects(assets)
2151+
items[java_item.id()] = item
2152+
2153+
return items
21352154

21362155
else:
21372156
if not save_filename.endswith(".png"):

tests/test_batch_result.py

+101-2
Original file line numberDiff line numberDiff line change
@@ -2624,8 +2624,10 @@ def apply_datacube(cube: XarrayDataCube, context: dict) -> XarrayDataCube:
26242624
),
26252625
],
26262626
)
2627-
def test_unified_asset_keys(tmp_path, separate_asset_per_band, expected_tiff_files, expected_asset_keys):
2628-
process_graph = { # plain old spatiotemporal data cube to GeoTIFF
2627+
def test_unified_asset_keys_spatiotemporal_geotiff(
2628+
tmp_path, separate_asset_per_band, expected_tiff_files, expected_asset_keys
2629+
):
2630+
process_graph = {
26292631
"load2": {
26302632
"process_id": "load_collection",
26312633
"arguments": {
@@ -2842,3 +2844,100 @@ def test_unified_asset_keys_sample_by_feature(tmp_path):
28422844

28432845
for item in items:
28442846
assert set(item["assets"].keys()) == {"openEO"}
2847+
2848+
2849+
@pytest.mark.parametrize(
2850+
["separate_asset_per_band", "expected_tiff_files", "expected_asset_keys"],
2851+
[
2852+
(False, {"openEO.tif"}, {"openEO"}),
2853+
(
2854+
True,
2855+
{
2856+
"openEO_Flat:0.tif",
2857+
"openEO_Flat:1.tif",
2858+
"openEO_Flat:2.tif",
2859+
},
2860+
{"openEO_Flat:0", "openEO_Flat:1", "openEO_Flat:2"},
2861+
),
2862+
],
2863+
)
2864+
def test_unified_asset_keys_spatial_geotiff(
2865+
tmp_path, separate_asset_per_band, expected_tiff_files, expected_asset_keys
2866+
):
2867+
process_graph = {
2868+
"load2": {
2869+
"process_id": "load_collection",
2870+
"arguments": {
2871+
"bands": [
2872+
"Flat:0",
2873+
"Flat:1",
2874+
"Flat:2",
2875+
],
2876+
"id": "TestCollection-LonLat16x16",
2877+
"spatial_extent": {
2878+
"west": 0,
2879+
"south": 50,
2880+
"east": 5,
2881+
"north": 55,
2882+
},
2883+
"temporal_extent": ["2025-04-01", "2025-04-21"],
2884+
},
2885+
},
2886+
"reducedimension1": {
2887+
"process_id": "reduce_dimension",
2888+
"arguments": {
2889+
"data": {"from_node": "load2"},
2890+
"dimension": "t",
2891+
"reducer": {
2892+
"process_graph": {
2893+
"first1": {
2894+
"process_id": "first",
2895+
"arguments": {"data": {"from_parameter": "data"}},
2896+
"result": True,
2897+
}
2898+
}
2899+
},
2900+
},
2901+
},
2902+
"save1": {
2903+
"process_id": "save_result",
2904+
"arguments": {
2905+
"data": {"from_node": "reducedimension1"},
2906+
"format": "GTIFF",
2907+
"options": {"separate_asset_per_band": separate_asset_per_band},
2908+
},
2909+
"result": True,
2910+
},
2911+
}
2912+
2913+
process = {
2914+
"process_graph": process_graph,
2915+
}
2916+
2917+
job_dir = tmp_path
2918+
metadata_file = job_dir / "job_metadata.json"
2919+
2920+
run_job(
2921+
process,
2922+
output_file=job_dir / "out",
2923+
metadata_file=metadata_file,
2924+
api_version="2.0.0",
2925+
job_dir=job_dir,
2926+
dependencies=[],
2927+
)
2928+
2929+
tiff_files = {file for file in os.listdir(job_dir) if file.endswith(".tif")}
2930+
assert tiff_files == expected_tiff_files
2931+
2932+
with open(metadata_file) as f:
2933+
job_metadata = json.load(f)
2934+
2935+
items = job_metadata["items"]
2936+
print(f"items={json.dumps(items, indent=2)}")
2937+
2938+
assert len(items) == 1
2939+
# single item ID can be anything (no spatial or temporal references)
2940+
assert job_metadata["start_datetime"] == "2025-04-01T00:00:00Z" # top-level rather than on Item
2941+
assert job_metadata["end_datetime"] == "2025-04-21T00:00:00Z" # ditto
2942+
2943+
assert set(items[0]["assets"].keys()) == expected_asset_keys

0 commit comments

Comments
 (0)