Pour boucler un dossier vers des rasters de clip par lot par polygone en utilisant python et QGIS?

9

J'utilise python et QGIS 2.0. J'essaie de découper les rasters dans un dossier par une entité polygonale. C'est la première fois que j'utilise (disons) "PyQGIS", j'étais habitué à arcpy avant. Quoi qu'il en soit, je ne fais pas fonctionner mon script simple, toute suggestion serait très appréciée!

import qgis.core, qgis,utils
QgsApplication.setPrefixPath("C:/OSGeo4W64/apps/qgis", True)
QgsApplication.initQgis()

CLIP= "C:/Users/unim/Documents/Umberto/Universita/PhD/Guglielmin/Permafrost/Alta_Valtellina/Landsat_ita/study_area_foscagno.shp"
INPUT_FOLDER="C:/Users/unimi/Documents/Umberto/Universita/PhD/Guglielmin/Permafrost/Alta_Valtellina/Landsat_ita/LE71930282000259EDC00"
OUTPUT= "C:/Users/unim/Documents/Umberto/Universita/PhD/Guglielmin/Permafrost/Alta_Valtellina/Landsat_ita/foscagno_pyqgis/"


for RASTER in INPUT_FOLDER.tif
do
    echo "Processing $RASTER"
    gdalwarp -q -cutline CLIP -crop_to_cutline -of GTiff RASTER OUTPUT+ "clip_"+ RASTER
done

QgsApplication.exitQgis()

Vous trouverez ci-dessous les améliorations que j'ai apportées depuis maintenant, sans que le script fonctionne, mais je pense que je vais peut-être me rapprocher ...

import qgis.core, qgis.utils, os, fnmatch
from osgeo import gdal

CLIP= "C:/Users/unimi/Documents/Umberto/Universita/PhD/Guglielmin/Permafrost/Alta_Valtellina/Landsat_ita/study_area_foscagno.shp"
INPUT_FOLDER= "C:/Users/unimi/Documents/Umberto/Universita/PhD/Guglielmin/Permafrost/Alta_Valtellina/Landsat_ita/LE71930282000259EDC00/DNs2Reflectance_LE71930282000259EDC00"
OUTPUT= "C:/Users/unimi/Documents/Umberto/Universita/PhD/Guglielmin/Permafrost/Alta_Valtellina/Landsat_ita/Cloud_mask_AltaValtellina/clip_2_foscagno"

def findRasters (path, filter):
    for root, dirs, files in os.walk(path):
        for file in fnmatch.filter(files, filter):
            yield os.path.join (root, file)

for raster in findRasters (INPUT_FOLDER, '*.tif'):
    print (raster)
    outRaster = OUTPUT + '/clip_' + raster
    cmd = 'gdalwarp -dstnodata 0 -q -cutline CLIP -crop_to_cutline %s %s' % (raster, outRaster)
    os.system (cmd)

Je pense qu'il pourrait y avoir quelque chose de mal dans la commande "gdal", car la fonction "print" fait son travail correctement, mais aucun fichier n'est écrit dans la sortie, ni je ne reçois aucune erreur. Au fait, il a été difficile de fonder une documentation facile sur le codage gdal ...

umbe1987
la source
Eh bien pour commencer, vous mélangez Python et bash avec les scripts gdal. Vous pouvez le faire en utilisant simplement gdal ou avez-vous besoin d'utiliser pyqgis?
Nathan W
merci, je voudrais utiliser Python car ce ne serait qu'un point de départ pour un plus gros script. Est-il possible de l'utiliser comme je l'ai fait avec arcpy avec une solution de contournement?
umbe1987
Le CLIPdans l' cmdexpression est le problème. Si vous mettez une variable dans une chaîne, elle n'est pas lue. Au lieu de cela, vous concaténeriez la chaîne avec la variable.
Antonio Falciano
Je l'utilise à l'extérieur maintenant, il ne génère aucune erreur et il "imprime" correctement tous les rasters ".tif". Cependant, après avoir fait certaines choses (comme ouvrir 4 fois moins d'une seconde qu'une fenêtre), je n'obtiens aucune sortie dans mon dossier OUTPUT.
umbe1987
Vérifiez les chemins de trame avec print(cmd)à la place de os.system(cmd). Votre outRastervariable n'est pas correcte.
Antonio Falciano

