Puede usar rasterio para extraer los valores de trama dentro de un polígono como en GIS SE: GDAL python cut geotiff image with geojson file
Utilizo aquí un archivo ráster de una banda y GeoPandas para el archivo de forma (en lugar 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)
El resultado de out_image es una matriz enmascarada de 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)
Ahora uso ¿Cómo obtengo las coordenadas de una celda en un geotif? o Python affine transforma para transformar entre el píxel y las coordenadas proyectadas con out_transform
la transformación afín para los datos del 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
Creación de un nuevo GeoDataFrame resultante con los valores de columna, fila y elevación
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')