Skip to content

resample: attrs['transform'] is wrong for ascending-y or descending-x inputs #2571

@brendancol

Description

@brendancol

Describe the bug

resample() always writes a north-up rasterio transform (positive x
scale, negative y scale, origin at the top-left edge), no matter what
orientation the input coords have. If the input array has ascending y
or descending x coords, attrs['transform'] on the output no longer
matches the coords on the same DataArray. Downstream code that
georeferences via attrs['transform'] will get a flipped raster.

The bug is in xrspatial/resample.py around line 1364. The current
code picks the right top / left corner for the coord direction,
but it still writes (out_res_x, 0.0, left, 0.0, -out_res_y, top).
Rasterio's affine maps (col=0, row=0) -> (x, y) for the first pixel
in the array, not for the top-left geographic corner, so the scale
signs and origin corner have to follow the actual array layout.

Expected behavior

attrs['transform'] should match the coords on the output array for
all four combinations of x ascending/descending and y
ascending/descending. transform * (0, 0) should land on the upper-
left corner of the first array pixel (the pixel at [0, 0]), and the
scale signs should follow the coord direction.

Minimal repro

```python
import numpy as np
import xarray as xr
from xrspatial import resample

Ascending-y input.

data = np.arange(16, dtype=np.float32).reshape(4, 4)
raster = xr.DataArray(
data,
dims=['y', 'x'],
coords={'y': np.linspace(0, 3, 4), 'x': np.linspace(0, 3, 4)},
attrs={'transform': (1.0, 0.0, -0.5, 0.0, 1.0, -0.5),
'res': (1.0, 1.0)},
)

out = resample(raster, scale_factor=0.5)
print(out.attrs['transform'])

Currently: (2.0, 0.0, -0.5, 0.0, -2.0, 3.5) -- negative y scale,

top-edge origin, even though the output y coords still ascend.

Expected: (2.0, 0.0, -0.5, 0.0, 2.0, -0.5).

```

Additional context

Surfaced by a code review of the resample module. Only the metadata
refresh block at the end of `resample()` is affected -- the resampled
pixel values are correct.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions