功能描述:
對於含有多個要素的矢量文件shp、柵格影像raster,按照shp中的各要素範圍,逐個對raster進行提取,並保存到文件夾中
效果如圖所示:
主要思路:
1)獲取矢量圖層、柵格圖層
2)遍歷矢量圖層中的要素
3)按要素裁剪柵格(有 Spatial Analysis-ExtractByMask;Clip_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個參數均設置爲可選選項,方便重複使用