一、前言与准备
在GIS数据处理中,我们经常需要从大范围的栅格数据中提取出研究区域的部分,这就需要进行栅格裁剪操作。例如:从全国DEM数据中提取某个省份的高程数据、从卫星影像中裁剪出目标流域范围等。当需要裁剪的栅格数量较多时,手动操作效率低下。本文将介绍两种高效的方法:ArcGIS的"按掩膜提取"工具和Python脚本批量处理。
二、数据准备与环境设置
开始操作前,请确保以下数据和环境已准备就绪:
2.1 所需数据
| 数据类型 | 格式 | 说明 |
|---|---|---|
| 待裁剪栅格 | .tif / .img / .grid | 大范围栅格数据(如全国DEM、遥感影像) |
| 裁剪边界 | .shp / .gdb | 面状矢量数据(如行政边界、流域边界) |
| 输出文件夹 | — | 新建空文件夹,用于存放裁剪结果 |
2.2 环境检查
- 打开 ArcMap 或 ArcGIS Pro,确认 Spatial Analyst 扩展模块已启用
- 加载数据:通过"添加数据"按钮将栅格数据和矢量边界添加到数据框
- 检查坐标系:确保栅格数据和矢量边界的坐标系一致。如果不一致,先用"投影"或"投影栅格"工具统一坐标系
三、方法一:使用"按掩膜提取"工具(适合少量栅格)
"按掩膜提取"(Extract by Mask)是 ArcGIS 中最常用的栅格裁剪工具。它按照掩膜数据的空间范围提取栅格像元,操作直观简单。
打开工具对话框
在 ArcToolbox 中依次展开 Spatial Analyst Tools → 提取分析(Extraction),双击"按掩膜提取"(Extract by Mask)工具。或者在搜索栏直接输入"Extract by Mask"快速定位。
配置工具参数
在工具对话框中设置以下参数:
- 输入栅格(Input raster):选择待裁剪的栅格数据
- 输入栅格数据或要素掩膜数据(Input raster or feature mask data):选择矢量边界
- 输出栅格(Output raster):设置输出路径和文件名,建议使用 .tif 格式
环境设置(可选但推荐)
点击对话框底部的"环境设置",可进一步配置以下参数:
- 处理范围:设置为"与掩膜相同",确保输出栅格范围与矢量边界完全一致
- 像元大小:设置为"与输入栅格相同",保持原始分辨率不变
- 捕捉栅格:设置为输入栅格,确保输出像元与原始栅格对齐
执行并验证结果
点击"确定"执行工具。处理完成后,裁剪结果自动添加到地图中。通过以下方式验证结果:
- 检查栅格范围是否与矢量边界一致
- 对比原始栅格和裁剪结果的像元值(使用"识别"工具)
- 确认 NoData 区域是否正确处理
四、方法二:使用 Python 脚本批量裁剪(推荐)
当需要按多个边界裁剪大量栅格文件时,Python脚本是最佳选择。ArcGIS提供了ArcPy站点包,可以在Python环境中调用所有地理处理工具。以下提供两种场景的完整脚本。
场景一:单个边界裁剪多个栅格
适用情况:有多个栅格文件(如多年份的NDVI数据),需要用同一个矢量边界分别裁剪。
# -*- coding: utf-8 -*-
import arcpy
import os
# ============================================
# 场景一:同一边界裁剪多个栅格
# 在 ArcMap Python 窗口或 ArcGIS Pro 中运行
# ============================================
# 设置工作环境
arcpy.env.workspace = r"D:\GIS_Data\Raster" # 栅格所在文件夹
arcpy.env.overwriteOutput = True # 允许覆盖同名输出
# 配置路径
output_dir = r"D:\GIS_Data\Output" # 输出文件夹
clip_boundary = r"D:\GIS_Data\Boundary\study_area.shp" # 裁剪边界
# 创建输出文件夹
if not os.path.exists(output_dir):
os.makedirs(output_dir)
# 遍历所有tif栅格文件
raster_list = arcpy.ListRasters("*.tif")
total = len(raster_list)
print(f"共找到 {total} 个栅格文件,开始批量裁剪...")
for i, raster in enumerate(raster_list, 1):
out_name = os.path.join(output_dir, f"clip_{raster}")
arcpy.gp.ExtractByMask_sa(
in_raster=raster,
in_mask_data=clip_boundary,
out_raster=out_name
)
print(f"[{i}/{total}] 完成: {raster}")
print("所有栅格裁剪完成!")
场景二:多个边界分别裁剪同一栅格
适用情况:有一个大范围栅格,需要按多个矢量边界(如多个行政区域)分别裁剪。
# -*- coding: utf-8 -*-
import arcpy
import os
# ============================================
# 场景二:多个边界分别裁剪同一栅格
# 适用于按行政区域批量裁剪等场景
# ============================================
arcpy.env.workspace = r"D:\GIS_Data"
arcpy.env.overwriteOutput = True
raster_data = r"D:\GIS_Data\dem_province.tif" # 待裁剪栅格
boundary_fc = r"D:\GIS_Data\admin\counties.shp" # 包含多个面要素的矢量
output_dir = r"D:\GIS_Data\Output_Counties"
if not os.path.exists(output_dir):
os.makedirs(output_dir)
# 获取边界图层中每个要素的唯一标识字段
# 假设有 NAME 字段存储区域名称
with arcpy.da.SearchCursor(boundary_fc, ["NAME", "SHAPE@"]) as cursor:
for row in cursor:
name = row[0].replace(" ", "_") # 处理文件名中的空格
geometry = row[1]
# 为每个要素创建临时图层
temp_layer = "temp_layer"
arcpy.MakeFeatureLayer_management(boundary_fc, temp_layer)
arcpy.SelectLayerByAttribute_management(temp_layer, "NEW_SELECTION",
f"NAME = '{row[0]}'")
# 执行裁剪
out_raster = os.path.join(output_dir, f"dem_{name}.tif")
arcpy.gp.ExtractByMask_sa(raster_data, temp_layer, out_raster)
print(f"完成: {name}")
# 清理临时图层
arcpy.Delete_management(temp_layer)
print("所有区域裁剪完成!")
- 为栅格数据构建金字塔(使用"构建金字塔"工具),可显著提升读取速度
- 将输出格式设置为
.tif并启用 LZW 压缩,减小文件体积 - 大批量处理时,考虑使用 ArcGIS Server 或 Python multiprocessing 实现并行处理
五、常见问题与解决方案
问题1:裁剪后栅格范围比边界多出几个像元
原因:栅格数据的最小单元是像元,裁剪工具默认以像元为单位进行处理。当矢量边界落在一个像元内部时,该像元会被完整保留。
解决方案:在环境设置中将"处理范围"的"捕捉栅格"设置为输入栅格,确保输出像元与原始像元对齐。对范围精度要求极高时,可考虑在裁剪后再用矢量边界对栅格进行空值填充。
问题2:裁剪后的栅格存在黑色或白色边框
原因:边界以外的区域被赋值为 NoData,在没有背景显示时会呈现黑色或白色。
解决方案:在图层属性的"符号系统"选项卡中,勾选"显示背景值"并设置背景颜色为透明(NoData 设为无色);或者在"按掩膜提取"工具中将"提取区域"设为"INSIDE"。
问题3:Python脚本报错"No Spatial Analyst license"
原因:Spatial Analyst扩展模块未启用或授权不可用。
解决方案:在脚本开头添加以下代码,手动启用扩展:
# 启用 Spatial Analyst 扩展
if arcpy.CheckExtension("Spatial") == "Available":
arcpy.CheckOutExtension("Spatial")
print("Spatial Analyst 已启用")
else:
print("错误:Spatial Analyst 授权不可用")
问题4:大量栅格裁剪导致内存不足
解决方案:在脚本中每次处理完一个栅格后,使用 arcpy.Delete_management() 释放中间数据;关闭不需要的其他应用程序;将大栅格分块处理(使用"分割栅格"工具)。