Untuk mengulang folder ke batch raster klip dengan poligon menggunakan python dan QGIS?

9

Saya menggunakan python dan QGIS 2.0. Saya mencoba untuk klip raster di folder dengan satu fitur poligon. Ini pertama kalinya bagi saya menggunakan (katakanlah) "PyQGIS", saya sudah terbiasa dengan arcpy sebelumnya. Lagi pula, saya tidak membuat skrip sederhana saya berfungsi, saran apa pun akan sangat dihargai!

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

Di bawah ini adalah peningkatan yang telah saya lakukan sejak sekarang, tidak membuat skrip bekerja, tapi saya pikir saya mungkin semakin dekat ...

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)

Saya pikir mungkin ada sesuatu yang salah dalam perintah "gdal", karena fungsi "print" melakukan tugasnya dengan benar, tetapi tidak ada file yang ditulis ke output, saya juga tidak menerima kesalahan. Ngomong-ngomong, sulit untuk menyukai dokumentasi yang mudah tentang pengkodean gdal ...

umbe1987
sumber
Yah untuk memulai Anda mencampur Python dan bash dengan skrip gdal. Anda dapat melakukan ini hanya menggunakan gdal atau Anda perlu menggunakan pyqgis?
Nathan W
terima kasih, saya ingin menggunakan Python karena ini hanya akan menjadi titik awal untuk skrip yang lebih besar. Apakah mungkin untuk menggunakannya seperti yang saya lakukan dengan arcpy dengan beberapa solusi?
umbe1987
The CLIPdalam cmdekspresi masalahnya. Jika Anda meletakkan variabel dalam string, itu tidak dibaca. Sebagai gantinya, Anda akan menggabungkan string dengan variabel.
Antonio Falciano
Saya menggunakannya di luar sekarang, tidak menghasilkan kesalahan apa pun dan "mencetak" semua raster ".tif" dengan benar. Namun, setelah melakukan beberapa hal (seperti membuka 4 kali kurang dari sedetik jendela), saya tidak mendapatkan output di folder OUTPUT saya.
umbe1987
Periksa jalur raster dengan print(cmd)di tempat os.system(cmd). outRasterVariabel Anda salah.
Antonio Falciano

Jawaban:

9

Saya setuju dengan Nathan. Anda perlu membuat python seluruh skrip Anda. Jadi gantilah forloop Anda dengan sesuatu seperti berikut ini:

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)

Catatan 1: Saya kira file raster Anda adalah GeoTIFF ( *.tif).
Catatan 2: -of GTiff tidak diperlukan di cmd, karena ini adalah format keluaran default di gdalwarp.

Antonio Falciano
sumber
Terima kasih. Namun, ia mengatakan "os.command (cmd) AttributeError: objek 'module' tidak memiliki atribut 'command'", meskipun modul "os" telah
diportport
Seharusnya os.system, Anda benar.
Antonio Falciano
4

Saya akhirnya berhasil dengan skrip yang sangat sederhana dan bersih ini, yang memanggil GDAL dari Python tanpa mengimpornya (seperti yang disarankan, tetapi menggunakan metode "Call ()" alih-alih "os.system ()". Saya harap ini bisa membantu!

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

Versi modifikasi dari solusi umbe1987 untuk pengguna 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
sumber