Зацикливание папок для пакетного копирования растров по полигонам с использованием Python и QGIS?

9

Я использую Python и QGIS 2.0. Я пытаюсь обрезать растры в папке одним полигоном. Это первый раз, когда я использую (скажем, «PyQGIS»), я раньше привык к Arcpy. В любом случае, мой простой сценарий не работает, любое предложение будет высоко оценено!

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

Ниже приведены улучшения, которые я сделал с тех пор, пока сценарий не работал, но я думаю, что могу быть ближе ...

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)

Я думаю, что может быть что-то не так в команде "gdal", так как функция "print" выполняет свою работу в основном, но файл не записывается в вывод, и я не получаю никакой ошибки. Кстати, трудно найти простую документацию по кодированию gdal ...

umbe1987
источник
Для начала вы смешиваете Python и bash с gdal-скриптингом. Вы можете сделать это, просто используя gdal, или вам нужно использовать pyqgis?
Натан W
спасибо, я бы хотел использовать Python, так как это было бы просто отправной точкой для более крупного скрипта. Можно ли использовать это, как я сделал с arcpy с некоторым обходным путем?
umbe1987
CLIPВ cmdвыражении является проблемой. Если вы поместите переменную в строку, она не будет прочитана. Вместо этого вы должны объединить строку с переменной.
Антонио Фальчано,
Сейчас я использую его снаружи, он не выдает никаких ошибок и «печатает» все растры «.tif» соответственно. Однако после выполнения некоторых действий (например, открытия 4 раза менее чем за секунду в окне) я не получаю вывод в папку OUTPUT.
umbe1987
Проверьте растровые пути с print(cmd)вместо os.system(cmd). Ваша outRasterпеременная неверна.
Антонио Фальчано

Ответы:

9

Я согласен с Натаном. Вы должны питонизировать весь ваш скрипт. Поэтому замените ваш forцикл на что-то вроде следующего:

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)

Примечание 1: я предполагаю, что ваши растровые файлы - GeoTIFF ( *.tif).
Примечание 2: -of GTiff не требуется в cmd, потому что это формат вывода по умолчанию в gdalwarp.

Антонио Фальчано
источник
благодарю вас. Тем не менее, он говорит: "os.command (cmd) AttributeError: у объекта 'module' нет атрибута 'command'", хотя модуль "os" был вставлен ...
umbe1987
Так и должно быть os.system, ты прав.
Антонио Фальчано,
4

Я наконец справился с этим очень простым и чистым скриптом, который вызывает GDAL из Python без его импорта (как предложено, но с использованием метода «Call ()» вместо «os.system ()». Надеюсь, это могло бы помочь!

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
источник
4

Модифицированная версия решения umbe1987 для пользователей 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
источник