diff --git a/docs/history.rst b/docs/history.rst index c381976c..a8609571 100644 --- a/docs/history.rst +++ b/docs/history.rst @@ -3,6 +3,7 @@ History Unreleased ---------- +- BUG: Preserve requested bounds when resampling merge inputs (#859) - ENH: Add write support for Zarr spatial and proj conventions 0.22.0 diff --git a/rioxarray/merge.py b/rioxarray/merge.py index f9d6212f..73192290 100644 --- a/rioxarray/merge.py +++ b/rioxarray/merge.py @@ -9,6 +9,8 @@ import numpy from rasterio.crs import CRS from rasterio.merge import merge as _rio_merge +from rasterio.transform import Affine +from rasterio.windows import transform as _rio_window_transform from xarray import DataArray, Dataset, IndexVariable from rioxarray._spatial_utils import _get_nonspatial_coords, _make_coords @@ -60,9 +62,10 @@ def read(self, window, out_shape, *args, **kwargs) -> numpy.ma.MaskedArray: _, out_height, out_width = out_shape else: out_height, out_width = out_shape - data_window = self._xds.rio.reproject( - self._xds.rio.crs, - transform=self.transform, + data_window = data_window.rio.reproject( + data_window.rio.crs, + transform=_rio_window_transform(window, self.transform) + * Affine.scale(window.width / out_width, window.height / out_height), shape=(out_height, out_width), ) diff --git a/test/integration/test_integration_merge.py b/test/integration/test_integration_merge.py index 8d148fcc..7b2b4701 100644 --- a/test/integration/test_integration_merge.py +++ b/test/integration/test_integration_merge.py @@ -1,15 +1,48 @@ import os +import numpy import pytest import xarray from numpy import nansum -from numpy.testing import assert_almost_equal +from numpy.testing import assert_almost_equal, assert_array_equal +from rasterio.io import MemoryFile +from rasterio.merge import merge as rio_merge +from rasterio.transform import from_origin from rioxarray import open_rasterio from rioxarray.merge import merge_arrays, merge_datasets from test.conftest import TEST_INPUT_DATA_DIR +@pytest.mark.parametrize("bounds", [None, (1, 1, 3, 3), (0.8, 0.6, 3.4, 3.2)]) +def test_merge_arrays__bounds(bounds): + data = numpy.arange(16, dtype=numpy.uint8).reshape(1, 4, 4) + transform = from_origin(0, 4, 1, 1) + array = ( + xarray.DataArray(data, dims=("band", "y", "x")) + .rio.write_crs("EPSG:4326") + .rio.write_transform(transform) + ) + + with MemoryFile() as memory_file: + with memory_file.open( + driver="GTiff", + height=4, + width=4, + count=1, + dtype=data.dtype, + crs=array.rio.crs, + transform=transform, + ) as raster: + raster.write(data) + expected, expected_transform = rio_merge([raster], bounds=bounds) + + merged = merge_arrays([array], bounds=bounds) + + assert_array_equal(merged.values, expected) + assert merged.rio.transform() == expected_transform + + @pytest.mark.parametrize("squeeze", [True, False]) def test_merge_arrays(squeeze): dem_test = os.path.join(TEST_INPUT_DATA_DIR, "MODIS_ARRAY.nc")