¿Para la carpeta de bucle a los rásteres de recorte por lotes por polígono usando Python y QGIS?

9

Estoy usando python y QGIS 2.0. Estoy tratando de recortar rásteres en una carpeta por una función de polígono. Es la primera vez que uso (digamos) "PyQGIS", estaba acostumbrado a hacer arcpy antes. De todos modos, no logro que mi script simple funcione, ¡cualquier sugerencia sería muy apreciada!

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

A continuación se muestran las mejoras que he realizado desde ahora, aunque no logro que el script funcione, pero creo que podría estar acercándome ...

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)

Creo que puede haber algo mal en el comando "gdal", ya que la función "imprimir" hace su trabajo correctamente, pero no se escribe ningún archivo en la salida, ni recibo ningún error. Por cierto, ha sido difícil encontrar una documentación fácil sobre la codificación de gdal ...

umbe1987
fuente
Bueno, para empezar, estás mezclando Python y bash con scripts gdal. ¿Puedes hacer esto solo usando gdal o necesitas usar pyqgis?
Nathan W
gracias, me gustaría usar Python ya que este sería solo un punto de partida para un script más grande. ¿Es posible usarlo como lo hice con arcpy con alguna solución?
umbe1987
El CLIPen la cmdexpresión es el problema. Si coloca una variable en una cadena, no se lee. En su lugar, concatenaría la cadena con la variable.
Antonio Falciano
Lo estoy usando afuera ahora, no genera ningún error y "imprime" todos los rásteres ".tif" correctamente. Sin embargo, después de hacer algunas cosas (como abrir 4 veces por menos de un segundo por ventana), no obtengo ningún resultado en mi carpeta de SALIDA.
umbe1987
Compruebe las rutas de trama con print(cmd)en lugar de os.system(cmd). Tu outRastervariable no es correcta.
Antonio Falciano

Respuestas:

9

Estoy de acuerdo con Nathan. Necesita pythonize todo su script. Así que sustituya su forciclo con algo como lo siguiente:

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)

Nota 1: supongo que sus archivos ráster son GeoTIFF ( *.tif).
Nota 2: -of GTiff no es necesario en cmd, porque es el formato de salida predeterminado en gdalwarp.

Antonio Falciano
fuente
gracias. Sin embargo, dice "os.command (cmd) AttributeError: el objeto 'módulo' no tiene atributo 'comando'", aunque el módulo "os" se ha importado ...
umbe1987
Debería ser os.system, tienes razón.
Antonio Falciano
4

Finalmente me las arreglé con este script muy simple y limpio, que llama a GDAL desde Python sin importarlo (como se sugiere, pero usando el método "Call ()" en lugar de "os.system ()". ¡Espero que esto pueda ayudar!

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
fuente
4

Versión modificada de la solución de umbe1987 para usuarios de 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)
Taladro oxidado
fuente