Come chiamare gdal_translate dal codice Python?


40

È possibile utilizzare alcune API gdal per chiamare gdal_translatedal codice Python? Non intendo semplicemente eseguire gdal_translate.exe dal file system, ma piuttosto chiamarlo in qualche modo nel codice, quindi non ho bisogno di conoscere la directory esatta in cui si trova l'eseguibile gdal_translate?


4
Sì, a partire da gdal-2.1. Questa risposta dovrebbe essere accettata come corretta.
Pete,

Risposte:



23

Consulta il tutorial sull'API GDAL .

#Import gdal
from osgeo import gdal

#Open existing dataset
src_ds = gdal.Open( src_filename )

#Open output format driver, see gdal_translate --formats for list
format = "GTiff"
driver = gdal.GetDriverByName( format )

#Output to new format
dst_ds = driver.CreateCopy( dst_filename, src_ds, 0 )

#Properly close the datasets to flush to disk
dst_ds = None
src_ds = None

Se vuoi un maggiore controllo dell'output, come ridimensionamento, subsetting, ecc ... usa un VRT come input, ecco come gdal_translate lo fa internamente.


sfortunatamente questo non include la re-espulsione, vero?
Riccardo,

1
@butcher - no. Perché la domanda non menzionava la riproiezione. Ovviamente puoi riproiettare i raster con l'API python di gdal. Se vuoi sapere come, fai una nuova domanda.
user2856

L'ho già fatto qui: gis.stackexchange.com/questions/103874/… ma thius è stato contrassegnato come duplicato :-(
Riccardo

2
@butcher - che è stato chiuso come duplicato di questa domanda. La tua domanda fa anche domande su gdal_translate. Sei consapevole che gdal_translate non riproiettare? Se si desidera riproiettare, utilizzare gdalwarp o il metodo API python gdal
gdal.ReprojectImage

10

Sì, puoi chiamare le utility GDAL da Python. Ci sono differenze minime nell'approccio a seconda che l'utilità sia un exe a sé stante o anche un pezzo di codice Python. In ogni caso, però, è necessario utilizzare il modulo di sottoprocesso :

import subprocess

# constants
gdalTranslate = r'C:\Program Files\GDAL\gdal_translate.exe'
src = r"C:\somefolder\somefile.tif"
dst = r"C:\someotherfolder\myresul.tif"
cmd = "-ot float32 -outsize 25 25"  # just for example!

# see note below
def youCanQuoteMe(item):
    return "\"" + item + "\""

fullCmd = ' '.join([gdalTranslate, cmd, youCanQuoteMe(src), youCanQuoteMe(dst)])
subprocess.popen(fullCmd)

Noterai che aggiungo virgolette sfuggite attorno ai miei percorsi. Questo perché, su Windows, ho avuto problemi con i percorsi, specialmente quelli con spazi o in cui uno dei caratteri "\" crea un altro carattere di escape accidentale. Quindi, preservo il percorso corretto in Aspec per così dire.

Se stai usando una delle utility di Python, fai la stessa cosa tranne che il tuo exe all'inizio della stringa di comando del sottoprocesso ora è "C: \ python32 \ python.exe" (o qualunque versione tu abbia) e il tuo secondo elemento è l'utilità python che si desidera utilizzare.

Ovviamente puoi anche iterare sul tuo file system piuttosto che usare costanti codificate, ma questo è solo un esempio.

EDIT - Generalizzando per i plugin
QGIS QGIS crea / modifica una serie di variabili d'ambiente all'avvio. Quindi, puoi costruire variabili di percorso generalizzate alle librerie / utilità GDAL usando queste (vedi Impostazioni-> Opzioni-> Sistema) invece dei percorsi codificati nell'esempio sopra.


Quindi non posso farlo? import gdal_translate e quindi chiama .main ()?
Katie E.,

No, non funzionerà. gdal_translate non è un pacchetto Python, quindi python non ne saprà nulla. Verrà visualizzato un errore che dice "ImportError No Module chiamato gdal_translate". Utilizzare invece il modulo di sottoprocesso per chiamarlo.
MappaGnosis,

ok una domanda simile con l'utilizzo di gdal_retile.py .. Ho provato a fare quanto segue: import gdal_retile gdal_retile.main ("- v -r bilinear -levels 4 -ps 2048 2048 -co \" tiled = YES \ "-targetDir cablepyramid - -optfile files.txt ") ma visualizzo l'errore: Opzione di comando non riconosciuta: - Qualche idea sul perché?
Katie E.,

A prima vista non riesco a vedere il problema, tranne la mia ipotesi è che potrebbe non piacere l'opzione '--optfile'. Quest'ultimo non è documentato.
MappaGnosis,

@MappaGnosis Esiste un'alternativa di gdal_translate nella libreria di Python gdal?
multigoodverse,

7

Faccio questo con vari comandi gdal usando os.system che puoi usare per chiamare le funzioni proprio come dalla riga di comando:

os.system("gdal_translate -of GTiff " + sourcefile + " " +  destinationfile)

È anche descritto nella lezione 7 qui: http://www.gis.usu.edu/~chrisg/python/2009/


I comandi GDAL sono disponibili come funzioni Python in GDAL 2.1 tramite RFC 59.1 . Inoltre subprocess.callè più sicuro di os.system.
Dmitri Chubarov,

1
Qualcuno deve scrivere un buon esempio di quelle funzioni di Python; Ho lottato gdal.Warp()per un paio d'ore per ottenere correttamente un'origine PG:dati da cutlineDSNameguidare cutlineSQL. (Lo so, vero? Un paio d' ore in realtà stanno risolvendo qualcosa ? L'orrore! </kidding>). Alla fine ha funzionato e sembra essere significativamente più veloce di os.system()o subprocess.call(). Sta facendo ~ 2 milioni di linee di taglio, quindi non saprò se in realtà è più veloce fino a qualche volta stanotte ... ma funziona esattamente bene.
GT.

3

Ecco un codice rapido per chiunque desideri salvare bande da un TIF multi-banda composito in singoli file utilizzando GDAL Translate in Python.

import gdal

in_path = 'C:/GIS/Sample.tif' #input composite raster
out_path = 'C:/GIS/Output/' #output directory for individual bands as files

#Open existing raster ds
src_ds = gdal.Open(in_path)

for i in range(1,src_ds.RasterCount +1): #Save bands as individual files
    out_ds = gdal.Translate(out_path + 'band' + str(i) + '.tiff', src_ds, format='GTiff', bandList=[i])
    out_ds=None

Questo potrebbe essere utile per ulteriori elaborazioni (ad es. Utilizzando Rasterio, come qui ).

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.