
哈喽各位GIS小伙伴们~
你们是不是日常做地理数据生产、空间分析时,总被重复机械操作折磨?
几百个矢量/栅格数据要裁剪、投影、转格式,一个个点工具至少要半天,还容易出错漏!
今天我将给大家认真介绍下ArcGISPro自带的Python(ArcPy)语句,几行代码就能实现全自动批量处理基本流程化工作,代码可以实现,改个路径就能用的生产一线10大高频批量脚本,对各位宝子们照顾特殊,每一行都加了详细注释,搭配实际案例,我亲自实操验证过,新手也能轻松上手,建议收藏后随时查看!如果对你文章对你有用,欢迎转发、点赞、关注,评论区留言。#GIS技巧#ArcGISPro#Python批量处理#空间数据处理#测绘#数据分析#代码#批处理
学习之前点首轻音乐,愉快的学习吧。
话不多说,直接上开干。哈哈



本文所用的pyton代码均使用Python2.8以上的版本,所有脚本都在ArcGISPro的Python窗口或Notebook里运行,先记牢这几句基础代码,所有脚本都能套用,避免运行报错!
#导入ArcPy库,这是ArcGISProPython处理的核心库,必须导入importarcpy#导入os库,用于处理文件路径、文件夹操作,避免路径报错importos#允许覆盖已存在的文件,运行时不用手动删除旧成果arcpy.env.overwriteOutput=True#关闭Z因子,栅格/三维数据处理时避免坐标异常,(可选)arcpy.env.ZFactor=1
小伙伴们~实际操作请注意:
①所有文件路径必须用英文、数字,不要出现中文、空格、特殊字符如(\-),否则极易报错,如果确实需要-建议用下划线_。
②请小伙伴们~注意处理前一定备份数据哟,避免数据删除。
③严格注意Python的缩减。
甲方爸爸经常给我们项目区有几百张DOM栅格、几百个地块矢量图层,需要用项目边界统一裁剪,剔除无关区域,手动裁剪至少2小时,代码1分钟搞定!
# 导入ArcGIS核心库import arcpy# 导入路径处理库import os# 允许覆盖输出文件arcpy.env.overwriteOutput = True# 设置输入栅格所在文件夹(改成你自己的栅格目录)arcpy.env.workspace = r"D:\data\input_rasters"# 裁剪边界文件(shp或gdb要素类)clip_mask = r"D:\data\mask.shp"# 裁剪结果输出文件夹out_folder = r"D:\data\clip_result"# 自动列出工作空间下所有栅格文件(tif、img等)rasters = arcpy.ListRasters()# 开始循环,逐个处理每一张栅格for ras in rasters:# 拼接输出路径:输出文件夹 + 原文件名,保证名字不变out_ras = os.path.join(out_folder, ras)# 执行栅格裁剪工具arcpy.management.Clip(in_raster=ras,rectangle="",out_raster=out_ras,in_template_dataset=clip_mask,nodata_value="",clipping_geometry="ClippingGeometry")# 输入当前栅格# 范围留空,使用边界范围# 输出栅格路径# 裁剪边界# 空值不设置 # 按边界形状裁剪# 控制台打印进度,方便查看运行到哪一个print(f"已完成裁剪:{ras}")

