Usando o Rasterio ou GDAL para empilhar várias bandas sem usar comandos de subprocesso

11

Alguém tem uma maneira eloquente de empilhar vários arquivos .tif em uma pilha de várias bandas usando o Rasterio e / ou o GDAL?

Estou procurando uma maneira de evitar o uso de um comando de subprocesso como gdal_merge.py e, em vez disso, tê-lo como parte do meu script python.

Eu sei que tanto o Rasterio quanto o GDAL leem os arquivos .tif como matrizes, mas como empilhei essas matrizes e escrevi o resultado como bandas separadas?

Jens Hiestermann
fonte

Respostas:

20

Usando rasteriovocê poderia fazer

import rasterio

file_list = ['file1.tif', 'file2.tif', 'file3.tif']

# Read metadata of first file
with rasterio.open(file_list[0]) as src0:
    meta = src0.meta

# Update meta to reflect the number of layers
meta.update(count = len(file_list))

# Read each layer and write it to stack
with rasterio.open('stack.tif', 'w', **meta) as dst:
    for id, layer in enumerate(file_list, start=1):
        with rasterio.open(layer) as src1:
            dst.write_band(id, src1.read(1))

Obviamente, assume que suas camadas de entrada já compartilham a mesma extensão, resolução e tipo de dados

Loïc Dutrieux
fonte
1
Sim, é essencialmente o que o programa rio-stack do Rasterio faz: github.com/mapbox/rasterio/blob/master/rasterio/rio/… .
sgillies
É eficiente manter a pilha na memória (para executar várias funções nas várias bandas) em vez de gravar o arquivo empilhado? Ou deveria ser gravado em um arquivo e depois manipulado?
Shawn
infelizmente, recebo este erro "RasterioIOError: '/' não reconhecido como um formato de arquivo suportado."
IlFonta 31/07/19
@ilFonta, faça uma nova pergunta com um exemplo de código mínimo reproduzível.
bugmenot123
13

Se estiver usando GDAL 2.1+ é tão simples como gdal.BuildVRTseguida gdal.Translate:

from osgeo import gdal
outvrt = '/vsimem/stacked.vrt' #/vsimem is special in-memory virtual "directory"
outtif = '/tmp/stacked.tif'
tifs = ['a.tif', 'b.tif', 'c.tif', 'd.tif'] 
#or for all tifs in a dir
#import glob
#tifs = glob.glob('dir/*.tif')

outds = gdal.BuildVRT(outvrt, tifs, separate=True)
outds = gdal.Translate(outtif, outds)
user2856
fonte