Describe the bug
to_geotiff accepts arrays whose spatial height or width is zero. It writes a TIFF file, and the reader then refuses to open it with "Invalid image dimensions". Clip and window pipelines can produce empty rasters, so this turns a recoverable input-validation error into a stale-file-on-disk failure that only surfaces at read time.
The eager validation at xrspatial/geotiff/_writers/eager.py:670 checks arr.ndim but never that height and width are positive. The streaming path at xrspatial/geotiff/_writer.py:1939 then computes zero tile/strip counts and writes a file with no pixel data.
Reproducer
import numpy as np
import xarray as xr
from xrspatial.geotiff import to_geotiff, open_geotiff
for shape in [(0, 5), (5, 0), (0, 0)]:
da = xr.DataArray(np.zeros(shape, dtype=np.float32), dims=('y', 'x'))
to_geotiff(da, f'/tmp/empty_{shape[0]}x{shape[1]}.tif') # succeeds
open_geotiff(f'/tmp/empty_{shape[0]}x{shape[1]}.tif') # raises "Invalid image dimensions"
Expected behavior
to_geotiff raises ValueError at the write entry point with a message that names the offending dimension (e.g. "got shape (0, 5) with height=0"). The failure happens before any bytes hit disk.
Actual behavior
The writer produces a file. The error surfaces later at read time with a generic "Invalid image dimensions" message that does not name the writer as the source.
Source locations
- Eager entry:
xrspatial/geotiff/_writers/eager.py:670 (the arr.ndim not in (2, 3) check).
- Streaming entry:
xrspatial/geotiff/_writer.py:1939 (tile/strip count math runs on height/width).
Additional context
Affects all four backends (numpy, cupy, dask+numpy, dask+cupy). The validation gap is upstream of backend dispatch.
Describe the bug
to_geotiffaccepts arrays whose spatial height or width is zero. It writes a TIFF file, and the reader then refuses to open it with "Invalid image dimensions". Clip and window pipelines can produce empty rasters, so this turns a recoverable input-validation error into a stale-file-on-disk failure that only surfaces at read time.The eager validation at
xrspatial/geotiff/_writers/eager.py:670checksarr.ndimbut never that height and width are positive. The streaming path atxrspatial/geotiff/_writer.py:1939then computes zero tile/strip counts and writes a file with no pixel data.Reproducer
Expected behavior
to_geotiffraisesValueErrorat the write entry point with a message that names the offending dimension (e.g. "got shape (0, 5) with height=0"). The failure happens before any bytes hit disk.Actual behavior
The writer produces a file. The error surfaces later at read time with a generic "Invalid image dimensions" message that does not name the writer as the source.
Source locations
xrspatial/geotiff/_writers/eager.py:670(thearr.ndim not in (2, 3)check).xrspatial/geotiff/_writer.py:1939(tile/strip count math runs onheight/width).Additional context
Affects all four backends (numpy, cupy, dask+numpy, dask+cupy). The validation gap is upstream of backend dispatch.