Raster di ritaglio con livello vettoriale mediante GDAL


26

Ho installato GDAL usando il programma di installazione di Osgeo. Come posso tagliare un livello raster con un livello vettoriale a livello di codice? C'è qualche API GDAL disponibile che mi può aiutare in questo? Sto usando Python.

Risposte:


13

Non sono sicuro dell'API di gdal, void* GDALWarpOptions::hCutlinenelle Opzioni di Warp è presente il tutorial API Warp , ma non ci sono esempi espliciti. Sei sicuro di aver bisogno di una risposta programmatica? Le utility della riga di comando possono farlo immediatamente:

  1. creare un file di forma contenente solo l'area del poligono di ritaglio di interesse
  2. utilizzare ogrinfoper determinare l'estensione del file di forma del ritaglio
  3. usare gdal_translateper agganciarlo all'estremità della forma
  4. utilizzare gdalwarpcon il -cutlineparametro

I passaggi 2 e 3 sono per l'ottimizzazione, potresti cavartela semplicemente gdalwarp -cutline ....

Guarda i raster di ritaglio con GDAL usando poligoni di Linfinity per la soluzione basata su Linux, tutti racchiusi in uno script. Un altro esempio di linea sottile può essere visto nel tutorial di Michael Corey sulla creazione di sfumature per Mapnik .


Matt, potresti ricordare che trac.osgeo.org/gdal/ticket/1599 sembra che la linea di demarcazione compia questo
Mike T,


10

Sembra che questo argomento ritorni sempre. Io stesso non sapevo che GDAL> 1.8 è così avanzato che ti dà già una corretta gestione della riga di comando per fare quel compito.

Il commento di Mike Toews è piuttosto utile ma potresti semplicemente fare ad esempio:

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

È possibile racchiudere questo comando in uno script Python con l'eccellente modulo di sottoprocesso .

Una cosa che è stata davvero problematica per me è che dovevo fornire una soluzione minima a quel problema, il che significa il più semplice possibile e non richiede molte dipendenze esterne. L'uso di Python Imaging Library come nel tutorial di Joel Lawhead è pulito, ma ho trovato la seguente soluzione: usare gli array mascherati Numpy.
Non so se sia meglio, ma era quello che sapevo da (3 anni fa ...).
Inizialmente ho creato un'area dati valida all'interno del raster originale (ad es. L'estensione del raster di output dove lo stesso), ma mi è piaciuta l'idea di rendere anche il raster più piccolo (ad esempio -crop_to_cutline), quindi ho adottato world2Pixelda Joel Lawhead. Ecco la mia soluzione:

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)

per una descrizione completa dei class MaskRastermetodi e dei relativi, consultare il github del mio progetto .

Usando questo codice dovrai comunque usare GDAL. Tuttavia, il piano è quello di utilizzare in futuro Python puro dove posso, perché il pubblico previsto del mio software ha difficoltà con troppe dipendenze (uso Debian per sviluppare il software, ei client usano Windows 7 ...).


Mi piace l'esempio della riga di comando che hai fornito, ma puoi spiegare cosa fa l'argomento -crop_to_cutline? Non sono sicuro di quale sia il suo scopo dato che lo shapefile di ritaglio è specificato da -cutline.
Hendra,

1
l'opzione -cutline aggancia il raster al riquadro di delimitazione interno del livello poligonale. Ad esempio, se è più piccolo nelle dimensioni, anche il raster di output sarà più piccolo. Senza questo, il raster di output avrà le stesse dimensioni dell'originale, ma con NULL in tutti i punti al di fuori dell'area di tuo interesse.
Oz123,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.