Você pode usar o rasterio para extrair os valores do raster dentro de um polígono, como no GIS SE: GDAL, imagem de geotiff de corte python com arquivo geojson
Eu uso aqui um arquivo raster de uma banda e GeoPandas para o shapefile (em vez de Fiona)
import rasterio
from rasterio.mask import mask
import geopandas as gpd
shapefile = gpd.read_file("extraction.shp")
# extract the geometry in GeoJSON format
geoms = shapefile.geometry.values # list of shapely geometries
geometry = geoms[0] # shapely geometry
# transform to GeJSON format
from shapely.geometry import mapping
geoms = [mapping(geoms[0])]
# extract the raster values values within the polygon
with rasterio.open("raster.tif") as src:
out_image, out_transform = mask(src, geoms, crop=True)
O resultado out_image é um array mascarado Numpy
# no data values of the original raster
no_data=src.nodata
print no_data
-9999.0
# extract the values of the masked array
data = out_image.data[0]
# extract the row, columns of the valid values
import numpy as np
row, col = np.where(data != no_data)
elev = np.extract(data != no_data, data)
Agora eu uso Como obter as coordenadas de uma célula em um geotif? ou Python affine transforma para transformar entre o pixel e as coordenadas projetadas com out_transform
a transformação affine para os dados do subconjunto
from rasterio import Affine # or from affine import Affine
T1 = out_transform * Affine.translation(0.5, 0.5) # reference the pixel centre
rc2xy = lambda r, c: (c, r) * T1
Criação de um novo GeoDataFrame resultante com os valores de col, linha e elevação
d = gpd.GeoDataFrame({'col':col,'row':row,'elev':elev})
# coordinate transformation
d['x'] = d.apply(lambda row: rc2xy(row.row,row.col)[0], axis=1)
d['y'] = d.apply(lambda row: rc2xy(row.row,row.col)[1], axis=1)
# geometry
from shapely.geometry import Point
d['geometry'] =d.apply(lambda row: Point(row['x'], row['y']), axis=1)
# first 2 points
d.head(2)
row col elev x y geometry
0 1 2 201.7! 203590.58 89773.50 POINT (203590.58 89773.50)
1 1 3 200.17 203625.97 89773.50 POINT (203625.97 89773.50)
# save to a shapefile
d.to_file('result.shp', driver='ESRI Shapefile')