Suite

Est-il possible d'utiliser gdal_calc.py avec un chemin entier de rasters ?


J'essaie d'utiliser gdal_calc.py pour mettre à l'échelle et transformer une série chronologique d'images MODIS. Je l'ai fait lorsque j'ai travaillé avec une seule image dans la variable -A et un masque dans -B, mais j'ai besoin de travailler avec un répertoire de 350 images .tif et de les convertir en raster ENVI .bin. Mon problème est de savoir comment affecter la variable -A pour réaliser l'opération avec toutes les images et obtenir 1 fichier de sortie par image

Pour travailler avec une seule image, j'utilise :

gdal_calc.py -A image.tif -B MASK10000 --calc="A/B" --NoDataValue=0 --format=ENVI --outfile=image.bin

J'utilise le bash linux, mais peut-être qu'un script python sous linux fonctionne mieux


J'utilise un moyen simple de résoudre ce problème en utilisant le bash UNIX.

J'ai créé un script dans le même chemin d'images et je l'ai exécuté ("script.sh").

#!/bin/bash for i in *.tif do gdal_calc.py -A $i -B MASK.dat --calc="A/B" --NoDataValue=0 --format=ENVI --outfile=directory/ $i.bin fait
  • MASK.dat est une image binaire avec seulement 10 000 valeurs à mettre à l'échelle dans la plage NDVI.
  • "i" sont toutes les images MODIS que j'ai besoin de convertir. "répertoire" est le chemin où toutes les sorties seront créées.

Il s'agissait ensuite d'utiliser les fichiers images dans le logiciel TIMESAT.


Il existe deux manières python de le faire simplement, utilisez os.walk() pour trouver les fichiers, puis créez un fichier batch ou utilisez subprocess.Popen() pour exécuter la commande.

Ce code contient à la fois… le fichier par défaut est le fichier batch qui peut être commuté en définissantUsingBat = Faux:

importer os, sys, sous-processus BaseInFolder = sys.argv[1] BaseOutFolder = sys.argv[2] MaskImage = sys.argv[3] UsingBat = True si UsingBat : FirstPartOfBat = "GDAL_CALC.py -A " SecondPartOfBat = " -B " + MaskImage + " --calc="A/B" --NoDataValue=0 --format=ENVI "#--outfile=image.bin TempDir = os.environ.get("Temp") # récupère le Répertoire 'temp' BatFile = os.path.join(TempDir,"RunMe.bat")# utilisez votre propre fichier batch si vous le souhaitez avec open(BatFile,'w') comme BatchWriter: for (path, dirs, files) in os.walk(BaseInFolder): pour le fichier dans les fichiers: fName,fExt = os.path.splitext(file) # vous voudrez peut-être penser à quelque chose ici pour limiter les types de fichiers # comme if len( fExt ) == 0: I je n'ai pas d'expérience avec MODIS donc je ne peux pas dire OutFileName = fName + fExt # si ce nom est déjà utilisé, essayez un autre nom si os.path.exists(os.path.join(BaseOutFolder,OutFileName)): Try = 1 while os.path.exists(os.path.join(BaseOutFolder,OutFileName)): OutFileName = fName + str(Try) + fExt Try += 1 # assembler la ligne de commande et wri te vers le fichier batch pBat = FirstPartOfBat + os.path.join(BaseOutFolder,file) + SecondPartOfBat + "--outfile=" +os.path.join(BaseOutFolder,OutFileName) BatchWriter.write(pBat + "
") # ne peut pas oublier la nouvelle ligne… Linux/Mac peut être différent sinon : FirstPartOfCommand = ["GDAL_CALC.py","-A"] SecondPartOfCommand = ["-B",MaskImage,"--calc="A/B" ","--NoDataValue=0","--format=ENVI"]#--outfile=image.bin pour (chemin, répertoires, fichiers) dans os.walk(BaseInFolder) : pour le fichier dans les fichiers : fName,fExt = os.path.splitext(file) # vous voudrez peut-être penser à quelque chose ici pour limiter les types de fichiers # comme if len( fExt ) == 0: je n'ai pas d'expérience avec MODIS donc je ne peux pas dire OutFileName = fName + fExt # si ce nom est déjà utilisé, essayez un autre nom si os.path.exists(os.path.join(BaseOutFolder,OutFileName)): Try = 1 while os.path.exists(os.path.join(BaseOutFolder) ,OutFileName)): OutFileName = fName + str(Try) + fExt Try += 1 # doit utiliser une nouvelle liste, sinon l'attribution directe modifie la liste existante # voir http://stackoverflo w.com/questions/2612802/how-to-clone-or-copy-a-list-in-python pOpenCommand = list(FirstPartOfCommand) pOpenCommand.append(os.path.join(path,file)) pOpenCommand.extend( SecondPartOfCommand) pOpenCommand.append("--outfile=" +os.path.join(BaseOutFolder,OutFileName)) ThisProc = subprocess.Popen(pOpenCommand) ThisProc.wait() # attendez la fin, vous n'en voulez pas 350 courir en même temps

À l'aide d'un fichier batch, vous devez compiler des chaînes et insérer des valeurs le cas échéant, écrire dans le fichier, puis exécuter le fichier (double-clic); En utilisant Popen, vous devez créer une liste de chaque élément de la commande - et sans oublier d'utiliser.attendre()sur le processus, sinon le code générera un processus et passera à un autre processus avant que le précédent ne se termine - vous finirez par remplir votre mémoire en quelques secondes.

Je n'ai rien à voir avec les données MODIS, donc je ne peux pas m'empêcher de limiter les fichiers d'entrée, vous devriez donc réfléchir à la façon dont vous allez limiter les fichiers…os.marche()renvoie tous les fichiers du dossier actuel et tous les sous-dossiers - vous aurez besoin d'un moyen de détecter si le fichier convient avant d'essayer de le convertir.


Voir la vidéo: Merge raster data with GDAL in Python (Octobre 2021).