①需要特别注意输入的是上述代码使用的是一个shp数据去裁剪多个影像,适用于一个范围的shp数据区裁剪历年的影像数据。
import arcpyimport osarcpy.env.overwriteOutput = True# 设置输入矢量所在的地理数据库(gdb路径)arcpy.env.workspace = r"D:\GIS项目\原始矢量数据.gdb"# 裁剪边界路径clip_mask = r"D:\GIS项目\项目边界.shp"# 输出成果地理数据库(提前新建空gdb)out_gdb = r"D:\GIS项目\裁剪后矢量成果.gdb"# 自动遍历工作空间内所有矢量要素类fcs = arcpy.ListFeatureClasses()# 循环批量裁剪for fc in fcs:# 输出要素命名:原名称+_clip,方便区分out_fc = os.path.join(out_gdb, fc + "_clip")# 执行矢量裁剪工具arcpy.analysis.Clip(fc, clip_mask, out_fc)# 打印处理日志print(f"矢量裁剪完成:{fc}")
测试数据完成截图如下:
①需要特别注意的是上述代码使用的是一个shp数据去裁剪多个矢量数据,其中shp需单独放在一个文件夹下,多个矢量数据表示的是一个数据库下同样的数据包含多个(如历年的DLTB)。
②存放的路径是单独的gdb数据库,该行代码无法实现数据集下的多个图层,小伙伴们~需注意哟。
③处理上述代码前请保证你的shp数据、影像数据及矢量数据的空间位置一致。
我们在收集外业采集的数据时,经常坐标系混乱(WGS84、北京54、西安80),数据入库要求统一转CGCS2000经纬度/投影坐标系,批量一键转换,杜绝坐标偏移!
import arcpyimport osarcpy.env.overwriteOutput = True# ====================== 【这里改成你自己路径】 ======================arcpy.env.workspace = r"E:\测试数据\待投影数据.gdb" # 原始GDBout_gdb = r"E:\测试数据\CGCS2000投影成果.gdb" # 输出GDB# !!重要:如果你的数据原本是某已知坐标系,在这里指定原始WKIDsource_wkid = 4537 # 举例:比如原本是西安80 3度带,改成你实际的。# =================================================================# 创建输出GDB(不存在就新建)if not arcpy.Exists(out_gdb):arcpy.management.CreateFileGDB(os.path.dirname(out_gdb), os.path.basename(out_gdb))# 目标坐标系 CGCS2000 地理坐标系(4490)out_sr = arcpy.SpatialReference(4490)# 遍历所有要素类fcs = arcpy.ListFeatureClasses()for fc in fcs:# 获取当前要素空间参考desc = arcpy.Describe(fc)in_sr = desc.spatialReference# 处理:无坐标系/未知坐标系if in_sr.name == "Unknown":print(f"【警告】{fc} 无定义坐标系,临时指定预设原始坐标系WKID:{source_wkid}")in_sr = arcpy.SpatialReference(source_wkid)# 先给图层定义投影arcpy.management.DefineProjection(fc, in_sr)out_fc = os.path.join(out_gdb, f"{fc}_CGCS2000")try:arcpy.management.Project(fc, out_fc, out_sr)print(f"✅ 投影成功:{fc} -> {os.path.basename(out_fc)}")except Exception as e:print(f"❌ 投影失败:{fc},错误信息:{str(e)}")
测试数据完成截图如下:

1.你必须确认自己原始数据真实坐标系,把source_wkid改成对应编号:如果不知道请在投影工具下照到数据的基本坐标系WKID编号如下入所示:

