arcgis使用python腳本批量裁剪影像

功能描述:

對於含有多個要素的矢量文件shp、柵格影像raster,按照shp中的各要素範圍,逐個對raster進行提取,並保存到文件夾中

效果如圖所示:

 

主要思路:

1)獲取矢量圖層、柵格圖層

2)遍歷矢量圖層中的要素

3)按要素裁剪柵格(有 Spatial Analysis-ExtractByMaskClip_management 兩種方法)

 

注意:

在裁剪影像時,可能出現柵格範圍小於矢量範圍的情況(如果shp200*200,柵格只有200*199)

方法1,Spatial Analysis-ExtractByMask,雖慢,但是十分穩定,在可以按矢量範圍裁剪,得到200*200

方法2,Clip_management雖快(約方法10倍速度),但是不太穩定,柵格缺失部分可能無法裁剪,得到200*199

根據個人對數據精度、速度要求,在代碼中選擇對應方法

 

代碼:

# -*- coding: utf-8 -*- 
# @Time : 2020/1/8 15:04 
# @Author : Zhao HL
# @File : extract by mask.py
import arcpy
import os,time

shp_path = r'E:\rs\sample_extent.shp'
img_path = r'E:\rs\m08.tif'
save_path = r'E:\rs\test'

arcpy.CheckOutExtension("Spatial")
def clear_folder(root_path):
    '''
    clear all files in root_path(include files in subfolders, but not folders)
    :param root_path:
    :return:
    '''
    files_list = os.listdir(root_path)
    for f in files_list:
        file_path = os.path.join(root_path,f)
        if os.path.isdir(file_path):
            clear_folder(file_path)
        else:
            os.remove(file_path)

    print('clear ' + root_path)

def clip_img(in_raster, clip_shp, workspace):
    '''
    according to features in the Shp, extract the raters one by one;
    all result rasters are saved at wordspace according to the FID field in Shp
    :param in_raster:
    :param clip_shp:
    :param workspace:
    :return:
    '''
    if arcpy.GetParameterAsText(0) != '':
        in_raster = arcpy.GetParameterAsText(0)
    if arcpy.GetParameterAsText(1) != '':
        clip_shp = arcpy.GetParameterAsText(1)
    if arcpy.GetParameterAsText(2) != '':
        workspace = arcpy.GetParameterAsText(2)

    clear_folder(workspace)
    arcpy.env.workspace = workspace

    t1 = time.time()
    for row in arcpy.SearchCursor(clip_shp):
        mask = row.getValue("Shape")
        FID = int(row.getValue("FID"))
        FID_name = str(FID).zfill(5)+'.tif'
        img_8_path = os.path.join(workspace, FID_name)

        #region method 1: slow but steady
        mask_raster = arcpy.sa.ExtractByMask(in_raster, mask)
        arcpy.CopyRaster_management(in_raster=mask_raster,
                                    out_rasterdataset=img_8_path,
                                    config_keyword="DEFAULTS",
                                    background_value=255,
                                    nodata_value=255,
                                    onebit_to_eightbit="", 
                                    colormap_to_RGB="", 
                                    pixel_type="8_BIT_UNSIGNED",
                                    scale_pixel_value=None,
                                    RGB_to_Colormap=None)
        #endregion

        #region method 2: fast but probably get null result
        #arcpy.Clip_management(in_raster, '#', img_8_path, mask, 0, "ClippingGeometry")
        # endregion

        t2 = time.time() - t1
        arcpy.AddMessage (FID_name+ ' is generated successfully,  total time:'+str(round(t2,2)))

if __name__ == "__main__":
    pass
    clip_img(img_path, shp_path, save_path)

實施細節:

1)裁剪出的文件名可以與已有文件重複,考慮到可能多次裁剪重複試驗,

因此調用clear_folder函數清除保留路徑下的所有文件(根據情況自行使用)

2)Clip_management 可能出現空結果(可能是路徑等問題),但比ExtractByMask快數倍

因此建議調試成功後使用Clip_management 方法

3)在arcmap中添加腳本

右擊my toolbox-new-tool box,新建工具箱

右擊新建的工具箱-add-script;第一頁設置默認;第二頁設置在script file中選擇python腳本文件、其餘默認;第三頁可以設置輸入參數,可以跳過,進行默認參數訓練,也可以按照4)進行設置。

4)輸入參數設置

可以直接在腳本中修改,在arcmap中跳過、不設置參數。

也可以在arcmap中按下圖將3個參數均設置爲可選選項,方便重複使用

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章