Skip to content

geotiff: align open_geotiff parameters with rioxarray's open_rasterio #2961

@brendancol

Description

@brendancol

Reason or Problem

xrspatial.geotiff.open_geotiff and rioxarray's open_rasterio do the same job (read a GeoTIFF/COG/VRT into an xarray.DataArray), but their signatures diverge on parameter names and one default, so moving code between them needs edits:

  • The nodata-masking flag is mask_nodata (default True, promotes the sentinel to NaN) here, versus masked (default False) in open_rasterio. The name and the default both differ.
  • The array-name kwarg is name here, versus default_name in open_rasterio.
  • open_rasterio has mask_and_scale, parse_coordinates, lock, and cache; open_geotiff has no counterpart for any of them.

Proposal

Align the overlapping parameters with open_rasterio so a rioxarray-style call works on open_geotiff with minimal edits, while keeping the xrspatial-only parameters (gpu, window, bbox, max_pixels, allow_*, tier flags) and not renaming parameters that already match (chunks).

Design:

  • Rename mask_nodata -> masked and flip the default from True to False to match open_rasterio. Keep mask_nodata as a deprecated alias: passing it emits a DeprecationWarning, passing both masked and mask_nodata raises TypeError. This reuses the sentinel-based deprecation pattern already used for read_geotiff_gpu's gpu -> on_gpu_failure rename (_runtime.py sentinels + the resolution block in _backends/gpu.py).
  • Rename name -> default_name with the same deprecated-alias mechanism.
  • Add mask_and_scale (default False): read GDAL SCALE/OFFSET from attrs['gdal_metadata'], apply data * scale + offset, mask the nodata sentinel, and record attrs['scale_factor']/attrs['add_offset'], mirroring open_rasterio.
  • Add parse_coordinates (default True): when False, skip building the x/y coordinate arrays while keeping attrs['transform'] and attrs['crs'].
  • Add lock and cache for signature compatibility. xrspatial's dask reader re-opens the source per window, so there is no shared GDAL handle to lock and no caching backend to toggle; passing a non-default value emits a GeoTIFFFallbackWarning explaining this rather than silently ignoring the kwarg.

The four backend readers keep their internal kwarg names; the public contract change lives only at open_geotiff.

Usage:

from xrspatial.geotiff import open_geotiff

da = open_geotiff("dem.tif", masked=True)              # was mask_nodata=True
da = open_geotiff("dem.tif", mask_and_scale=True)      # apply SCALE/OFFSET, mask nodata
da = open_geotiff("dem.tif", parse_coordinates=False)  # index coords, keep crs/transform attrs

Value: lowers the cost of switching from rioxarray and makes the reader's surface predictable for users who already know open_rasterio.

Stakeholders and Impacts

Affects callers of open_geotiff. The masking-default flip is a breaking behavior change: a bare open_geotiff(path) stops promoting the nodata sentinel to NaN. The deprecated mask_nodata alias keeps the old name working through a deprecation window.

Drawbacks

The masking-default flip changes the result of the default call path. mask_and_scale is new code and depends on GDAL writing scale/offset into the GDAL_METADATA tag. Sources without those items get a (1.0, 0.0) no-op.

Alternatives

  • Additive aliases that keep the current masking default — rejected because a bare call would still not match open_rasterio.
  • Renaming every shared parameter including chunks — rejected because chunks already matches.

Unresolved Questions

Whether lock/cache should map onto anything in the dask read path or stay accept-and-warn. The current plan is accept-and-warn.

Metadata

Metadata

Assignees

No one assigned

    Labels

    apiAPI design and consistencyenhancementNew feature or requestgeotiffGeoTIFF module

    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