สำหรับการวนลูปโฟลเดอร์ไปยังชุดคลิปแรสเตอร์โดยรูปหลายเหลี่ยมโดยใช้ python และ QGIS?


9

ฉันใช้ python และ QGIS 2.0 ฉันพยายามที่จะคลิป rasters ในโฟลเดอร์ด้วยคุณสมบัติรูปหลายเหลี่ยมเดียว มันเป็นครั้งแรกที่ฉันใช้ (สมมุติ) "PyQGIS" ฉันเคยชินกับการโค้งก่อน อย่างไรก็ตามฉันไม่ได้รับสคริปต์ง่ายๆของฉันทำงานข้อเสนอแนะใด ๆ จะได้รับการชื่นชมมาก!

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 scripting คุณสามารถทำได้โดยใช้ gdal หรือคุณจำเป็นต้องใช้ pyqgis?
นาธาน W

ขอบคุณคุณฉันต้องการใช้ Python เพราะนี่เป็นเพียงจุดเริ่มต้นสำหรับสคริปต์ที่ใหญ่กว่า เป็นไปได้หรือไม่ที่จะใช้อย่างที่เคยทำกับ arcpy กับวิธีแก้ปัญหาบางอย่าง
umbe1987

CLIPในcmdการแสดงออกที่เป็นปัญหา หากคุณใส่ตัวแปรในสตริงมันจะไม่อ่าน คุณจะเชื่อมสตริงกับตัวแปรแทน
Antonio Falciano

ฉันกำลังใช้มันอยู่ข้างนอกตอนนี้มันจะไม่แสดงข้อผิดพลาดใด ๆ และ "พิมพ์" rasters ".tif" ทั้งหมดอย่างถูกต้อง อย่างไรก็ตามหลังจากทำบางสิ่ง (เช่นการเปิด 4 ครั้งน้อยกว่าหนึ่งวินาทีในหน้าต่าง) ฉันไม่ได้รับผลลัพธ์ใด ๆ ในโฟลเดอร์ OUTPUT ของฉัน
umbe1987

ตรวจสอบเส้นทางแรสเตอร์ที่มีในสถานที่ของprint(cmd) ตัวแปรos.system(cmd)ของคุณoutRasterไม่ถูกต้อง
Antonio Falciano

คำตอบ:


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ไม่จำเป็นต้องใช้ในเพราะมันเป็นรูปแบบการออกค่าเริ่มต้นในcmdgdalwarp


ขอบคุณ. แต่ก็บอกว่า "os.command (cmd) AttributeError: 'โมดูล' วัตถุมีแอตทริบิวต์ไม่ 'คำสั่ง'" แม้ว่า "ระบบปฏิบัติการ" โมดูลได้รับการ inported ...
umbe1987

มันควรจะเป็นos.systemคุณถูกต้อง
Antonio Falciano

4

ในที่สุดฉันก็จัดการกับสคริปต์ที่เรียบง่ายและสะอาดซึ่งเรียก GDAL จาก Python โดยไม่ต้องนำเข้า (ตามที่แนะนำ แต่ใช้วิธี "โทร ()" แทน "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

เวอร์ชั่นที่แก้ไขของumbe1987`sโซลูชันสำหรับผู้ใช้ 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)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.