Como chamar gdal_translate a partir do código Python?

40

É possível usar alguma API gdal para chamar gdal_translatedo código Python? Não quero dizer simplesmente executar o gdal_translate.exe no sistema de arquivos, mas chamá-lo de alguma forma no código, para que eu não precise saber o diretório exato em que o executável do gdal_translate está?

Katie E.
fonte
4
Sim, a partir de gdal-2.1. Esta resposta deve ser aceita como correta.
Pete

Respostas:

27

Desde o GDAL 2.1 (mais informações aqui ), os utilitários GDAL e OGR podem ser usados ​​como funções de biblioteca. Por exemplo:

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
fonte
2
Todas as opções que gdal.Translate()toma são listados aqui: gdal.org/python/osgeo.gdal-module.html#TranslateOptions
Marcelo Villa
23

Veja o Tutorial da 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 você deseja mais controle de saída, como redimensionamento, subconjunto, etc ... use uma VRT como entrada, é assim que o gdal_translate faz isso internamente.

user2856
fonte
infelizmente, isso não inclui a rejeição, inclui?
Riccardo
11
@butcher - não. Porque a pergunta não mencionou reprojeção. É claro que você pode reprojetar rasters com a API gdal python. Se você quiser saber como, faça uma nova pergunta.
28284
Eu já fiz isso aqui: gis.stackexchange.com/questions/103874/… mas thius foi marcado como um duplicado :-(
Riccardo
2
@ Butcher - que foi fechado como uma duplicata desta pergunta. Sua pergunta também faz perguntas sobre o gdal_translate. Você está ciente de que o gdal_translate não reprojeta? Se você quiser reprojetar, uso gdalwarp ou o método python API gdal - gdal.ReprojectImage
user2856
10

Sim, você pode chamar os Utilitários GDAL de dentro do Python. Existem diferenças muito pequenas na abordagem, dependendo se o utilitário é um exe por si só ou também um trecho de código python. De qualquer forma, você precisa usar o módulo de subprocesso :

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)

Você notará que adiciono aspas aos meus caminhos. Isso ocorre porque, no Windows, tive problemas com caminhos, especialmente com espaços ou onde um dos caracteres '\' cria outro caractere de escape acidental. Portanto, apenas preservo o caminho correto no aspec por assim dizer.

Se você estiver usando um dos utilitários python, faça o mesmo, exceto que o exe no início da cadeia de comando do subprocesso agora é "C: \ python32 \ python.exe" (ou qualquer versão que você tenha) e seu segundo elemento é o utilitário python que você deseja usar.

Obviamente, você também pode interagir com o sistema de arquivos em vez de usar constantes codificadas, mas este é apenas um exemplo.

EDIT - Generalizando para plugins
QGIS O QGIS cria / modifica várias variáveis ​​de ambiente na inicialização. Portanto, você pode criar variáveis ​​de caminho generalizadas para as bibliotecas / utilitários GDAL usando estas (consulte Configurações-> Opções-> Sistema) em vez dos caminhos codificados no exemplo acima.

MappaGnosis
fonte
Então eu não posso fazer isso? importar gdal_translate e, em seguida, chame o .main ()?
Katie E.
Não - isso não vai funcionar. gdal_translate não é um pacote Python, portanto, o python não saberá nada sobre isso. Você receberá um erro dizendo "ImportError No Module named gdal_translate". Use o módulo de subprocesso para chamá-lo.
MappaGnosis
ok uma pergunta parecida com o uso do gdal_retile.py .. Tentei fazer o seguinte: import gdal_retile gdal_retile.main ("- v -r bilinear -levels 4 -ps 2048 2048 -co \" tiled = YES \ "-targetDir cablepyramid -optfile files.txt "), mas recebo o erro: Opção de comando não reconhecida: - Alguma idéia do porquê?
Katie E.
Imediatamente, não consigo ver o problema, exceto que acho que ele pode não gostar da opção '--optfile'. Este último não está documentado.
MappaGnosis
@MappaGnosis Existe uma alternativa para gdal_translate na biblioteca Pydal gdal?
multigoodverse
7

Eu faço isso com vários comandos gdal usando os.system, que você pode usar para chamar funções, assim como na linha de comando:

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

Também está descrito na aula 7 aqui: http://www.gis.usu.edu/~chrisg/python/2009/

Máx.
fonte
Os comandos GDAL estão disponíveis como funções python no GDAL 2.1 a RFC 59.1 . Também subprocess.callé mais seguro que os.system.
Dmitri Chubarov
11
Alguém precisa escrever um bom exemplo dessas funções do Python; Eu lutei gdal.Warp()por um par de horas para obter uma PG:fonte de dados adequada cutlineDSNamepara conduzir o cutlineSQL. (Eu sei, certo? Duas horas realmente trabalhando em algo ? O horror! </kidding>). Finalmente, funcionou e parece ser significativamente mais rápido que os.system()ou subprocess.call(). Está fazendo ~ 2 milhões de linhas de corte, então não saberei se é realmente mais rápido até algum momento hoje à noite ... mas está funcionando exatamente certo.
GT.
3

Aqui está um código rápido para quem deseja salvar bandas de um TIF composto de várias bandas em arquivos individuais usando o GDAL Translate em 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

Isso pode ser útil para processamento adicional (por exemplo, usando o Rasterio, como aqui ).

15Step
fonte