diff --git a/src/rasterix/utils.py b/src/rasterix/utils.py index 8a080b3..0d87c98 100644 --- a/src/rasterix/utils.py +++ b/src/rasterix/utils.py @@ -148,8 +148,9 @@ def get_affine( dx = (x[1] - x[0]).item() dy = (y[1] - y[0]).item() return Affine.translation( - x[0].item() - dx / 2, (y[0] if dy < 0 else y[-1]).item() - dy / 2 - ) * Affine.scale(dx, dy) + x[0].item() - dx/2, + y[0].item() - dy/2 +) * Affine.scale(dx, dy) def get_crs_from_proj_zarr_convention(obj: xr.Dataset | xr.DataArray) -> CRS | None: diff --git a/tests/test_raster_index.py b/tests/test_raster_index.py index 4973653..d89941b 100644 --- a/tests/test_raster_index.py +++ b/tests/test_raster_index.py @@ -1059,3 +1059,26 @@ def test_tolerance_in_concat(): with set_options(transform_rtol=1e-9): _assert_transforms_are_compatible(a1, a2) # passes with 1e-9 + + +def test_get_affine_preserves_ascending_y(): + nx, ny = 4, 3 + lon = np.array([-179.5, -89.5, 0.5, 89.5]) # ascending + lat_asc = np.array([-60.0, 0.0, 60.0]) # ascending + lat_desc = lat_asc[::-1] # descending + + ds_asc = xr.Dataset( + {"foo": (("lat", "lon"), np.zeros((ny, nx)))}, + coords={"lat": lat_asc, "lon": lon}, + ) + ds_desc = xr.Dataset( + {"foo": (("lat", "lon"), np.zeros((ny, nx)))}, + coords={"lat": lat_desc, "lon": lon}, + ) + + out_asc = assign_index(ds_asc, x_dim="lon", y_dim="lat") + out_desc = assign_index(ds_desc, x_dim="lon", y_dim="lat") + + # The materialized coords should round-trip the input direction + np.testing.assert_allclose(out_asc.lat.values, lat_asc) + np.testing.assert_allclose(out_desc.lat.values, lat_desc)