需要特别注意:CGCS20003度带/高斯克吕格、西安80、北京54对应不同WKID。
2.代码会先给无坐标系的数据先定义原始投影,再执行转换。
3.自动判断并新建输出GDB,避免路径报错。
Arcgis Pro中常用坐标系EPSG码
3°带带号 | 中央经线 | ArcGISWKID代号 |
25 | 75° | 4526 |
26 | 78° | 4527 |
27 | 81° | 4529 |
28 | 84° | 4530 |
29 | 87° | 4531 |
30 | 90° | 4532 |
31 | 93° | 4533 |
32 | 96° | 4534 |
33 | 99° | 4535 |
34 | 102° | 4536 |
35 | 105° | 4537 |
36 | 108° | 4538 |
37 | 111° | 4539 |
38 | 114° | 4540 |
39 | 117° | 4541 |
40 | 120° | 4542 |
41 | 123° | 4543 |
42 | 126° | 4544 |
43 | 129° | 4545 |
44 | 132° | 4546 |
45 | 135° | 4547 |
我们在处理土地利用数据、路网数据入库前,需要统一添加面积、长度、中心点坐标字段,自动计算属性,不用手动逐个添加!
import arcpyimport osarcpy.env.overwriteOutput = True# 输入需要处理的矢量数据路径arcpy.env.workspace = r"E:\测试数据\测试数据1.gdb"# 遍历所有矢量要素fcs = arcpy.ListFeatureClasses()for fc in fcs:# 1. 添加面积字段,字段类型为双精度(DOUBLE),存储小数arcpy.management.AddField(fc, "mj", "DOUBLE", field_alias="实测面积(㎡)")# 2. 计算面积,单位:平方米,如需公顷改成"SQUARE_HECTARES"arcpy.management.CalculateGeometryAttributes(fc, [["mj", "AREA"]], area_unit="SQUARE_METERS")# 3. 添加x字段arcpy.management.AddField(fc, "CENTROID_X", "DOUBLE", field_alias="X坐标")# 4. 添加y字段arcpy.management.AddField(fc, "CENTROID_Y", "DOUBLE", field_alias="y坐标")# 4. 游标更新坐标with arcpy.da.UpdateCursor(fc,["SHAPE@","CENTROID_X","CENTROID_Y"]) as cursor:for r in cursor:c = r[0].centroidr[1] = c.Xr[2] = c.Ycursor.updateRow(r)print(f"字段添加+几何计算完成:{fc}")
测试数据完成截图如下:

上述代码为计算面要素的质心坐标,若要批量添加线的字段和计算线的长度请替换下述代码:
#添加长度字段arcpy.management.AddField(in_table=fc,field_name="Shape_Length",field_type="DOUBLE",field_alias="长度(m)")#计算长度arcpy.management.CalculateGeometryAttributes(in_features=fc,geometry_property=[["Shape_Length","LENGTH"]],length_unit="METERS")print(f"字段与几何计算完成:{fc}")
自己的思考!(其实上述代码还可以批量实现点、线、面要素的中心的坐标,最小X/Y坐标、最大X/Y坐标的批量写入)这些数据的获取,可以为后期点线面之间的空间位置距离管关系打下基础,也能实现比例尺的缩放,固定比例尺出图等实现自动化输出。
在我们处理数据时候经常按乡镇名称、固定字段分割数据,分发给各个乡镇工作人员使用,手动分割太繁琐,代码自动按字段拆分!
import arcpyarcpy.env.overwriteOutput = True# 输入需要分割的完整矢量数据路径input_fc = r"E:\测试数据\测试数据1.gdb\test"# 分割后成果输出文件夹(空文件夹)out_workspace = r"E:\测试数据\按乡镇分割成果"# 执行按属性分割工具,最后一个参数是分割字段(改成你的字段名:乡镇/区县/图幅号)arcpy.analysis.SplitByAttributes(input_fc, out_workspace, "CITY_NAME")
测试数据完成截图如下:

小伙伴们~注意啦,上述代码输入需要分割的完整矢量数据路径建议你在分发任务前,请保证你要素图层名称唯一。
多个乡镇的路网、地块数据,需要合并成全区完整数据,用于整体空间分析,批量合并避免手动选择遗漏!
import arcpyarcpy.env.overwriteOutput = True# 输入待合并的矢量数据所在gdbarcpy.env.workspace = r"E:\测试数据\处理结果.gdb"# 筛选同类要素:比如只合并前缀为road_的路网数据,按需修改匹配规则fcs = arcpy.ListFeatureClasses("test_*")# 合并后成果输出路径out_fc = r"E:\测试数据\合并成果.gdb\megre"# 执行合并工具,自动拼接所有符合条件的要素arcpy.management.Merge(fcs, out_fc)print(f"批量合并完成,共合并{len(fcs)}个图层")
测试数据完成截图如下:

