Skip to content

Incorrect y-coordinates for non-georeferenced data from open_rasterio #1686

Description

@maaleske

For a non-georeferenced dataset, open_rasterio() results in y-coordinates from the raster height to two times the height, instead of the expected 0 .. height range:

import numpy as np
import rasterio
from xarray import open_rasterio

tmp_file = 'no_transform.tif'
nx, ny, nz = 4, 3, 3 
data = np.arange(nx*ny*nz,
                 dtype=rasterio.float32).reshape(nz, ny, nx)
with rasterio.open(
              tmp_file, 'w', 
              driver='GTiff', height=ny, width=nx, count=nz,
              dtype=rasterio.float32) as s:
        s.write(data)

open_rasterio(tmp_file)
<xarray.DataArray (band: 3, y: 3, x: 4)>
array( ... )
Coordinates:
  * band     (band) int64 1 2 3
  * y        (y) float64 3.5 4.5 5.5
  * x        (x) float64 0.5 1.5 2.5 3.5
Attributes:
     res:        (1.0, -1.0)
     is_tiled:   0
     transform:  (0.0, 1.0, 0.0, 0.0, 0.0, 1.0)

Passing transform=from_origin(0,3,1,1) (from rasterio.transforms) to rasterio.open() in the above code seems to give the expected result with y running down from 2.5:

<xarray.DataArray (band: 3, y: 3, x: 4)>
array( ... )
Coordinates:
  * band     (band) int64 1 2 3
  * y        (y) float64 2.5 1.5 0.5
  * x        (x) float64 0.5 1.5 2.5 3.5
Attributes:
    res:        (1.0, 1.0)
    is_tiled:   0
    transform:  (0.0, 1.0, 0.0, 3.0, 0.0, -1.0)

I'm not sure whether there's something amiss in the xarray coordinate calculations or the rasterio default transform logic. Looking at the code, I feel like there's some mismatch between the rasterio res property logic and the xarray coordinate generation (namely, the sign of res[1]):

https://github.com/mapbox/rasterio/blob/fcd361c49cca9c4ad32a2ac1f5d66b967f4b6cd4/rasterio/_base.pyx#L611-L619

# Get geo coords
nx, ny = riods.width, riods.height
dx, dy = riods.res[0], -riods.res[1]
x0 = riods.bounds.right if dx < 0 else riods.bounds.left
y0 = riods.bounds.top if dy < 0 else riods.bounds.bottom
coords['y'] = np.linspace(start=y0 + dy/2, num=ny,
stop=(y0 + (ny - 1) * dy) + dy/2)
coords['x'] = np.linspace(start=x0 + dx/2, num=nx,
stop=(x0 + (nx - 1) * dx) + dx/2)

I'm not quite sure if the xarray code is quite correct for georefenced data, since it doesn't utilize the given coordinate transform. I don't' have files to test it with though.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    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