diff --git a/xcube_stac/_utils.py b/xcube_stac/_utils.py index 7134e9c..b9276fa 100644 --- a/xcube_stac/_utils.py +++ b/xcube_stac/_utils.py @@ -570,11 +570,11 @@ def get_gridmapping( crs: Union[str, pyproj.crs.CRS], tile_size: Union[int, tuple[int, int]] = TILE_SIZE, ) -> GridMapping: - x_size = int((bbox[2] - bbox[0]) / spatial_res) + 1 - y_size = int(abs(bbox[3] - bbox[1]) / spatial_res) + 1 + x_size = int((bbox[2] - bbox[0]) / spatial_res) + y_size = int(abs(bbox[3] - bbox[1]) / spatial_res) return GridMapping.regular( size=(x_size, y_size), - xy_min=(bbox[0] - spatial_res / 2, bbox[1] - spatial_res / 2), + xy_min=(bbox[0], bbox[1]), xy_res=spatial_res, crs=crs, tile_size=tile_size, diff --git a/xcube_stac/stac_extension/raster.py b/xcube_stac/stac_extension/raster.py index 4c6fbe2..0a18dc1 100644 --- a/xcube_stac/stac_extension/raster.py +++ b/xcube_stac/stac_extension/raster.py @@ -37,3 +37,29 @@ def apply_offset_scaling( offset = raster_bands[0].get("offset", 0) ds[asset_name] += offset return ds + + +def apply_offset_scaling_odc_stac(ds: xr.Dataset, grouped_items: dict) -> xr.Dataset: + for asset_name in ds.key(): + if asset_name == "crs" or asset_name == "spatial_ref": + continue + for i, (date, items) in enumerate(grouped_items): + raster_bands = items[0].assets[asset_name].extra_fields.get("raster:bands") + if raster_bands is None: + LOG.warning( + f"Item {items[0].id} is not conform to the stac-extension " + f"'raster'. No scaling is applied." + ) + return ds + + if asset_name.lower() != "scl": + nodata_val = raster_bands[0].get("nodata") + if nodata_val is not None: + ds[asset_name][i] = ds[asset_name][i].where( + ds[asset_name] != nodata_val + ) + scale = raster_bands[0].get("scale", 1) + ds[asset_name][i] *= scale + offset = raster_bands[0].get("offset", 0) + ds[asset_name][i] += offset + return ds diff --git a/xcube_stac/store_mode.py b/xcube_stac/store_mode.py index cff081e..f18cf90 100644 --- a/xcube_stac/store_mode.py +++ b/xcube_stac/store_mode.py @@ -45,6 +45,7 @@ from .constants import TILE_SIZE from .mldataset import SingleItemMultiLevelDataset from .stac_extension.raster import apply_offset_scaling +from .stac_extension.raster import apply_offset_scaling_odc_stac from ._utils import ( merge_datasets, rename_dataset, @@ -526,7 +527,10 @@ def open_data( items_odc_stac = [ item for sublist in grouped_items.values() for item in sublist ] - items = [self._helper.parse_item(item, **open_params) for item in items] + items_odc_stac = [ + self._helper.parse_item(item, **open_params) + for item in items_odc_stac + ] bbox = open_params["bbox"] odc_stac_params = dict( bands=open_params.get("asset_names"), @@ -541,6 +545,8 @@ def open_data( items_odc_stac, **odc_stac_params, ) + ds = apply_offset_scaling_odc_stac(ds, grouped_items) + else: ds = self.stack_items(grouped_items, **open_params) ds.attrs["stac_catalog_url"] = self._catalog.get_self_href()