Recorte de trama con capa vectorial usando GDAL

26

He instalado GDAL usando el instalador de Osgeo. ¿Cómo puedo recortar una capa ráster con una capa vectorial mediante programación? ¿Hay alguna API de GDAL disponible que pueda ayudarme con esto? Estoy usando Python

Vicky
fuente

Respuestas:

13

No estoy seguro acerca de la API gdal, existe void* GDALWarpOptions::hCutlineen las Opciones de deformación que se hace referencia desde el API tutorial Warp , pero no hay ejemplos explícitos. ¿Estás seguro de que necesitas una respuesta programática? Las utilidades de línea de comando pueden hacerlo de forma inmediata:

  1. crear un archivo de forma que contenga solo el polígono de recorte del área de interés
  2. se usa ogrinfopara determinar la extensión del archivo de forma de recorte
  3. se usa gdal_translatepara recortar las extensiones de forma
  4. usar gdalwarpcon -cutlineparámetro

Los pasos 2 y 3 son para la optimización, puede pasar con solo gdalwarp -cutline ....

Consulte Recorte de rásteres con GDAL utilizando polígonos de Linfinity para una solución basada en Linux, todo envuelto en una secuencia de comandos. Otro ejemplo de línea de corte se puede ver en el tutorial de Michael Corey creando sombreados para Mapnik .

wilkie mate
fuente
Matt, tal vez recuerdes que trac.osgeo.org/gdal/ticket/1599 parece que Cutline cumple con esto
Mike T
10

Parece que este tema siempre está volviendo. Yo mismo no sabía que GDAL> 1.8 es tan avanzado que ya te da un manejo justo de la línea de comandos para hacer esa tarea.

El comentario de Mike Toews es bastante útil, pero podría simplemente hacer, por ejemplo:

gdalwarp -of GTiff -cutline DATA/area_of_interest.shp -cl area_of_interest  -crop_to_cutline DATA/PCE_in_gw.asc  data_masked7.tiff 

Puede incluir este comando dentro de un script de Python con el excelente módulo de subproceso .

Una cosa que fue realmente problemática para mí es que necesitaba proporcionar una solución mínima a ese problema, es decir, lo más simple posible y no requiere muchas dependencias externas. El uso de Python Imaging Library como en el tutorial de Joel Lawhead es bueno, pero se me ocurrió la siguiente solución: usar matrices enmascaradas de Numpy.
No sé si es mejor, pero eso era lo que sabía que (hace 3 años ...).
Originalmente, creé un área de datos válida dentro del ráster original (por ejemplo, la extensión del ráster de salida donde era igual), pero me gustó la idea de hacer que el ráster también sea más pequeño (por ejemplo, -crop_to_cutline), así que adopté world2Pixelde Joel Lawhead. Aquí está mi propia solución:

def RasterClipper():
    craster = MaskRaster()
    contraster2 = 'PCE_in_gw.aux'
    craster.reader("DATA/"+contraster2.replace('aux','asc'))
    xres, yres = craster.extent[1], craster.extent[1]
    craster.fillrasterpoints(xres, yres)
    craster.getareaofinterest("DATA/area_of_interest.shp")
    minX, maxX=craster.new_extent [0]-5,craster.new_extent[1]+5
    minY, maxY= craster.new_extent [2]-5,craster.new_extent[3]+5
    ulX, ulY=world2Pixel(craster.extent, minX, maxY)
    lrX, lrY=world2Pixel(craster.extent, maxX, minY)
    craster.getmask(craster.corners)
    craster.mask=np.logical_not(craster.mask)
    craster.mask.resize(craster.Yrange.size,craster.Xrange.size)
    # choose all data points inside the square boundaries of the AOI,
    # replace all other points with NULL
    craster.cdata= np.choose(np.flipud(craster.mask), (craster.data, -9999))
    # resise the data set to be the size of the squared polygon
    craster.ccdata=craster.cdata[ulY:lrY, ulX:lrX]
    craster.writer("ccdata2m.asc",craster.ccdata, (minX+xres*.5, maxY+yres*.5), 10,10,Flip=False)
    # in second step we rechoose all the data points which are inside the
    # bounding vertices of AOI
    # need to re-define our raster points
    craster.xllcorner, craster.yllcorner = minX, minY
    craster.xurcorner, craster.yurcorner = maxX, maxY
    craster.fillrasterpoints(10,10)
    craster.getmask(craster.boundingvertices) # just a wrapper around matplotlib.nxutils.points_in_poly
    craster.data=craster.ccdata
    craster.clip2(new_extent_polygon=craster.boundingvertices)
    craster.data = np.ma.MaskedArray(craster.data, mask=craster.mask)
    craster.data = np.ma.filled(craster.data, fill_value=-9999)
    # write the raster to disk
    craster.writer("ccdata2m_clipped.asc",craster.data, (minX+xres*.5, maxY+yres*.5), 10,10,Flip=False)

Para obtener una descripción completa de los class MaskRastermétodos, consulte el github de mi proyecto .

Con este código, aún necesitará usar GDAL. Sin embargo, el plan es usar Python puro en el futuro donde pueda, porque la audiencia prevista de mi software tiene dificultades con demasiadas dependencias (uso Debian para desarrollar el software, y los clientes usan Windows 7 ...).

Oz123
fuente
Me gusta el ejemplo de línea de comandos que dio, pero ¿puede explicar qué hace el argumento -crop_to_cutline? No estoy seguro de cuál es su propósito dado que el archivo de forma de recorte se especifica mediante -cutline.
hendra
1
la opción -cutline recorta el ráster en el cuadro delimitador interno de la capa de polígono. Por ejemplo, si es más pequeño en la extensión, el ráster de salida también será más pequeño. Sin esto, el ráster de salida tendrá el mismo tamaño que el original, pero con NULL en todos los puntos fuera del área de su interés.
Oz123