Utilisation de Rasterio ou GDAL pour empiler plusieurs bandes sans utiliser de commandes de sous-processus

11

Quelqu'un a-t-il un moyen éloquent d'empiler plusieurs fichiers .tif dans une pile à plusieurs bandes en utilisant Rasterio et / ou GDAL?

Je cherche un moyen d'éviter d'utiliser une commande de sous-processus comme gdal_merge.py et plutôt de l'avoir dans le cadre de mon script python.

Je sais que Rasterio et GDAL lisent les fichiers .tif sous forme de tableaux, mais comment puis-je empiler ces tableaux et écrire le résultat sous forme de bandes distinctes?

Jens Hiestermann
la source

Réponses:

20

En utilisant rasteriovous pourriez faire

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))

Cela suppose bien sûr que vos couches d'entrée partagent déjà la même étendue, la même résolution et le même type de données

Loïc Dutrieux
la source
1
Oui, c'est essentiellement ce que fait le programme rio-stack de Rasterio : github.com/mapbox/rasterio/blob/master/rasterio/rio/… .
sgillies
Est-il efficace de conserver la pile en mémoire (pour exécuter plusieurs fonctions sur les différentes bandes) au lieu d'écrire le fichier empilé? Ou doit-il être écrit dans un fichier puis manipulé?
Shawn
hélas, j'obtiens cette erreur "RasterioIOError: '/' n'est pas reconnu comme format de fichier pris en charge."
ilFonta
@ilFonta, faites une nouvelle question avec un exemple de code minimal reproductible.
bugmenot123
13

Si vous utilisez GDAL 2.1+ il est aussi simple que gdal.BuildVRTpuis 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
la source