¿Cómo llamar a gdal_translate desde el código de Python?

40

¿Es posible usar alguna API de gdal para llamar gdal_translatedesde código Python? No me refiero simplemente a ejecutar gdal_translate.exe desde el sistema de archivos, sino a llamarlo de alguna manera en el código para que no necesite saber el directorio exacto en el que se encuentra el ejecutable gdal_translate.

Katie E.
fuente
44
Sí, a partir de gdal-2.1. Esta respuesta debe aceptarse como correcta.
Pete

Respuestas:

27

Desde GDAL 2.1 (más información aquí ), las utilidades GDAL y OGR pueden usarse como funciones de biblioteca. Por ejemplo:

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
fuente
2
Todas las opciones que gdal.Translate()toma se enumeran aquí: gdal.org/python/osgeo.gdal-module.html#TranslateOptions
Marcelo Villa
23

Consulte el tutorial de la API de 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 desea más control de salida, como cambiar el tamaño, subconjunto, etc., use un VRT como entrada, así es como gdal_translate lo hace internamente.

usuario2856
fuente
desafortunadamente esto no incluye el rechazo, ¿verdad?
Riccardo
1
@butcher - no. Porque la pregunta no mencionaba la reproyección. Por supuesto, puede reproyectar rásteres con la API gdal python. Si quieres saber cómo, haz una nueva pregunta.
usuario2856
Ya lo hice aquí: gis.stackexchange.com/questions/103874/… pero thius fue marcado como un duplicado :-(
Riccardo
2
@butcher: se cerró como un duplicado de esta pregunta. Tu pregunta también se refiere a gdal_translate. ¿Sabías que gdal_translate no se reproyecta? Si desea reproyectar, use gdalwarp o el método API gdal python - gdal.ReprojectImage
user2856
10

Sí, puede llamar a las Utilidades GDAL desde Python. Existen diferencias muy pequeñas en el enfoque dependiendo de si la utilidad es un exe por derecho propio o también una pieza de código python. De cualquier manera, aunque necesita usar el módulo de subproceso :

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)

Notarás que agrego comillas escapadas alrededor de mis caminos. Esto se debe a que, en Windows, he tenido problemas con las rutas, especialmente las que tienen espacios o donde uno de los caracteres '\' genera otro carácter de escape accidental. Entonces, solo conservo el camino correcto en aspec por así decirlo.

Si está utilizando una de las utilidades de python, simplemente haga lo mismo, excepto que su exe al comienzo de la cadena de comando del subproceso ahora es "C: \ python32 \ python.exe" (o la versión que tenga) y su segundo elemento es la utilidad python que quieres usar.

Obviamente, también puede iterar sobre su sistema de archivos en lugar de usar constantes codificadas, pero esto es solo un ejemplo.

EDITAR: generalización de los complementos
QGIS QGIS crea / modifica una serie de variables de entorno al inicio. Por lo tanto, puede crear variables de ruta generalizadas para las bibliotecas / utilidades GDAL utilizando estas (consulte Configuración-> Opciones-> Sistema) en lugar de las rutas codificadas en el ejemplo anterior.

MappaGnosis
fuente
¿Entonces no puedo hacer esto? importar gdal_translate y luego llamar a .main ()?
Katie E.
No, eso no funcionará. gdal_translate no es un paquete de Python, por lo que python no sabrá nada al respecto. Recibirá un error que dice "ImportError No Module llamado gdal_translate". Utilice el módulo de subproceso para llamarlo en su lugar.
MappaGnosis
ok una pregunta similar con el uso de gdal_retile.py .. Traté de hacer lo siguiente: import gdal_retile gdal_retile.main ("- v -r bilinear -levels 4 -ps 2048 2048 -co \" tiled = YES \ "-targetDir cablepyramid - -optfile files.txt ") pero aparece el error: Opción de comando no reconocida: - ¿Alguna idea de por qué?
Katie E.
De improviso, no puedo ver el problema, excepto que supongo que es posible que no le guste el interruptor '--optfile'. Este último no está documentado.
MappaGnosis
@MappaGnosis ¿Existe una alternativa de gdal_translate dentro de la biblioteca gdal de Python?
multigoodverse
7

Hago esto con varios comandos de gdal usando os.system que puedes usar para llamar funciones como desde la línea de comandos:

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

También se describe en la clase 7 aquí: http://www.gis.usu.edu/~chrisg/python/2009/

Max
fuente
Los comandos GDAL están disponibles como funciones de python en GDAL 2.1 a través de RFC 59.1 . También subprocess.calles más seguro que os.system.
Dmitri Chubarov
1
Alguien necesita escribir un buen ejemplo de esas funciones de Python; Luché gdal.Warp()durante un par de horas para obtener correctamente una PG:fuente de datos cutlineDSNamepara conducir el cutlineSQL. (Lo sé, ¿verdad? ¿Un par de horas realmente resolviendo algo ? ¡El horror! </kidding>). Finalmente funcionó, y parece ser significativamente más rápido que os.system()o subprocess.call(). Está haciendo ~ 2 millones de líneas de corte, por lo que no sabré si en realidad es más rápido hasta algún momento esta noche ... pero está funcionando exactamente bien.
GT.
3

Aquí hay un código rápido para cualquier persona que desee guardar bandas de un TIF compuesto de múltiples bandas en archivos individuales utilizando GDAL Translate 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

Esto podría ser útil para un procesamiento posterior (por ejemplo, usando Rasterio, como aquí ).

15 paso
fuente