从接触ArcGIS到现在,我大部分时间都在跟地形图打交道。很多刚入行的朋友拿到高程点或者DEM,第一反应是打开ArcToolbox找等值线工具,点一下生成完事。结果出来的等高线要么锯齿感明显,要么穿出研究区边界老远,更别说后续拿去拼图出成果图了。这一篇我会把整个流程——等高线快速生成、边界提取、裁切、到地形图拼图出图——完整走一遍,把背后涉及的原理和关键参数一起讲透,希望能给正在做类似项目的同行省掉几个晚上的加班时间。
这篇文章适合两类人:一类是测绘、城乡规划、地质、水利背景,需要频繁出地形图的技术人员;另一类是刚接触ArcGIS、想把数据变成规范图件的学生或转行新人。文章里我会尽量把工具路径和参数逻辑说明白,即使你以前没怎么碰过空间分析,也能按步骤跟下来。
1. 为什么90%的人做等高线都在低效加班:先看清工作流的全貌
先说一个我观察了很久的现象。很多人在拿到原始数据之后,不做任何检查和处理,直接就把高程点丢进“3D Analyst”或者“Spatial Analyst”工具里生成表面。这样不是不行,但后续麻烦非常多:生成的等高线会越过图幅边界,或者是围绕孤立的高程异常值生成一堆不闭合的小圈,也就是我们常说的“炮弹线”。最后为了保证图面干净,你得手工删线,一条一条去修剪,工作量直接翻倍。
真正高效的流程,应该是在生成等高线之前,先把数据准备、边界控制、成果裁切这几件事一次性想清楚。整个流程拉通之后,大概是这样几大块:
- 数据检查与预处理:检查原始高程点或等高线数据有没有错误,包括高程异常、平面坐标是否统一、有无缺失区域。
- DEM构建与修正:把离散的高程点转为连续表面,填洼或者按需平滑,让后续生成的等高线符合地形逻辑。
- 等高线自动生成:这一步不是单纯点一下工具,而是要选对方法、设对参数,保证等高线走势合理、精度够用。
- 地形图边界构建:要得到测量规范要求中的图幅边界或者工作区边界,并据之裁切生成的等高线,让图面范围干净、规范。
- 拼图与制图整饰:在ArcGIS里完成图幅拼接、取舍、注记避让、配色、图廓整饰,输出满足交付要求的地形图。
你注意一下,这里面“边界”和“裁切”是关键。很多人的等高线之所以后期难处理,就是因为第二步和第五步之间缺少一个“边界控制”的概念。先有边界,再有裁切,最后才是出图。
从技术路线来说,ArcGIS Desktop和ArcGIS Pro都能完成这些工作,只是界面和部分工具位置有差异。如果条件允许,我个人推荐直接用ArcGIS Pro,因为Pro在多线程处理、大数据的平稳性上比Desktop的ArcMap好很多,尤其是做填洼和等值线提取时,特别明显。当然,ArcMap 10.x的流程也完全一致,工具名称基本不变,所以这套操作思路在两个平台上都通用。
2. 数据理清之后,等高线生成的几个关键参数不能拍脑袋
2.1 高程点转DEM:插值方法决定了等高线的“骨架”
等高线本质上是对连续表面的等值抽取。也就是说,你得先有一个连续的栅格表面,才能在上面切出等值线。这个连续表面,通常用高程点或者等高线数据通过插值得到。ArcGIS里最常用的两个工具是“反距离权重法(IDW)”和“克里金法(Kriging)”,都在ArcToolbox的“Spatial Analyst工具—插值分析”下面。
- IDW的原理是距离越近影响越大,计算速度快,适合地形变化不算太剧烈、点密度比较均匀的数据。
- 克里金插值会考虑空间自相关性,能给出一个相对平滑且有统计意义的表面,但参数设置相对复杂,如果数据本身质量一般,反而容易插出夸张的极值。
我自己的习惯是:如果只是出1:10000甚至更小比例尺的地形图,用IDW就足够了,power值默认2。如果做水库淹没分析这类和精度强相关的项目,才会考虑克里金。
需要注意一个细节:DEM是栅格数据,像元大小很关键。像元设置得太大,微地形会被抹平,等高线细节丢失;设置得太小,数据体积暴涨,处理速度下降,而且可能把插值带来的噪点放大。一个比较实用的经验值是:像元大小设置为原始高程点平均间距的1/2到1/3。比如你的数据点平均间距是5米,像元大小设在2米左右比较合适。
2.2 等值线工具:忙于输出之前,先把基线和计曲线分开
在ArcGIS里生成等高线,工具路径是“Spatial Analyst工具—表面分析—等值线”。这个工具的界面极其朴素,就三个必填参数:输入栅格、等值线间距、输出要素。我第一次用的时候也没多想,输入10米间距直接生成,结果后续做图例、做标注的时候难受得不行。因为地形图规范里,计曲线和首曲线是分开的,计曲线加粗、标注也只标在计曲线上。
所以正确的做法是:不要一次生成全部等高线,而是分开生成两次:
- 首曲线(基本等高距):比如5米间距,用于表达地形细部。
- 计曲线(加粗等高线):通常是基本等高距的5倍,比如25米,用于读图和标注。
这样做的好处非常多。你可以在符号化时直接给计曲线一个较宽的线宽,而首曲线保持细线,不需要额外写表达式去判断Z值是否是整倍数。而且做注记的时候,直接用计曲线那层去做,标注数量和压盖问题会大大减少。
等值线工具有个隐藏的选项叫“Z因子”,我见过很多人忽略它。Z因子用于转换高程值的单位,比如水平单位是米、高程单位也是米,那Z因子填1就行。如果你的数据是经纬度坐标、高程又是米,就必须设置正确的Z因子,否则生成的等高线会完全拧巴。这种情况在往届学生作业和刚入职的同事身上出现过不止一次。
2.3 DEM要不要填洼:看地形,别一刀切
等值线工具是直接在栅格表面提取等值线的,它不会管这个表面里有没有不合理的洼地。如果你的DEM做出来有很多“假坑”,等高线在这些区域会出现一圈一圈的闭合小圆,像蟾蜍皮一样难看。
“填洼”工具在“Spatial Analyst工具—水文分析”里,作用就是把这类低洼区域填平。但这里要特别提醒:填洼是给水文分析用的,不是给等高线出图用的。盲目把DEM填洼,会抹掉真实的负地形,比如采坑、凹地,这些在地形图上恰恰是需要保留表达的。
如果只是为了出图好看,我建议先做一次“焦点统计”或者“低通滤波”来平滑表面,而不是直接填洼。ArcGIS里也可以用“Spatial Analyst工具—邻域分析—焦点统计”,设置一个3×3的矩形邻域、统计类型为MEAN,生成平滑后的栅格再做等高线。注意平滑会带来高程值的一定偏移,在要求严格的生产项目里,这个操作要谨慎,最好在交付说明里记录清楚。
3. 边界抽取与等高线的“修剪战”:这一步才是图面干净的关键
3.1 从哪里得到边界:矢量转换是成本最低的方法
很多项目里,工作区边界在数据一开始就有,比如甲方给的勘测定界图、村界、林班界等等。但如果你手里只有DEM或者影像,没有现成的矢量边界,就得自己从栅格数据里抽。
常规做法是把DEM先做一个“提取分析—按属性提取”,把有效值范围提取成栅格,然后使用“转换工具—从栅格转出—栅格转面”。这样能得到一个覆盖整个有效区域的完整面状要素。但这个面往往边缘破碎,锯齿感很强,还得进一步做“平滑”和“简化”。
ArcGIS里简化面有“制图综合—简化面”工具,建议选择“PAEK”算法,容差设置为DEM像元大小的2~3倍,这样得到的边界既不会过度变形,又能去掉大部分狗牙状的凸起。
如果你面临的是流域边界提取,那就需要用“水文分析”那一整套工具:填洼、流向、流量、栅格计算器提取河网、分水岭。这是另一个大话题,这里不展开。但核心流程是:填洼后的DEM -> 流向 -> 流量,流量阈值设为合适值之后,再用“分水岭”工具提取汇水区。得到的流域边界,再转成矢量之后一样可以用下面讲的裁切流程。
3.2 用边界裁切等高线:按要素裁剪和按掩膜提取的区别
有了边界之后,就要用它来裁剪等高线。ArcGIS里的裁剪方式有两种,很多人分不清:
- “分析工具—提取分析—裁剪”:这个工具适用于矢量对矢量裁剪,直接按照边界面的形状,把等高线切出来。用起来简单,但有个问题:裁剪出来的等高线只是在边界处被硬生生切开,边缘处没有闭合,严格说还不是一幅“画完”的地形图。
- “ Spatial Analyst工具—提取分析—按掩膜提取”:这是栅格层面的裁剪。它会先按边界范围把DEM裁出来,再在裁好的DEM上生成等高线,这样生成的等高线天然就在边界范围内,不会出现穿出边界的现象。
如果你的边界是面状矢量,又希望保证等高线完全落在范围内,最理想的流程是:原始DEM——按掩膜提取——得到裁剪后的DEM——然后在这个DEM上生成等高线。这样做还有一个附带好处:因为参与计算的栅格变小了,等值线工具的运行速度明显更快。
3.3 边界处的“半截线”要怎么处理
即便用了按掩膜提取,边界处的等高线依然会出现“断头”现象。地形图规范里,等高线是可以闭合在边界上的,这个闭合有两种表现:一是碰到边界线就自然终止,二是环绕成闭合圈。在ArcGIS里,断在边界处的线在显示上够用,但如果甲方要求每条等高线都得闭合(这种情况多发于CAD出图场景),就需要做一步拓扑处理。
做拓扑检查时,对等高线图层启用“不能有悬挂点”规则,把边界处的悬挂点找出来,然后在编辑会话里,用“延伸”工具将断头线延伸到边界线上。这个过程比较繁琐,但这是保证CAD画幅完整性的常见做法。如果你最终交付的是ArcGIS的mxd/aprx工程文件,断头线完全可以接受,不必强行闭合。
4. 把裁切好的等高线变成拿得出手的地形图:制图整饰实操
4.1 合理地分层与符号化:地形图第一眼观感来自线型
等高线生成之后,默认的符号是黑色细实线,一眼看去就是一团乱麻。要让地形图读起来舒服,符号化是关键。
在图层属性的“符号系统”里,用“类别—唯一值”的方式,分别给首曲线、计曲线设置符号。具体来说:
- 首曲线:线宽0.2mm,颜色可以用棕褐色(CMYK约41/53/70/12),也可以纯黑色。
- 计曲线:线宽0.4mm,颜色同样用棕褐色,但要加粗。
- 如果地形图还要叠加高程点注记,高程点的小十字丝一般用灰黑色,点大小控制在2pt左右。
实际操作中,很多朋友会把等高线导出到CAD里再符号化,其实ArcGIS自带的制图效果已经足够了,而且再导出到CAD会面临字体、线型重新调整的问题,得不偿失。
4.2 等高线注记的避让:别让标注堆成一坨
注记是地形图里最考验耐心的一环。直接用“标注”功能时,ArcGIS会自动根据优先级避让,遇到复杂地形,还是会冒出密密麻麻的标签。
这里分享一个标注表达式技巧。右键点击计曲线图层,进入“标注”——“表达式”,在表达式框里输入:
Function FindLabel ([ContourElev]) Dim elevation elevation = [ContourElev] If elevation Mod 25 = 0 Then FindLabel = elevation End If End Function这段代码的作用是:只有高程值是25的整数倍时,才显示标注。在计曲线上,等高距为5米的前提下,每隔25米标注一次,图面一下子就清爽了。Mod函数会判断是否是整倍数,你根据实际等高距去改那个25就行。另外在“放置属性”里,把“放置压盖要素”勾掉,让标注自动避开线状要素,也能减少注记和等高线交叠。
你可能注意到了,ArcPy表达式在Desktop和Pro里略有差异,但Function FindLabel这个结构两边通用。我当年第一次在Pro里写这段代码,发现它执行不了,后来看了日志才知道是因为字段名大小写的问题,Pro的字段名默认带全大写,需要用[字段名]方式访问,把字段换成你属性表里实际的高程字段名就好。
4.3 图幅拼图:ArcGIS中“数据驱动页面”解决分幅难题
地形图拼图,在ArcGIS里的核心功能叫“数据驱动页面”,位于“视图—数据驱动页面”菜单里,而ArcGIS Pro中对应的是“布局—地图系列”。这个功能的逻辑是:你事先准备一组分幅面(每个面代表一幅图的范围),软件自动按照这些面逐页生成布局,每页聚焦一个图幅范围。
拿一个具体的项目场景说:某村庄地形图项目需要按1:2000分幅,我把村庄范围用“格网索引要素”工具按规定的图幅大小切分成了8个图幅面,然后图层按这个格网来出图。这样每页输出一幅图,图名、图号、比例尺、指北针都会随着格网属性自动更新。
这里最关键的一步是用“新建格网索引要素”工具(在“制图工具—制图综合”里)而不是手工画格网面。该工具可以设定格网的宽度、高度和原点坐标,自动生成的图幅面带“PageNumber”字段。数据驱动页面正是依据这个字段来控制出图顺序。如果你手工画8个矩形,没有PageNumber字段,后面做自动分幅会很麻烦。
分幅还有一个重要细节:相邻图幅之间的接边。ArcGIS数据驱动页面并不会自动做接边处的等高线拼接处理,你必须保证相邻图幅的等高线在接边处坐标一致。如果你是从同一个DEM裁切出来的,那么坐标一致性是天然满足的;如果是多个项目拼起来的数据,需要先做交叉检查,确保重叠区域的高程误差在允许范围内。数据库里我常听到的“接边检查”,就是这个过程。
4.4 输出打印:按比例尺出图,别用“适合页面”
当你要输出最终的纸质地形图或PDF,请注意ArcGIS布局里的输出比例尺设置。很多人做完数据驱动页面后,直接把布局缩放到合适大小,然后导出PDF,结果是图纸打印出来后比例尺完全不对。
正确做法是:在布局视图里,右键页面,打开“布局”属性,把“比例”设置为1:2000(或你需要的比例尺),然后调整数据框的大小和位置,让图幅完全充满。再往“文件—导出地图”走,设置分辨率至少300dpi,这样打印出来比例尺才严谨。
这个坑几乎每个测绘新人都会踩一次。我有一个师弟,头一回出图,导出的PDF在屏幕上看着挺好,打印出来发现图廓里标注的1:2000和实际量测的距离对不上。他来找我排查,我到布局里一看,“缩放地图以适合页面”勾上了,比例尺早就不是1:2000了。那一次我们花了几个小时重新出图。这个教训让我后来每次出图都先看布局属性里的“比例”,再谈导出。
5. 遇到的那些“折腾死人”的问题:来自实测现场的排查复盘
5.1 等高线锯齿感严重:先别急着平滑,检查原始数据的噪点
有次我帮朋友处理某矿区地形图,生成的等高线锯齿感非常严重,看起来像心电图而不是地形。当时我第一反应是等值线工具的平滑阈值不够,正准备调参数。后来仔细看了一下,问题出在原始数据上——那份高程点数据里混入了不少异常值,比如某个点高程显示为-9999(这是很多软件的无值编码),或者个别点高程比周边突然高了十几米。
这类情况一定要在生成DEM之前就处理掉。可以用“栅格计算器”快速把所有小于等于-9999的无效值设为NoData,公式类似:
SetNull("dem" <= -9999, "dem")“栅格计算器”在“Spatial Analyst工具—地图代数”里,是最常用的工具。如果异常值不是固定编码,而是随机的大偏差,你可以先用“查找异常值”工具(在“空间统计工具—工具”里)做一次统计筛查。这个工具专用于识别那些在空间分布上明显偏离邻域的值,跑一遍基本能圈出问题点。
排查完异常值之后再看锯齿感,往往已经好很多了。实在还不够的话,再用“制图综合—平滑线”工具,对等高线做一次PAEK平滑。注意PAEK平滑的容差设置为等高线间距的1/3到1/2即可,容差太大会导致等高线之间相交,这在几何上是不允许的。
5.2 等高线在平缓区域拉得跟面条一样:等值线间距的关键影响
平缓地区,比如冲积平原,地形高差很小,等高线会非常稀疏,甚至出现长距离的平行线,读图效果特别差。这种情况有两个应对思路:
- 在关键区域加密等高线:保持全局的等高距不变,单独对重点区域(比如地块中心)增加辅助等高线(半距等高线)。
- 调整等高距:某些情况下可以和甲方沟通,把基本等高距从5米改为2米。但注意,改等高距会直接改变图面表达和后续土方计算的精度,必须提前确认。
在ArcGIS里做半距等高线其实很简单:等值线工具的间距参数填2.5米就行,生成后用属性表的Z值字段筛选出非整数倍的那部分,单独放到“辅助等高线”图层里,符号用长虚线。
5.3 生成等高线时内存崩溃:大数据量场景的分块策略
处理的DEM如果范围特别大,等值线工具很容易报内存不足。尤其是32位ArcMap环境里,这是家常便饭。我的经验是:先用“分割栅格”工具,按图幅把大DEM切成若干块,每块分别生成等高线,最后用“合并”工具把生成的线要素合到一起。
分割栅格工具位于“数据管理工具—栅格—分割栅格”,可以按指定的行数、列数或者面要素去切。切的时候注意设一点重叠范围,比如相邻块重叠50米,避免接边处出现等高线断裂。合并之后,再用“修复几何”工具检查一下有没有几何错误,这个步骤耗费的时间很少,但能省去后续大量的制图麻烦。
5.4 尖锐角与自相交:把“高级编辑”工具用起来
针对网络热词里被反复提到的“尖锐角”“线压盖”问题,ArcGIS里有一个被低估的工具:高级编辑工具条上的“修整线”和“要素转面”。如果你的等高线在某些地方形成了极窄的V字形夹角,在出图比例尺下几乎看不出间距,这种尖锐角是不符合地形图规范表达的。
排查尖锐角可以用一个取巧的方法:做一个“缓冲区分析”,对等高线做一个极小宽度的缓冲(比如0.01米),然后在属性表里筛选出那些自相交或者和其他线距离过近的要素。缓冲区的面积异常可以从侧面反映尖锐角问题。接下来,在编辑会话里,用“整形要素”工具手工调整这些位置。这个工作没什么捷径,只能靠经验判断哪里需要修,修多了自然会形成肌肉记忆。
6. 定制你自己的“等高线工作流”:一些可供参考的制作路线
从更宏观的角度看,上面这套流程完全可以固化成一套个人或者团队的“等高线工作流”。我这里分享一个我自己在用的标准制作路线,你可以直接把它当作清单来用:
| 阶段 | 核心任务 | 关键工具 | 常见错误 |
|---|---|---|---|
| 数据准备 | 检查点/线数据、统一坐标系 | 投影、定义投影、查找异常值 | 跳过检查直接生成DEM |
| DEM构建 | 插值、裁剪、平滑 | IDW/克里金、按掩膜提取 | 像元大小过大或过小 |
| 等高线生成 | 首曲线+计曲线分离 | 等值线、标注表达式 | 一次性生成所有等高线 |
| 边界处理 | 提取/简化边界 | 栅格转面、简化面、裁剪 | 边界锯齿感强 |
| 制图整饰 | 分层符号化、注记避让 | 符号系统、数据驱动页面 | 标注堆叠、比例尺错乱 |
| 输出交付 | 打印PDF、导入CAD | 导出地图、转换工具 | 分辨率不足、比例尺出错 |
这张表打印出来贴工位上,每次做地形图项目之前过一遍,能挡掉很多返工。特别是“首曲线和计曲线分离”这一条,对后期出图效率的影响最明显。我见过太多人到了制图阶段,为了把计曲线单独标粗,写了一大段表达式去区分Z值倍数,白白浪费几个小时。
如果你经常处理批量任务,还可以把整个流程录制成ArcGIS Python脚本,用ArcPy把DEM裁剪、等值线生成、边界提取串起来。比如下面这个简单流程可以自动完成“按掩膜提取→等值线”两步:
import arcpy from arcpy.sa import * arcpy.env.workspace = r"C:\Project\Terrain" arcpy.env.overwriteOutput = True dem = "dem_mosaic.tif" boundary = "work_area.shp" out_dem_clip = "dem_clip.tif" out_contour = "contour_5m.shp" outExtractByMask = ExtractByMask(dem, boundary) outExtractByMask.save(out_dem_clip) arcpy.gp.Contour_sa(out_dem_clip, out_contour, 5)这段脚本很短,但它背后对应的流程我已经在上文拆解过了:先裁DEM、再生成等高线。脚本的好处是不受GUI的限制,可以批量处理几十个图幅。如果你对ArcPy不熟,也不用急着学,先把手工流程跑顺,再慢慢把脚本化提上日程。
这里有个CASS平滑等高线的思路顺便说一下。很多人之前用CASS画等高线,然后被“如何一键平滑”折磨。CASS里等高线平滑主要是“等高线—等高线滤波”和“等高线—等高线内插”这类命令。但在ArcGIS里,我们更倾向于在DEM层面做平滑,而不是在已经生成的等高线层面做滤波。因为在要素层面平滑相当于“事后补救”,线在几何上会被移动,精度受影响;而在栅格层面做滤波,保证的是原始地形的连续性和合理性。这也是我为什么在流程里坚持“先DEM后等高线”的原因。
7. 几个我踩过之后不再犯的细节:样式、坐标系与图面整洁
最后再分享一些散但很重要的细节,都是实际项目中经常被忽略的。
关于坐标系统。如果给的是经纬度坐标(GCS_WGS_1984),而你最终要输出的是高斯投影(例如CGCS2000 / 3-degree Gauss-Kruger zone),一定要在数据准备阶段完成“投影”工具转换,而不是直接在地图文档里用“动态投影”将就。动态投影只管显示,改不了数据本身,导出到CAD或者做面积量算时,坐标还是错的。很多人做面积统计时候以为什么都没动,结果一切换投影,面积数值就变了,其实就是底层数据坐标系没有真正转换。
关于等高线压盖。“arcgis中不要压盖线”这个搜索词背后的问题,其实多半出在矢量线图层相互之间的叠置顺序,以及符号线的透明度。合理设置图层绘制顺序能解决大部分压盖:高优先级的面在下,然后是等高线,最上面是注记,这样注记不会被线吃掉。如果两条等高线之间距离太近、符号本身叠在一起,就要回溯DEM精度问题了。
关于无效值和背景。等高线生成区域如果存在NoData,等值线是不会跨过NoData区域的,所以在DEM阶段,要把无效值处理好。有时NoData在栅格边缘形成一圈,等高线就跟着绕开一圈,看起来像沿边界画了个框,非常丑。用“按掩膜提取”之前,先确保掩膜范围没有破碎,或者先做一次“栅格计算器”把NoData赋值为有效高程值,再用边界裁切一次。
关于成果版本管理。地形图项目经常要反复修改。我的习惯是每一版成果都存一个带日期的文件夹,比如“Terrain_20240115”,里面分好“01_Data”“02_DEM”“03_Contour”“04_Layout”四个子目录,处理过程中产生的临时数据全部丢到“Temp”里。这个习惯最初只是为了防止自己把回归测试的数据弄混,后来发现同事协作时也方便很多,不会出现“谁覆盖了谁的成果”这种扯皮情况。ArcGIS里保存的mxd或者aprx工程文件,也建议跟着这个目录结构一起走。
关于平滑和简化的度量。简化面、平滑线这类制图综合工具,每一次处理都会改变几何形状。做之前记录一下要素的面积和周长,做完之后再对比一次——面积变化超过0.5%就要警惕过度简化,这时候应该调整容差。这种方法虽然土,但非常有效,至少能保证你的成果数据在精度上站得住脚。
搞地形图拼图这件事,说白了就是把一堆离散的高程点,变成一张能让人看得明白、量得准确、出得了图的地形图。ArcGIS提供的工具链本身的逻辑并不复杂,每一步背后的选择和参数,才是真正拉开效率和成品质量差距的地方。上面这套流程是我自己反复打磨沉淀的结果,也还在持续根据新版本的功能做调整。你在实际项目中遇到更奇怪的情况,欢迎带着现场截图和参数设置来交流。做GIS这行,很多经验就是在一次次的“这次怎么又出问题了”当中磨出来的。