Ten en cuenta que en la informática un problema puede tener varias resoluciones, por lo tanto nosotros aquí enseñamos lo más óptimo y eficiente.
Solución:
Estás en el camino correcto y el GeoDataFrame de geopandas es una buena opción para la rasterización sobre Fiona. Fiona es un gran conjunto de herramientas, pero creo que DataFrame se adapta mejor a los archivos de formas y geometrías que a los diccionarios anidados.
import geopandas as gpd
import rasterio
from rasterio import features
Configura tus nombres de archivo
shp_fn = 'cb_2013_us_county_20m.shp'
rst_fn = 'template_raster.tif'
out_fn = './rasterized.tif'
Abra el archivo con GeoPANDAS read_file
counties = gpd.read_file(shp_fn)
Agregue la nueva columna (como en su código anterior)
for i in range (len(counties)):
LSAD = counties.at[i,'LSAD']
if LSAD == 00 :
counties['LSAD_NUM'] == 'A'
elif LSAD == 03 :
counties['LSAD_NUM'] == 'B'
elif LSAD == 04 :
counties['LSAD_NUM'] == 'C'
elif LSAD == 05 :
counties['LSAD_NUM'] == 'D'
elif LSAD == 06 :
counties['LSAD_NUM'] == 'E'
elif LSAD == 13 :
counties['LSAD_NUM'] == 'F'
elif LSAD == 15 :
counties['LSAD_NUM'] == 'G'
elif LSAD == 25 :
counties['LSAD_NUM'] == 'I'
else :
counties['LSAD_NUM'] == 'NA'
Abra el archivo ráster que desea usar como plantilla para la grabación de características usando rasterio
rst = rasterio.open(rst_fn)
copie y actualice los metadatos del ráster de entrada para la salida
meta = rst.meta.copy()
meta.update(compress='lzw')
Ahora grabe las características en el ráster y escríbalo
with rasterio.open(out_fn, 'w+', **meta) as out:
out_arr = out.read(1)
# this is where we create a generator of geom, value pairs to use in rasterizing
shapes = ((geom,value) for geom, value in zip(counties.geometry, counties.LSAD_NUM))
burned = features.rasterize(shapes=shapes, fill=0, out=out_arr, transform=out.transform)
out.write_band(1, burned)
La idea general es crear un iterable que contenga tuplas de (geometría, valor), donde la geometría es una geometría bien formada y el valor es lo que desea grabar en el ráster en la ubicación de esa geometría. Tanto Fiona como GeoPANDAS usan geometrías bien formadas, así que estás de suerte. En este ejemplo, se utiliza un generador para iterar a través de los pares (geometría, valor) que se extrajeron del GeoDataFrame y se unieron mediante zip().
Asegúrate de abrir el out_fn
presentar en w+
modo, porque tendrá que ser utilizado para leer y escribir.
geocube es una nueva herramienta diseñada específicamente para rasterizar datos de geopandas que envuelven rasterio. Simplifica el proceso y elimina la necesidad de un ráster de plantilla.
https://github.com/corteva/geocubo
En el contexto del ejemplo anterior:
from geocube.api.core import make_geocube
import geopandas
counties = geopandas.read_file("zip://cb_2013_us_county_20m.zip/cb_2013_us_county_20m.shp")
La letra se puede configurar en el marco de datos de esta manera:
counties["LSAD_LETTER"] = 'NA'
lsad_letter = counties.LSAD_LETTER.copy()
lsad_letter[counties.LSAD=='00'] = 'A'
lsad_letter[counties.LSAD=='03'] = 'B'
lsad_letter[counties.LSAD=='04'] = 'C'
lsad_letter[counties.LSAD=='05'] = 'D'
lsad_letter[counties.LSAD=='06'] = 'E'
lsad_letter[counties.LSAD=='13'] = 'F'
lsad_letter[counties.LSAD=='15'] = 'G'
lsad_letter[counties.LSAD=='25'] = 'I'
counties["LSAD_LETTER"] = lsad_letter
Sin embargo, solo se pueden rasterizar valores numéricos. Aquí hay un ejemplo categórico: https://corteva.github.io/geocube/stable/examples/categorical.html
Entonces, en lugar de usar eso, use los números en string formatear y convertir a enteros:
counties["LSAD_NUM"] = counties.LSAD.astype(int)
Luego, rasterice los datos:
cube = make_geocube(
counties,
measurements=["LSAD_NUM"],
resolution=(1, -1),
)
Por último, expórtalo a un ráster:
cube.LSAD_NUM.rio.to_raster("lsad_num.tif")
No se te olvide compartir esta crónica si te fue de ayuda.