使用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编码的简单文档...


首先,您将Python和bash与gdal脚本混合使用。您可以仅使用gdal来执行此操作,还是需要使用pyqgis?
内森·W

谢谢,我想使用Python,因为这只是更大脚本的起点。是否可以像使用arcpy一样使用它并提供一些解决方法?
umbe1987

CLIPcmd表达的问题。如果将变量放在字符串中,则不会读取该变量。相反,您将字符串与变量连接在一起。
Antonio Falciano 2013年

我现在在外面使用它,它不输出任何错误,并且适当地“打印”所有“ .tif”栅格。但是,做完一些事情之后(例如,打开4次少于一秒钟然后再打开一个窗口),我的OUTPUT文件夹中没有任何输出。
umbe1987

print(cmd)代替检查栅格路径os.system(cmd)。您的outRaster变量不正确。
Antonio Falciano

Answers:


9

我同意内森。您需要对整个脚本进行python化。因此,将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:'模块'对象没有属性'命令'”,尽管“ os”模块已被
导入

应该是os.system,您是对的。
Antonio Falciano

4

我终于用这个非常简单干净的脚本进行了管理,该脚本从Python调用了GDAL而不导入它(如建议的那样,但是使用“ 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)

4

面向Linux用户的umbe1987解决方案的修改版本:

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)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.