Your raster DEM and vector road shapefile have different coordinate systems. They need a common coordinate reference system for the rasterstats package to compute the zonal statistics.
import rasterio
import geopandas as gpd
import rasterstats as rs
src = rasterio.open('example_dem.tif')
gdf = gpd.read_file('example_road.shp')
gdf.crs
{'init': 'epsg:4326'}
src.meta['crs']
CRS.from_wkt('PROJCS["NAD83 / Texas South Central (ftUS)",GEOGCS["NAD83",DATUM["North_American_Datum_1983",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],AUTHORITY["EPSG","6269"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4269"]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["latitude_of_origin",27.8333333333333],PARAMETER["central_meridian",-99],PARAMETER["standard_parallel_1",30.2833333333333],PARAMETER["standard_parallel_2",28.3833333333333],PARAMETER["false_easting",1968500],PARAMETER["false_northing",13123333.333],UNIT["US survey foot",0.304800609601219,AUTHORITY["9003","EPSG"]],AXIS["Easting",EAST],AXIS["Northing",NORTH]]')
As you can see these two CRS are not the same. To rectify, we can reproject the road shapefile to the DEM CRS.
# Project it
proj_gdf = gdf.to_crs(src.meta['crs'])
# Check the new CRS
proj_gdf.crs
RS.from_wkt('PROJCS["NAD83 / Texas South Central (ftUS)",GEOGCS["NAD83",DATUM["North_American_Datum_1983",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],AUTHORITY["EPSG","6269"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4269"]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["latitude_of_origin",27.8333333333333],PARAMETER["central_meridian",-99],PARAMETER["standard_parallel_1",30.2833333333333],PARAMETER["standard_parallel_2",28.3833333333333],PARAMETER["false_easting",1968500],PARAMETER["false_northing",13123333.333],UNIT["US survey foot",0.304800609601219,AUTHORITY["9003","EPSG"]],AXIS["Easting",EAST],AXIS["Northing",NORTH]]')
Now you can see it is the same! We are now ready to perform the zonal statistics:
stats=['min', 'max']
arr = src.read(1)
affine = src.transform
zonal_stats = (rs.zonal_stats(proj_gdf, arr, stats=stats, affine=affine))
Now inspect zonal_stats
:
[{'min': 0.1312335878610611, 'max': 40.10498809814453},
{'min': 5.505249500274658, 'max': 30.498685836791992},
{'min': 16.5944881439209, 'max': 38.684383392333984}]