Skip to content

Re-emit fresh transform/res, propagate _FillValue, use _find_spatial_dims in merge #1458

@brendancol

Description

@brendancol

Three small metadata follow-ups in xrspatial/reproject/__init__.py after PR #1446 (which added attrs preservation and popped stale grid attrs).

1. Re-emit fresh transform and res for the new output grid

Both reproject() (around line 693) and merge() (around line 1572) currently pop transform and res and never replace them. The output grid is fully known at that point: _compute_output_grid returns res_x, res_y, and bounds (left, bottom, right, top). We can emit:

  • attrs['res'] = (res_x, res_y)
  • attrs['transform'] = (res_x, 0.0, left, 0.0, -res_y, top) (rasterio/affine 6-tuple)

The xrspatial/geotiff reader does not put transform or res into attrs itself (it only stores crs_wkt, crs, nodata, etc.), so there is no in-repo convention to match. The 6-tuple form is the rasterio standard and what most external code expects when it sees attrs['transform'] on a DataArray. The tuple (res_x, res_y) is consistent with rasterio's Affine.scale accessors.

2. merge() does not use _find_spatial_dims

Lines 1482 and 1555-1556 hardcode the spatial dims as the last two, which breaks for inputs shaped (y, x, band) or other layouts where the last dims are not spatial. The helper _find_spatial_dims already exists at line 63 and should be used here, matching what reproject() already does.

3. _FillValue propagation

_detect_nodata reads _FillValue as a fallback nodata key, but neither reproject() nor merge() writes _FillValue on output. If the input raster used _FillValue, the output silently switches to nodata only. Round-trip serialization breaks.

Fix: when the input has _FillValue, set both nodata and _FillValue on the output. When it does not, leave it absent.

Tests

Extend TestMetadataPreservation in xrspatial/tests/test_reproject.py covering fresh transform/res emission, _find_spatial_dims use in merge with lat/lon dims, and _FillValue propagation for both reproject() and merge().

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions