Python equivalente a gdalbuildvrt

12

Existe uma maneira de executar a mesma tarefa que o utilitário gdalbuildvrt usando as ligações GDAL Python? Até agora, não encontrei outra maneira de fazer isso, a não ser criar um vrt de um único conjunto de dados e editar manualmente o xml. Gostaria de criar um vrt a partir de vários rasters (essencialmente executando um mosaico). Isso é possível usando Python puro? Minha outra opção é usar o subprocesso para simplesmente chamar gdalbuildvrt.

Brian
fonte

Respostas:

10

Honestamente, é mais fácil fazer isso usando gdalbuildvrt em um subprocessor os.system.

Se você desejar fazer isso através do Python, isso pode ser feito. Usando os métodos de criação de conjuntos de dados padrão no GDAL Python, podemos criar facilmente o VRT do conjunto de dados base .

from osgeo import gdal

drv = gdal.GetDriverByName("VRT")
vrt = drv.Create("test.vrt", x_size, y_size, 0)

Observe que estamos criando o conjunto de dados sem bandas inicialmente. Na documentação dos VRTs, os conjuntos de dados VRT são um dos poucos tipos de conjuntos de dados que podem aceitar AddBandargumentos.

vrt.AddBand(gdal.GDT_Float32)
band = vrt.GetRasterBand(1)

Agora, para cada banda, precisamos definir os itens de metadados manualmente:

simple_source = '<SourceFilename relativeToVRT="1">%s</SourceFilename>' % source_path + \
    '<SourceBand>%i</SourceBand>' % source_band + \
    '<SourceProperties RasterXSize="%i" RasterYSize="%i" DataType="Real" BlockXSize="%i" BlockYSize="%i"/>' % (x_size, y_size, x_block, y_block) + \
    '<SrcRect xOff="%i" yOff="%i" xSize="%i" ySize="%i"/>' % (x_offset, y_offset, x_source_size, y_source_size) + \
    '<DstRect xOff="%i" yOff="%i" xSize="%i" ySize="%i"/>' % (dest_x_offset, dest_y_offset, x_dest_size, y_dest_size)
band.SetMetadataItem("SimpleSource", simple_source)
band.SetMetadataItem("NoDataValue", -9999)

SetMetadatItemrecebe dois argumentos, o primeiro uma sequência do item de metadados, o segundo o próprio item. Isso significa que você não pode subconjunto de um item de metadados; portanto, para fontes de dados, é necessário definir todo o conteúdo como uma sequência.

Observe que podemos usar esse método para criar fontes complexas ( ComplexSource) que contêm tabelas de consulta de valores, fontes de filtro do Kernel ( KernelFilteredSource) de tamanhos e formas arbitrárias e Bandas de máscara ( MaskBand).

om_henners
fonte
Obrigado @om_henners - acabei usando o subprocesso para ligar para gdalbuildvrt. Eu tenho mais experiência com Python do que com a linha de comando, então esperava poder fazer isso diretamente no Python, mas não vale a pena mexer na criação de strings XML, como você descreveu. Certamente é bom saber que eu posso fazer isso se for necessário no futuro.
18712 Brian
Acabei de encontrar um caso de uso para ter um equivalente em python: adicionando recursos não suportados. Por exemplo, o formato de arquivo vrt suporta um overviewselemento, mas o gdalbuildvrt não o usa. Obrigado por fornecer um esboço sobre como isso pode ser adicionado em python.
mate Wilkie
@om_henners existe alguma maneira de drv.CreateCopy ('caminho / para / arquivo.vrt', input_ds) com caminho absoluto para o arquivo input_ds em python? existe a opção relatedToVRT = "1", mas como alterá-la ou definir ao criar a VRT?
Dmitriy Litvinov
7

Desde o GDAL 2.1, as ferramentas CLI estão disponíveis como funções de biblioteca e, de fato, é o que as ferramentas CLI chamam agora internamente.

Por exemplo:

gdalbuildvrt -r cubic -addalpha my.vrt one.tif two.tif

É o equivalente a:

from osgeo import gdal

vrt_options = gdal.BuildVRTOptions(resampleAlg='cubic', addAlpha=True)
gdal.BuildVRT('my.vrt', ['one.tif', 'two.tif'], options=vrt_options)

As opções disponíveis da CLI são mapeadas diretamente para os parâmetros de BuildVRTOptions , além de alguns extras, como retornos de chamada de progresso disponíveis.

rcoup
fonte
7

A resposta de @rcoup só funcionou para mim, se modificada da seguinte maneira:

from osgeo import gdal 

vrt_options = gdal.BuildVRTOptions(resampleAlg='cubic', addAlpha=True)
my_vrt = gdal.BuildVRT('my.vrt', ['one.tif', 'two.tif'], options=vrt_options)
my_vrt = None

Caso contrário, o arquivo não será gravado no disco.

JensL
fonte
JensL obrigado! você pode explicar a intuição de my_vrt = None para gravar no disco? Apenas parece muito estranho
mmann1123
3
@ mmann1123 : Caso contrário, não funcionou e eu tinha em mente que o Tutorial da API GDAL dizia: "Observe que o método CreateCopy () retorna um conjunto de dados gravável e que deve ser fechado corretamente para concluir a gravação e a liberação do conjunto de dados no disco. No caso do Python, isso ocorre automaticamente quando "dst_ds" sai do escopo. " Desde que não exista closingpara python, você deve tirar seu vrtescopo, atribuindo-o a None.
JensL
Na verdade, eles apenas corrigiram esse problema (consulte osgeo-org.1560.x6.nabble.com/… )
umbe1987 07/02