Wie rufe ich gdal_translate aus Python-Code auf?

40

Ist es möglich, eine gdal-API zum Aufrufen gdal_translatevon Python-Code zu verwenden? Ich meine nicht, einfach die Datei gdal_translate.exe aus dem Dateisystem auszuführen, sondern sie irgendwie im Code aufzurufen, damit ich nicht wissen muss, in welchem ​​Verzeichnis sich die ausführbare Datei gdal_translate befindet.

Katie E.
quelle
4
Ja, ab gdal-2.1. Diese Antwort sollte als richtig akzeptiert werden.
Pete

Antworten:

27

Seit GDAL 2.1 (weitere Informationen hier ) können GDAL- und OGR-Dienstprogramme als Bibliotheksfunktionen verwendet werden. Zum Beispiel:

from osgeo import gdal

ds = gdal.Open('input.tif')
ds = gdal.Translate('output.tif', ds, projWin = [-75.3, 5.5, -73.5, 3.7])
ds = None
Antonio Falciano
quelle
2
Alle verfügbaren Optionen gdal.Translate()sind hier aufgelistet: gdal.org/python/osgeo.gdal-module.html#TranslateOptions
Marcelo Villa
23

Siehe das GDAL API Tutorial .

#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

Wenn Sie mehr Ausgabesteuerung wünschen, wie z. B. Größenänderung, Teilmenge usw., verwenden Sie einen VRT als Eingabe. Dies geschieht intern durch gdal_translate.

user2856
quelle
das schließt leider keine ablehnung ein, oder?
Riccardo
1
@ butcher - nein. Denn die Frage erwähnte keine Reprojektion. Natürlich können Sie Raster mit der GDAL-Python-API neu projizieren. Wenn Sie wissen möchten wie, stellen Sie eine neue Frage.
user2856
Ich habe es schon hier gemacht: gis.stackexchange.com/questions/103874/… aber thius wurde als Duplikat markiert :-(
Riccardo
2
@butcher - das wurde als Duplikat dieser Frage geschlossen. Ihre Frage fragt auch nach gdal_translate. Ist Ihnen bewusst, dass gdal_translate keine Neuprojektion durchführt? Wenn Sie eine Neuprojektion durchführen möchten, verwenden Sie gdalwarp oder die gdal-Python-API-Methode - gdal.ReprojectImage
user2856
10

Ja, Sie können die GDAL-Dienstprogramme in Python aufrufen. Je nachdem, ob es sich bei dem Dienstprogramm um eine eigenständige Exe oder um einen Python-Code handelt, gibt es nur geringfügige Unterschiede in der Vorgehensweise. In beiden Fällen müssen Sie das Unterprozessmodul verwenden :

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)

Sie werden feststellen, dass ich meine Pfade in Anführungszeichen setze. Dies liegt daran, dass ich unter Windows Probleme mit Pfaden hatte, insbesondere mit Leerzeichen oder wenn eines der Zeichen '\' ein anderes versehentlich maskiertes Zeichen erzeugt. Also behalte ich sozusagen den richtigen Weg in aspec.

Wenn Sie eines der Python-Dienstprogramme verwenden, tun Sie dasselbe, mit der Ausnahme, dass Ihre Exe am Anfang der Unterprozessbefehlszeichenfolge jetzt "C: \ python32 \ python.exe" lautet (oder welche Version Sie auch haben) und Ihr zweites Element lautet das Python-Dienstprogramm, das Sie verwenden möchten.

Natürlich können Sie auch über Ihr Dateisystem iterieren, anstatt hartcodierte Konstanten zu verwenden, aber dies ist nur ein Beispiel.

BEARBEITEN - Generalisieren für QGIS-Plugins
QGIS erstellt / ändert beim Start eine Reihe von Umgebungsvariablen. Sie können also verallgemeinerte Pfadvariablen für die GDAL-Bibliotheken / -Dienstprogramme erstellen, indem Sie diese anstelle der fest codierten Pfade im obigen Beispiel verwenden (siehe Einstellungen-> Optionen-> System).

MappaGnosis
quelle
Also kann ich das nicht machen? importiere gdal_translate und rufe dann die .main () auf?
Katie E.
Nein - das geht nicht. gdal_translate ist kein Python-Paket, daher weiß Python nichts darüber. Sie erhalten die Fehlermeldung "ImportError No Module named gdal_translate". Verwenden Sie stattdessen das Unterprozessmodul, um es aufzurufen.
MappaGnosis 29.11.12 um 17:37
ok eine ähnliche Frage mit gdal_retile.py .. Ich habe versucht, das Folgende zu tun: -optfile files.txt ") aber ich erhalte die Fehlermeldung: Unbekannte Befehlsoption: - Irgendeine Idee warum?
Katie E.
Auf Anhieb kann ich das Problem nicht erkennen, außer ich vermute, dass der Schalter '--optfile' möglicherweise nicht gefällt. Letzteres ist nicht dokumentiert.
MappaGnosis
@MappaGnosis Gibt es eine Alternative zu gdal_translate in der Python-gdal-Bibliothek?
Multigoodverse
7

Ich mache das mit verschiedenen gdal-Befehlen unter Verwendung von os.system, mit denen Sie Funktionen wie von der Kommandozeile aus aufrufen können:

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

Es wird auch in Vorlesung 7 hier beschrieben: http://www.gis.usu.edu/~chrisg/python/2009/

Max
quelle
GDAL-Befehle sind als Python-Funktionen in GDAL 2.1 bis RFC 59.1 verfügbar . Ist auch subprocess.callsicherer als os.system.
Dmitri Chubarov
1
Jemand muss ein gutes Beispiel für diese Python-Funktionen schreiben. Ich habe gdal.Warp()ein paar Stunden damit PG:gerungen , eine Datenquelle cutlineDSNamezu finden, um das Laufwerk zu betreiben cutlineSQL. (Ich weiß, richtig? Ein paar Stunden, die tatsächlich etwas bewirken ? Der Horror! </ Scherz>). Hat es irgendwann geklappt und scheint deutlich schneller zu sein als os.system()oder subprocess.call(). Es macht ungefähr 2 Millionen Schnitte, also werde ich nicht wissen, ob es bis heute Abend tatsächlich schneller ist ... aber es funktioniert genau richtig.
GT.
3

Hier ist ein kurzer Code für alle, die mit GDAL Translate in Python Bänder aus einem zusammengesetzten Multiband-TIF in einzelne Dateien speichern möchten.

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

Dies kann für die weitere Verarbeitung nützlich sein (z. B. mit Rasterio, wie hier ).

15Schritt
quelle