不同时期的DEM、DOM数据分辨率不一(0.5m、1m、2m),空间分析前统一分辨率,保证数据精度一致!
import arcpyimport osarcpy.env.overwriteOutput = True# 输入原始栅格数据文件夹arcpy.env.workspace = r"E:\测试数据\原始栅格dem"# 输出重采样后栅格文件夹out_folder = r"E:\测试数据\成果栅格dom"# 遍历所有栅格rasters = arcpy.ListRasters()for ras in rasters:out_ras = os.path.join(out_folder, ras)# 重采样工具:输入、输出、分辨率(1.0=1米)、重采样方法(双线性插值,适合栅格)arcpy.management.Resample(ras, out_ras, 1.0, "BILINEAR")print(f"栅格重采样完成:{ras}")
测试数据完成截图如下:
小伙伴们~注意啦:上述代码也同样适用dom数据批量重采样,保证空间分辨率是一致的,但前提条件你的栅格数据空间坐标系需一致哟,同时重采样应该依据是分辨率从小到大的原则。反之可能导致你的结果不理想。嘿嘿

!!!
1.地理数据库(gdb)内的矢量数据,需要批量导出SHP给同事,或导出DWG给设计单位,一键批量导出!
import arcpyimport osarcpy.env.overwriteOutput=True#输入gdb数据路径arcpy.env.workspace=r"D:\GIS项目\成果数据.gdb"#导出SHP输出文件夹out_folder=r"D:\GIS项目\SHP格式成果"#遍历所有矢量,批量导出SHPfcs=arcpy.ListFeatureClasses()for fc in fcs:arcpy.conversion.FeatureClassToShapefile(fc,out_folder)print(f"批量导出SHP完成:{fc}")
测试数据shp完成截图如下:

2.地理数据库(gdb)内的矢量数据,需要批量导出DWG给设计单位,一键批量导出的代码如下:
importarcpyimportosarcpy.env.overwriteOutput=True#输入gdb数据路径arcpy.env.workspace=r"D:\GIS项目\成果数据.gdb"#导出SHP输出文件夹out_folder=r"D:\GIS项目\CAD格式成果"#遍历所有矢量,批量导出CAD#【CAD导出替换代码】,把上面导出SHP的循环换成这段即可for fc in fcs:out_cad=os.path.join(out_folder,fc+".dwg")arcpy.conversion.ExportCAD(fc,"DWG_R2018",out_cad)print(f"批量导出CAD完成:{fc}")
测试数据CAD完成截图如下:

另外这里给小伙伴们~整理出导出CAD类型的表格,方便大家查看Arcgis pro 输出cad类型关系对照表,贴心吧

。
序号 | 输出CAD类型 | 说明 |
1 | DGN_V8 | 输出类型将为MicrostationDGN。 |
2 | DWG_R2018 | 输出类型将为DWG2018版。这是默认设置。 |
3 | DWG_R2013 | 输出类型将为DWG2013版。 |
4 | DWG_R2010 | 输出类型将为DWG2010版。 |
5 | DWG_R2007 | 输出类型将为DWG2007版。 |
6 | DWG_R2005 | 输出类型将为DWG2005版。 |
7 | DWG_R2004 | 输出类型将为DWG2004版。 |
8 | DWG_R2000 | 输出类型将为DWG2000版。 |
9 | DWG_R14 | 输出类型将为DWG14版。 |
10 | DXF_R2018 | 输出类型将为DXF2018版。 |
11 | DXF_R2013 | 输出类型将为DXF2013版。 |
12 | DXF_R2010 | 输出类型将为DXF2010版。 |
13 | DXF_R2007 | 输出类型将为DXF2007版。 |
14 | DXF_R2005 | 输出类型将为DXF2005版。 |
15 | DXF_R2004 | 输出类型将为DXF2004版。 |
16 | DXF_R2000 | 输出类型将为DXF2000版。 |
17 | DXF_R14 | 输出类型将为DXF14版。 |
八、批量数据质检(修复几何+删除空要素)
很多时候我们在使用Arcgis pro数据入库前需要对基础数据进行质检,清理自相交、空几何、无效几何等问题,避免入库失败、分析出错!
import arcpyarcpy.env.overwriteOutput = True##输入待质检数据路径arcpy.env.workspace = r"E:\测试数据\测试数据1.gdb"# 遍历数据库下所有图层fcs = arcpy.ListFeatureClasses()for fc in fcs:# 检查几何错误arcpy.management.CheckGeometry(fc)# 自动修复几何错误arcpy.management.RepairGeometry(fc)# 选择没有几何图形的空要素arcpy.management.SelectLayerByAttribute(in_layer_or_view=fc,selection_type="NEW_SELECTION",where_clause="Shape IS NULL")# 删除选中的空要素arcpy.management.DeleteRows(fc)print(f"数据质检与修复完成:{fc}")
测试数据完成截图如下

