Describe the bug
contours(agg, return_type="geopandas") raises a ValueError when the input raster has a crs attribute but the requested levels produce no contour lines. This happens for a flat raster, for levels outside the data range, or any case where the result set is empty.
The error comes from _to_geopandas() in xrspatial/contour.py:
gdf = gpd.GeoDataFrame(records, crs=crs)
When records is empty and crs is not None, geopandas raises:
ValueError: Assigning CRS to a GeoDataFrame without a geometry column is not supported
A related problem: the all-NaN early-return path calls _to_geopandas([], None), which avoids the crash but drops the input CRS. So an empty result either crashes (when a CRS is present) or silently loses the CRS (on the all-NaN path).
Reproduce
import numpy as np, xarray as xr
from xrspatial import contours
flat = xr.DataArray(
np.ones((4, 4)), dims=["y", "x"],
coords={"y": np.linspace(2, 0, 4), "x": np.linspace(0, 2, 4)},
attrs={"crs": "EPSG:5070"},
)
contours(flat, levels=[5.0], return_type="geopandas") # raises ValueError
Expected behavior
An empty result returns an empty GeoDataFrame that still carries the input CRS and has a geometry column, with no exception.
Additional context
Found by the deep-sweep metadata propagation sweep on the contour module. The existing geopandas test uses a raster with no crs attribute and a non-empty result, so this path is uncovered.
Describe the bug
contours(agg, return_type="geopandas")raises aValueErrorwhen the input raster has acrsattribute but the requested levels produce no contour lines. This happens for a flat raster, for levels outside the data range, or any case where the result set is empty.The error comes from
_to_geopandas()inxrspatial/contour.py:When
recordsis empty andcrsis notNone, geopandas raises:A related problem: the all-NaN early-return path calls
_to_geopandas([], None), which avoids the crash but drops the input CRS. So an empty result either crashes (when a CRS is present) or silently loses the CRS (on the all-NaN path).Reproduce
Expected behavior
An empty result returns an empty GeoDataFrame that still carries the input CRS and has a
geometrycolumn, with no exception.Additional context
Found by the deep-sweep metadata propagation sweep on the contour module. The existing geopandas test uses a raster with no
crsattribute and a non-empty result, so this path is uncovered.