Describe the bug
to_geotiff(..., crs=np.int64(4326)) passes validation but writes a file with no EPSG and no crs_wkt tag. Reading the file back returns a DataArray with no CRS — the projection is silently lost.
The validator at xrspatial/geotiff/_crs.py:87 accepts numbers.Integral, which covers plain int and numpy integer scalars (np.int32, np.int64, ...). The writers gate EPSG assignment on isinstance(crs, int), which is False for numpy integers:
xrspatial/geotiff/_writers/eager.py:540
xrspatial/geotiff/_writers/eager.py:871
xrspatial/geotiff/_writers/gpu.py:349
So the value clears validation, falls through both writer branches, and nothing gets written.
Repro
import numpy as np
import xarray as xr
from xrspatial.geotiff import to_geotiff, open_geotiff
data = xr.DataArray(np.zeros((4, 4), dtype=np.float32), dims=('y', 'x'))
to_geotiff(data, 'out.tif', crs=np.int64(4326))
ds = open_geotiff('out.tif')
print(ds.attrs.get('crs')) # None
print(ds.attrs.get('crs_wkt')) # None
Expected behavior
Either the validator should reject numpy integer CRS values, or the writers should accept them and emit the EPSG tag. The validator is the intended path (it explicitly handles numbers.Integral), so the writers should match.
Fix
Widen the writer-side isinstance(crs, int) checks to isinstance(crs, numbers.Integral) and coerce to int(crs). Three call sites need the same change.
Additional context
The failure is silent. Anything reading the written file back gets no CRS and drops into the no-georef code path without a warning.
Describe the bug
to_geotiff(..., crs=np.int64(4326))passes validation but writes a file with no EPSG and nocrs_wkttag. Reading the file back returns a DataArray with no CRS — the projection is silently lost.The validator at
xrspatial/geotiff/_crs.py:87acceptsnumbers.Integral, which covers plainintand numpy integer scalars (np.int32,np.int64, ...). The writers gate EPSG assignment onisinstance(crs, int), which isFalsefor numpy integers:xrspatial/geotiff/_writers/eager.py:540xrspatial/geotiff/_writers/eager.py:871xrspatial/geotiff/_writers/gpu.py:349So the value clears validation, falls through both writer branches, and nothing gets written.
Repro
Expected behavior
Either the validator should reject numpy integer CRS values, or the writers should accept them and emit the EPSG tag. The validator is the intended path (it explicitly handles
numbers.Integral), so the writers should match.Fix
Widen the writer-side
isinstance(crs, int)checks toisinstance(crs, numbers.Integral)and coerce toint(crs). Three call sites need the same change.Additional context
The failure is silent. Anything reading the written file back gets no CRS and drops into the no-georef code path without a warning.