这里的数据库的数据请保证空间位置一致,否则容易报错,处理数据前请备份好自己的数据,避免删除数据。
经常我们在拿着甲方反馈给我们的基础航飞影像数据存在多幅的情况,打开数据半天才能加载在一起,有时候还容易报错。那么下面的代码是将多幅DOM、DEM影像,拼接成一张完整的区域影像,用于制图和分析!
import arcpyimport osarcpy.env.overwriteOutput=True#输入待拼接栅格文件夹arcpy.env.workspace=r"E:\测试数据\原始栅格路径"#拼接后成果输出路径out_mosaic=r"E:\测试数据\成果栅格dom\成果DOM.tif"#遍历所有栅格rasters=arcpy.ListRasters()#执行栅格拼接工具arcpy.management.MosaicToNewRaster(rasters,os.path.dirname(out_mosaic),os.path.basename(out_mosaic),pixel_type="8_BIT_UNSIGNED",number_of_bands=3)print("栅格批量拼接完成!")
测试数据完成截图如下

输入待拼接栅格文件夹下的栅格数据波段数,空间参考坐标系需要统一,否则你绝对报错,到时候别说我没告诉你哟

。
很多时候小伙伴们需要按乡镇批量更新地图范围,自动导出标准图件PDF,不用手动调整地图框、重复导出!
import arcpyaoi_fc = r"E:\测试数据\原始数据\乡界.shp" # 乡镇边界out_pdf_folder = r"E:\测试数据\成果数据" # 导出PDF目录name_field = "XZQMC" # 名称字段# 获取当前打开的ArcGIS工程aprx = arcpy.mp.ArcGISProject("CURRENT")# 获取第一个布局(你自己做好的制图模板)layout = aprx.listLayouts()[0]# 获取布局中的地图框元素map_frame = layout.listElements("MAPFRAME_ELEMENT")[0]# 遍历每个乡镇,自动定位并导出with arcpy.da.SearchCursor(aoi_fc, ["SHAPE@", name_field]) as cursor:for row in cursor:# 获取当前乡镇范围ext = row[0].extent# 地图框缩放到该范围map_frame.camera.setExtent(ext)# 拼接PDF路径out_pdf = os.path.join(out_pdf_folder, f"{row[1]}.pdf")# 导出高清PDFlayout.exportToPDF(out_pdf, resolution=300)print(f"已导出地图:{row[1]}")
1.运行前先备份原始数据,避免误操作覆盖。
2.先拿少量数据测试代码,没问题再跑全量。
3.栅格大数据运行时,关闭其他软件,避免内存不足。
4.报错先看路径是否有中文/空格,再检查坐标系是否匹配。
需要完整脚本源文件的小伙伴们,可直接复制代码修改路径,动手实操一遍就能熟练掌握,告别重复劳动,效率直接拉满!若操作过程有任何换问题欢迎私信我们哟,我们看见会一一答复大家的。
最后创作不易,如果这篇文章对小伙伴们~有帮助,欢迎点赞、在看、转发给身边的GISer小伙伴~ 有任何疑问,或者想了解更多的ArcGIS pro技巧,都可以在评论区留言,后续我将继续分享实战经验,让更多都小伙伴~在使用区软件方面收获满满,记得关注哟!另外后台私信我们,加交流群,获取更多软件技能知识。