Réponses:

9

Je suis d'accord avec Nathan. Vous devez pythoniser l'intégralité de votre script. Remplacez donc votre forboucle par quelque chose comme ceci:

import os, fnmatch

def findRasters (path, filter):
    for root, dirs, files in os.walk(path):
        for file in fnmatch.filter(files, filter):
            yield file

for raster in findRasters(INPUT_FOLDER, '*.tif'):
    inRaster = INPUT_FOLDER + '/' + raster
    outRaster = OUTPUT_FOLDER + '/clip_' + raster
    cmd = 'gdalwarp -q -cutline %s -crop_to_cutline %s %s' % (CLIP, inRaster, outRaster)
    os.system(cmd)

Remarque 1: je suppose que vos fichiers raster sont GeoTIFF ( *.tif).
Remarque 2: -of GTiff n'est pas nécessaire dans cmd, car il s'agit du format de sortie par défaut dans gdalwarp.

Antonio Falciano
la source
Merci. Cependant, il dit "os.command (cmd) AttributeError: l'objet 'module' n'a pas d'attribut 'command'", bien que le module "os" ait été importé ...
umbe1987
Ça devrait être os.system, tu as raison.
Antonio Falciano
4

J'ai finalement réussi avec ce script très simple et propre, qui appelle GDAL depuis Python sans l'importer (comme suggéré, mais en utilisant la méthode "Call ()" au lieu de "os.system ()". J'espère que cela pourrait aider!

import os, fnmatch
from subprocess import call
call(["ls", "-l"])

inFolder= 'C:/Users/unimi/Documents/Umberto/Universita/PhD/Guglielmin/Permafrost/Alta_Valtellina/Landsat_ita/LE71930282000259EDC00/DNs2Reflectance_LE71930282000259EDC00/'
outFolder= 'C:/Users/unimi/Documents/Umberto/Universita/PhD/Guglielmin/Permafrost/Alta_Valtellina/Landsat_ita/Cloud_mask_AltaValtellina/clip_2_foscagno/'

os.chdir (inFolder)

def findRasters (path, filter):
    for root, dirs, files in os.walk(path, filter):
        for file in fnmatch.filter(files, filter):
            yield os.path.join (root, file)

for raster in findRasters (inFolder, '*.tif'):
    (infilepath, infilename)= os.path.split (raster)
    print infilename
    outRaster= outFolder+ 'clip_'+ infilename
    print outRaster
    warp= 'gdalwarp -dstnodata 0 -q -cutline %s -crop_to_cutline -of GTiff %s %s' % ('study_area_foscagno.shp', raster, outRaster)
    call (warp)
umbe1987
la source
4

Version modifiée de la solution de umbe1987 pour les utilisateurs Linux:

import os, fnmatch
from subprocess import call
call(["ls", "-l"])

inFolder= '/run/media/user/SOFT/LANDSAT/Bulk Order 595257/L8 OLI_TIRS/LC81840262015165LGN00/'
outFolder= '/run/media/user/SOFT/LANDSAT/Bulk Order 595257/summer_clipped/'
shp = '/run/media/user/SOFT/LANDSAT/Bulk Order 595257/vector/mask.shp'
os.chdir (inFolder)

def findRasters (path, filter):
    for root, dirs, files in os.walk(path, filter):
        for file in fnmatch.filter(files, filter):
            yield os.path.join (root, file)

for raster in findRasters (inFolder, '*.TIF'):
    (infilepath, infilename)= os.path.split (raster)
    print infilename
    outRaster= outFolder+ 'clip_'+ infilename
    print outRaster
    warp= 'gdalwarp -cutline \'%s\' -crop_to_cutline -dstalpha \'%s\' \'%s\'' % (shp, raster, outRaster)
    os.system(warp)
RustyDrill
la source