Comment appeler gdal_translate à partir de code Python?


40

Est-il possible d'utiliser une API gdal pour appeler à gdal_translatepartir de code Python? Je ne parle pas simplement d'exécuter gdal_translate.exe à partir du système de fichiers, mais de l'appeler d'une manière ou d'une autre dans le code, de sorte que je n'ai pas besoin de connaître le répertoire exact dans lequel se trouve l'exécutable gdal_translate?


4
Oui, à partir de gdal-2.1. Cette réponse devrait être acceptée comme correcte.
Pete

Réponses:



23

Voir le didacticiel de l'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

Si vous souhaitez davantage de contrôle de sortie, tel que redimensionnement, sous-ensemble, etc., utilisez un VRT comme entrée, voici comment gdal_translate le fait en interne.


Malheureusement, cela n'inclut pas le renvoi, n'est-ce pas?
Riccardo

1
@butcher - non Parce que la question ne mentionnait pas de reprojection. Bien sûr, vous pouvez reprojeter des rasters avec l’API gdal python. Si vous voulez savoir comment, posez une nouvelle question.
user2856

Je l'ai déjà fait ici: gis.stackexchange.com/questions/103874/… mais thius a été marqué comme un doublon :-(
Riccardo le

2
@butcher - qui a été fermé en tant que duplicata de cette question. Votre question concerne également gdal_translate. Savez-vous que gdal_translate ne fait pas de reprojet? Si vous voulez reprojeter, utilisez gdalwarp ou la méthode API gdal python - gdal.ReprojectImage
user2856

10

Oui, vous pouvez appeler les utilitaires GDAL à partir de Python. Il y a de très petites différences dans l'approche selon que l'utilitaire est un exe à part entière ou aussi un morceau de code python. Quoi qu'il en soit, vous devez utiliser le module de sous - processus :

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)

Vous remarquerez que j'ajoute des guillemets échappés autour de mes chemins. En effet, sous Windows, j'ai eu des problèmes avec les chemins, en particulier ceux avec des espaces ou lorsqu'un des caractères "\" crée un autre caractère échappé par accident. Donc, je conserve juste le chemin approprié dans aspec pour ainsi dire.

Si vous utilisez un des utilitaires python, faites simplement la même chose, sauf que votre fichier exe au début de la chaîne de commande du sous-processus est maintenant "C: \ python32 \ python.exe" (ou quelle que soit la version que vous avez) et que votre deuxième élément est l'utilitaire Python que vous souhaitez utiliser.

Bien entendu, vous pouvez également parcourir votre système de fichiers plutôt que d'utiliser des constantes codées en dur, mais ceci n'est qu'un exemple.

EDIT - Généraliser pour les plugins
QGIS QGIS crée / modifie un certain nombre de variables d'environnement au démarrage. Vous pouvez donc créer des variables de chemin d'accès généralisées aux bibliothèques / utilitaires GDAL à l'aide de celles-ci (voir Paramètres-> Options-> Système) au lieu des chemins codés en dur de l'exemple ci-dessus.


Donc je ne peux pas faire ça? importer gdal_translate et ensuite appeler le .main ()?
Katie E.

Non, ça ne marchera pas. gdal_translate n'est pas un paquet Python, donc python n'en saura rien. Vous obtiendrez une erreur indiquant "ImportError No Module nommé gdal_translate". Utilisez le module de sous-processus pour l'appeler à la place.
MappaGnosis

ok une question similaire avec gdal_retile.py .. J'ai essayé de faire ce qui suit: import gdal_retile gdal_retile.main ("- v -r bilinear-level 4 -ps 2048 2048 -co \" tiled = YES \ "-targetDir cablepyramid - -optfile files.txt ") mais j'obtiens l'erreur suivante: Option de commande non reconnue: - Une idée pourquoi?
Katie E.

De prime abord, je ne vois pas le problème, sauf mon hypothèse: il se peut qu'il n'apprécie pas le commutateur '--optfile'. Ce dernier n'est pas documenté.
MappaGnosis

@MappaGnosis Existe-t-il une alternative à gdal_translate dans la bibliothèque python gdal?
multigoodverse

7

Je le fais avec différentes commandes gdal utilisant os.system que vous pouvez utiliser pour appeler des fonctions à partir de la ligne de commande:

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

Il est également décrit dans la conférence 7 ici: http://www.gis.usu.edu/~chrisg/python/2009/


Les commandes GDAL sont disponibles en tant que fonctions python dans GDAL 2.1 à RFC 59.1 . Aussi subprocess.callest plus sûr que os.system.
Dmitri Chubarov

1
Quelqu'un doit écrire un bon exemple de ces fonctions Python; Je me suis battu avec gdal.Warp()pendant quelques heures pour obtenir correctement une PG:source de données cutlineDSNamepour conduire le cutlineSQL. (Je sais, n'est-ce pas? Quelques heures à régler quelque chose ? L'horreur! </ Kidding>). Cela a finalement fonctionné, et il semble être beaucoup plus rapide que os.system()ou subprocess.call(). Il est fait ~ 2 millions cutlines, donc je ne sais pas s'il est effectivement plus rapide jusqu'à un certain temps ce soir ... mais il fonctionne tout à fait exact.
GT.

3

Voici un code rapide pour ceux qui souhaitent enregistrer des groupes d’un fichier TIF composite multibande composite dans des fichiers individuels à l’aide de GDAL Traduire en 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

Cela pourrait être utile pour un traitement ultérieur (par exemple, en utilisant Rasterio, comme ici ).

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.