Description
For a curvilinear raster with dims ('y', 'x'), numeric y/x index coordinates, and real 2-D latitude/longitude coordinates, the geodesic method silently uses the numeric y/x index coords as if they were lat/lon. The user gets wrong geodesic results with no warning.
The root cause is in _find_coord() in xrspatial/utils.py. It first accepts the dimension coordinate if it is numeric, before it ever scans for a coordinate explicitly named latitude or longitude. When the dimension coord is a numeric y/x pixel index, that index wins over the real 2-D lat/lon coords.
The range validation does not catch this: small pixel indices (0..N) fall inside the accepted geographic ranges of [-90, 90] for latitude and [-180, 360] for longitude, so no error is raised.
Reproduction
A 6x8 east-tilted surface over a real 40-41N / 10-11E grid:
- Curvilinear raster (dims y/x with numeric y/x coords plus 2-D lat/lon coords): center-cell slope = 0.0074
- Reference raster (same grid, dims lat/lon with 1-D lat/lon coords): center-cell slope = 0.0675
Same physical surface, ~9x difference, no warning.
Expected behavior
When real latitude/longitude coordinates exist on the DataArray, the geodesic path should prefer them over numeric y/x dimension index coords.
Affected
slope, aspect, and surface_distance geodesic paths all resolve coords through _extract_latlon_coords / _find_coord, so all are affected. The fix is backend-agnostic (numpy, cupy, dask+numpy, dask+cupy).
Test gap: existing geodesic tests cover 1-D lat/lon coords and backend parity but not the dims=('y','x') + 2-D lat/lon + numeric y/x case where this bug lives.
Description
For a curvilinear raster with dims ('y', 'x'), numeric y/x index coordinates, and real 2-D latitude/longitude coordinates, the geodesic method silently uses the numeric y/x index coords as if they were lat/lon. The user gets wrong geodesic results with no warning.
The root cause is in
_find_coord()inxrspatial/utils.py. It first accepts the dimension coordinate if it is numeric, before it ever scans for a coordinate explicitly named latitude or longitude. When the dimension coord is a numeric y/x pixel index, that index wins over the real 2-D lat/lon coords.The range validation does not catch this: small pixel indices (0..N) fall inside the accepted geographic ranges of [-90, 90] for latitude and [-180, 360] for longitude, so no error is raised.
Reproduction
A 6x8 east-tilted surface over a real 40-41N / 10-11E grid:
Same physical surface, ~9x difference, no warning.
Expected behavior
When real latitude/longitude coordinates exist on the DataArray, the geodesic path should prefer them over numeric y/x dimension index coords.
Affected
slope, aspect, and surface_distance geodesic paths all resolve coords through
_extract_latlon_coords/_find_coord, so all are affected. The fix is backend-agnostic (numpy, cupy, dask+numpy, dask+cupy).Test gap: existing geodesic tests cover 1-D lat/lon coords and backend parity but not the dims=('y','x') + 2-D lat/lon + numeric y/x case where this bug lives.