ArcPy入门教程:从环境配置到几何修复与批处理实战
简介ArcPy 基础教程是针对 ArcGIS Desktop 环境下 Python 二次开发的入门资料适合 GIS 开发初学者、测绘地理信息从业者以及有自动化处理需求的用户。教程从 Python 基础讲起系统覆盖导入 ArcPy、调用地理处理工具、使用函数与类、环境设置、消息与错误处理、数据路径配置、许可与扩展模块访问等核心内容同时包含数据集处理、字段映射与定时运行脚本等进阶章节。配套 PDF 共 1 个文件体积 7.76MB便携易查。已有 468 人学习下载。读者按目录循序渐进既能快速掌握 ArcPy 基本语法与工作流又能理解批量操作和脚本化处理的常见流程为后续编写自动化的空间分析、制图和数据管理脚本打下扎实基础是一份实用性很强的入门手册。1. 为什么入门ArcPy要先放下“写代码”的念头一份从CAD转过来的土地利用数据500多个面要素自相交、重复顶点、空几何全占齐了。用ArcMap逐个人工检查光是“检查几何”就要等半小时改用Python一条arcpy.RepairGeometry_management命令几分钟清完。ArcPy作为ArcGIS的Python接口把数据访问、地理处理工具和地图文档操作封装成Python对象与函数。这篇内容不按教科书讲类库结构而是按“环境配置→数据读取→字段计算→工具调用→排错”这条线把入门阶段最常用、最容易卡住的命令串起来。适合刚接触ArcGIS脚本的初学者也适合长期用鼠标点工具、想给日常处理提速的工程师。2. 从import arcpy到第一个脚本ArcGIS的Python环境怎么配2.1 先分清两个PythonDesktop的2.7与Pro的3.x先解决一个最常见的误区ArcPy不是pip包它依赖ArcGIS安装目录下的原生库所以不能指望在python.org下载的Python里直接import arcpy。ArcGIS Desktop 10.x自带Python 2.7解释器在C:\Python27\ArcGIS10.xArcGIS Pro自带Python 3.x装在Pro安装目录下的conda环境arcgispro-py3里。装10.2、10.5还是10.8Python都在同一位置区别只是ArcGIS的版本号。环境Python 版本解释器常见位置包管理方式ArcGIS Desktop 10.2/10.82.7C:\Python27\ArcGIS10.x\python.exepip旧ArcGIS Pro 3.x3.9C:\Program Files\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\python.execonda版本差异带来的第一批坑是语法层面的。Python 2的print不加括号Python 3必须加括号中文字符串在Python 2里要用u前缀在Python 3里不用管。判断当前解释器的正确姿势是直接打印版本信息。import sys, arcpy print(sys.version) print(arcpy.GetInstallInfo()[Version])sys.version显示解释器细节arcpy.GetInstallInfo()返回一个带“Version”键的字典。如果发现跑出来的是2.7.x说明用的是Desktop的Python这时再核对脚本里的print语法、字符串编码绝大部分兼容问题都能提前暴露。提示在VSCode里配ArcPy环境最忌讳的是把解释器选成系统单独安装的Python。ImportError: No module named arcpy九成是解释器选错。2.2 用VSCode配置arcpy的Python解释器很多人习惯在ArcGIS自带的IDLE里写脚本但代码超过50行后就想换编辑器。VSCode配置arcpy的Python环境的步骤很简单先找到上面说的python.exe路径按CtrlShiftP打开“Python: Select Interpreter”把解释器指向ArcGIS的Python如果项目里把路径写死也可以在.vscode/settings.json里指定。{ python.defaultInterpreterPath: E:\\Python27\\ArcGIS10.8\\python.exe, python.terminal.activateEnvironment: false }第二行activateEnvironment设为false是为了避免在集成终端里自动激活其他conda环境导致解释器被切换。配置完成后新建脚本先跑一行import arcpy能正常输出就说明解释器认对了。常见的坑在于ArcGIS Pro的Python在conda环境里VSCode常常会检测到系统自带Python并自动选中这时需要手动在命令面板里换成arcgispro-py3。2.3 第一个脚本列出工作空间里的所有要素类环境通了就写第一个真正的脚本。下面这段代码把工作空间指向一个文件地理数据库打印出里面每个要素类的名称、类型和坐标系。import arcpy arcpy.env.workspace rD:\gis_data\urban.gdb arcpy.env.overwriteOutput True for fc in arcpy.ListFeatureClasses(): desc arcpy.Describe(fc) print(fc, desc.shapeType, desc.spatialReference.name)第二行的rD:\gis_data\urban.gdb用了原始字符串反斜杠不再被当成转义符。arcpy.env.workspace设置了默认工作空间之后所有工具的路径参数都可以只写要素类名称。overwriteOutput设为True允许同名输出直接覆盖调试阶段省去反复删数据的麻烦。ListFeatureClasses()默认列出所有要素类也可以用通配和类型过滤arcpy.ListFeatureClasses(*_tmp, Polygon)只取面要素。打印出的shapeType是Polygon、Polyline、Point之一spatialReference.name标志坐标系——处理数据前先看这两项能避开大量坐标系不一致的坑。3. 读数据、改字段、写结果ArcPy Cursor与字段计算的最小套路3.1 Describe动手前先看清数据结构列表要素类只是第一步真正动手改数据前得先搞清数据是什么。arcpy.Describe返回一个描述对象包含数据集的元信息比如要素类型、字段列表、空间参考、是否有Z值。相比在ArcMap属性表里逐个点脚本里用统一接口拿这些信息更可靠。import arcpy fc rD:\gis_data\urban.gdb\buildings desc arcpy.Describe(fc) print(desc.dataType) print(desc.shapeType) print(desc.hasZ) print(desc.spatialReference.name) print([f.name for f in desc.fields])dataType判断是FeatureClass、Table还是DatasethasZ决定后面做3D几何时是否需要处理Z坐标fields列表里的每个元素还有Type、Length等属性适合做字段存在性检查。先判断字段是否存在再用字段计算器比直接算到一半报“字段不存在”再回头查要快得多。3.2 Cursor读、改、插的三条标准路径Describe只读元数据真正一条条处理数据时要用Cursor。这三个类名容易混SearchCursor只读UpdateCursor改已有记录InsertCursor新增记录。注意这里说的是arcpy.da下的新版本老版本的arcpy.SearchCursor不支持with上下文也不会返回迭代器生产代码统一用arcpy.da.Cursor。游标类功能返回值适合场景arcpy.da.SearchCursor只读遍历解包后的行元组统计、导出、验证arcpy.da.UpdateCursor读取并更新行元组修改后调用updateRow批量改属性、几何修复前的筛查arcpy.da.InsertCursor新增行无需读取批量导入点、生成采样点import arcpy fc rD:\gis_data\urban.gdb\buildings area_field AREA_M2 ha_field AREA_HA with arcpy.da.SearchCursor(fc, [SHAPE, area_field]) as cur: total 0 for geom, area in cur: if geom: total area print(total area:, total) with arcpy.da.UpdateCursor(fc, [area_field, ha_field]) as cursor: for row in cursor: if row[0] is not None: row[1] round(row[0] / 10000.0, 4) cursor.updateRow(row) point arcpy.Point(554000, 3412000) with arcpy.da.InsertCursor(fc, [SHAPE]) as ins: ins.insertRow([point])第一段SearchCursor里字段名列表是[SHAPE, AREA_M2]遍历出来的每行也是两个值。SHAPE是ArcGIS给几何对象留的特殊字段拿到的是Geometry对象可以直接访问area、length等属性不用再去解析坐标字符串。第二段UpdateCursor修改字段时索引顺序必须和字段列表一致改完必须调用updateRow否则数据不会落盘。第三段的InsertCursor接受一个列表里面放[几何对象]或[属性..., 几何]顺序同样要和字段列表对应。游标对象用完要关闭with写法的好处是循环结束或异常时自动释放文件句柄在10.x版本上尤其值得养成这个习惯。3.3 CalculateField_management三种字段表达式写法批量改字段除了UpdateCursor还可以直接用字段计算器工具。它语法简单但表达式类型容易写错。工具签名的关键参数是expression_typeArcGIS Pro环境用PYTHON3Desktop 10.x用PYTHON默认值是VB。import arcpy fc rD:\gis_data\urban.gdb\buildings # 直接表达式字段名用 ! 包裹 arcpy.CalculateField_management( fc, AREA_HA, !AREA_M2! / 10000.0, PYTHON3 ) # 多行逻辑code_block 提供函数定义 code def zone_class(area): if area is None: return UNKNOWN if area 1000: return SMALL return LARGE arcpy.CalculateField_management( fc, ZONE, zone_class(!AREA_M2!), PYTHON3, code )直接表达式里字段名用叹号包裹这和VB表达式用方括号的写法完全不同用错后计算值会全为Null。code_block参数提供一个代码文本块里面定义函数表达式里调用它函数名和表达式保持一致。需要提醒的是字段计算器适合一次性批量计算如果更新逻辑还要配合其他条件判断UpdateCursor里的循环控制更直观也更容易调试。4. 修复几何、裁剪影像ArcPy工具调用的实战与批处理4.1 arcpy修复几何一条命令处理空几何和自相交矢量数据在转换、合并、手工编辑后经常出现几何问题空几何null shape、自相交多边形、重复顶点和不合法的内部环。这些数据直接拿去建拓扑或做空间分析工具大概率报错。arcpy.RepairGeometry_management可以重建几何对象并清理这些无效结构字段值不会变。import arcpy arcpy.env.workspace rD:\gis_data\cad_source.gdb arcpy.env.overwriteOutput True for fc in arcpy.ListFeatureClasses(): count int(arcpy.GetCount_management(fc).getOutput(0)) if count 0: continue print(repairing, fc) try: arcpy.RepairGeometry_management(fc, DELETE_NULL) except arcpy.ExecuteError: print(arcpy.GetMessages(2))GetCount_management返回的对象要先getOutput(0)再转int这是地理处理结果的标准取数姿势直接print会看到一大段对象描述。RepairGeometry_management第一个参数是要修复的要素类第二个参数DELETE_NULL表示删除几何为空的整行记录如果只想保留空几何用于排查就传NO_DELETE_NULL。修复前建议先用FeatureClassToFeatureClass_conversion做一份备份。参数取值说明in_features要素类路径支持文件地理数据库和shapefiledelete_nullDELETE_NULL / NO_DELETE_NULL是否删除空几何记录默认不删除如果数据是SDE版本化数据修复前要确认用户具备版本编辑权限版本化环境下直接调用修复可能触发锁冲突修复完成后对应的几何缓存也要重算。这是arcpy修复几何里最容易踩的两个边界。另外修复并不会重新排列顶点顺序对“尖锐角”这类拓扑形态问题它不会改变拐角形状必须配合检查逻辑单独处理。4.2 用Clip_management裁剪影像参数顺序别记错影像处理里arcgis裁剪影像最直接的工具是Clip_management。它同时支持栅格和要素栅格裁剪时最关键的参数是输入范围坐标和NoData值。import arcpy in_raster rD:\data\landsat\LC08_2019.tif out_raster rD:\data\clip\LC08_study.tif arcpy.Clip_management( in_raster, 453000 4413000 489000 4455000, out_raster, 0, NONE, MAINTAIN_EXTENT )第二个参数是矩形范围字符串按“xmin ymin xmax ymax”四个空格分隔的数字传顺序错了裁剪区会出现奇怪的偏移。第四个参数nodata_value设成0表示裁剪区外像素写入0值如果不传默认保留原NoData拉伸显示时常出现黑边。第五个参数clipping_geometry取NONE表示矩形裁剪要按面要素裁剪时换成POLYGON并把面要素路径作为第七个参数。第六个参数MAINTAIN_EXTENT用来保留外包围盒如果不保留结果范围会严格贴合裁剪框。在实际作业里先用Clip_management做矩形裁剪再配合Con或ExtractByMask做掩膜是最稳的组合。4.3 批处理原则先跑一个样本再放开循环批量处理是ArcPy区别于鼠标操作的核心优势但也是有代价的。每个地理处理工具的启动都有固定开销在循环里为每个要素调用一次工具速度会非常难看。常见的做法是先对少量样本验证参数再用ListFeatureClasses、ListDatasets或ListRasters遍历整个工作空间。import arcpy arcpy.env.workspace rD:\gis_data\urban.gdb sample [buildings, roads] for name in sample: print(sample:, name) desc arcpy.Describe(name) print(desc.shapeType, desc.spatialReference.name) for fc in arcpy.ListFeatureClasses(): print(batch:, fc) arcpy.RepairGeometry_management(fc, DELETE_NULL)前半段只处理两个样本用来确认数据类型和范围避免把错误参数带进全量循环。放开全量循环时把print当作进度日志直接输出到控制台或重定向到文本文件。另一个常见误用是在循环内部每次重设arcpy.env.workspace全局环境变量应该在整个脚本入口设置一次循环内只需操作要素类的相对名称。5. 排错三件事与一个ArcPy进阶习惯5.1 路径、版本、许可ArcPy报错的三个高频来源入门阶段大部分报错逃不出三个来源。第一是路径中文目录在Python 2环境下要把字符串写成u...并配合os.path模块统一处理Python 3本身对Unicode支持更好但Windows下的中文路径仍然建议用原始字符串。第二是版本ImportError: No module named arcpy95%是解释器没指向ArcGIS的Python在VSCode里查一下右下角解释器路径即可。第三是许可地理处理工具报许可相关错误或同时开启多个进程导致许可冲突需要检查Desktop/Pro许可类型和当前运行的进程。import arcpy try: arcpy.RepairGeometry_management(rD:\gis_data\urban.gdb\buildings) except arcpy.ExecuteError: for i in range(arcpy.GetMessageCount()): msg arcpy.GetMessage(i) if ERROR in msg: print(msg) except RuntimeError as err: print(runtime:, err)arcpy.ExecuteError是地理处理工具自身报错的总入口RuntimeError捕获Python层面的异常。GetMessage遍历所有历史消息把这段模板贴在脚本入口批量中断时能定位是哪一步、哪个要素类失败。报错关键词优先排查No module named arcpy解释器没指向ArcGIS PythonERROR 000732工作空间或数据路径不对Product license has been expired许可服务未启动或类型不匹配5.2 把“尖锐角检查”写成自己的ArcPy函数很多工程师在找arcgis检查尖锐角插件但更快的做法是用ArcPy几何对象自己写函数。多边形由环组成环上每三个相邻顶点构成两条向量向量夹角小于阈值就是尖锐角。import arcpy import math def sharp_vertices(part, min_angle10): pts [arcpy.Point(p.X, p.Y) for p in part if p] n len(pts) if n 3: return [] found [] for i in range(n): p0, p1, p2 pts[i - 1], pts[i], pts[(i 1) % n] v1 (p0.X - p1.X, p0.Y - p1.Y) v2 (p2.X - p1.X, p2.Y - p1.Y) norm math.hypot(v1[0], v1[1]) * math.hypot(v2[0], v2[1]) cos_v (v1[0] * v2[0] v1[1] * v2[1]) / norm angle math.degrees(math.acos(max(-1, min(1, cos_v)))) if angle min_angle: found.append((p1.X, p1.Y, round(angle, 2))) return found fc rD:\gis_data\urban.gdb\buildings with arcpy.da.SearchCursor(fc, [SHAPE, OBJECTID]) as cur: for geom, oid in cur: if geom is None: continue for part in geom.getPart(): for x, y, a in sharp_vertices(part, 8): print(oid, x, y, a)getPart()返回每个环的Point数组环在数据上是闭合的循环里取模回到首点max(-1, min(1, cos_v))用来钳制浮点误差避免acos参数越界报错。阈值建议设在8到15度之间具体看制图规范。把可疑顶点导出成点要素类再用RepairGeometry_management批量处理就能把“先检查后修复”串成一条自动化流程同样这套逻辑也可以包装成ArcGIS Pro的脚本工具拖进模型里和裁剪、融合一起跑。本文还有配套的精品资源点击获取
上一篇/下一篇内容由系统自动关联
返回资讯列表 →