
先交代一下背景这套流程是我在做一个流域地形分析项目时反复打磨出来的。ArcGIS空间分析模块里的水文分析工具绝大多数人只用它提取河网、划分子流域很少有人会想到把DEM反过来用一遍直接提取山谷线和山脊线。这篇文章就把整套方法和盘托出从核心思路到每一步操作细节再到我踩过的一些坑一次说清楚。适合正在做地形分析、从事GIS数据生产、或者刚接触空间分析但对算法原理还不太明白的朋友阅读按文章顺序操作一遍你也能在ArcGIS里稳定提取出山谷线和山脊线。1. 先把核心思路理清楚山谷线是“流水路”山脊线是“分水墙”1.1 山谷线和山脊线在地貌上到底“长什么样”在动手之前先建立直观认识。山谷线也叫沟谷线是降雨后地表水最容易汇集的连线。你在地形图上看等高线等高线向高处凸出的那串鞍部连线基本就是山谷线放到真实地貌里就是山沟、溪流所在的位置。山脊线则刚好相反它是分水岭雨水落在山脊线上会往两侧分开流地形上表现为等高线向低处凸出的连线也就是山梁的顶部走向。这两类线是地形分析里最基本的地形骨架线。做水文分析要划分子流域分水岭山脊线是天然边界做道路选线要尽量沿山脊或缓坡布线需要知道山脊线的精确位置做植被分布调查、地质灾害评估也经常要参考沟谷和山梁的走向。可问题在于人工勾绘山脊山谷线非常费劲尤其研究区一大等高线密密麻麻眼睛看花不说不同人勾出来的结果还不一样标准很难统一。如果只看一句水文上的定义那就是山谷线是汇水线山脊线是分水线。这句话是整个方法的底层依据。1.2 地形翻转用一次反向DEM把山脊变成“假河谷”ArcGIS的水文分析工具本身是为提取河网设计的。水流在DEM上从高往低走山谷线天然满足“水流汇聚”这个条件所以直接用Flow Direction计算流向、再用Flow Accumulation计算汇流累积量就能把山谷线找出来。问题出在山脊线上。山脊线是水流的源头、是分水的边界水流不会沿着山脊走反而会从山脊向两侧散开。你用同样的工具去分析会发现山脊线上的汇流累积值非常小根本不可能作为“河网”被提取出来。解决办法其实是一招思维反转把DEM的每个像元乘以-1山变谷、谷变山。原本的山脊线在反向DEM上变成了“山谷”水流会在这里汇聚于是一套完全相同的流向、流量分析流程跑下来提取出的“反向河网”就是山脊线。这个思路并不复杂但理解以后你会发现它的可扩展性很强。提取沟沿线、提取鞍部点、分析地形起伏特征本质上都是在跟“地形翻转”做文章。把底层逻辑想明白后面调参数时就不会慌。2. 开始前的准备工作不是随便拿个DEM就能跑2.1 DEM数据的要求与常见坑理论上来讲任何DEM都能跑这套流程但结果的可靠程度取决于DEM质量和分辨率。分辨率一般用10米到30米的DEM比较合适。分辨率太高比如1米或2米地形细节太碎提取出的线会非常细碎后期要花大量时间修整分辨率太低比如90米或250米山谷和山脊的轮廓被压缩很多次级沟谷根本显示不出来。数据源国内做研究常用地理空间数据云下载的ASTER GDEM、GDEMV3或者ALOS 12.5米数据做工程应用时我一般用项目自己生成的5米或2米DEM。投影坐标系这是很多人忽略的坑。水文分析里的流向计算基于平面距离如果数据是经纬度坐标系每个像元在不同纬度上的实际距离不一样流向判断会出问题。实际操作时先把DEM投影到合适的坐标系比如UTM或者CGCS2000高斯投影再做水文分析结果才可靠。NoData区域DEM边缘或者水域位置如果存在NoData需要提前处理。流向计算遇到NoData会把像元当成阻碍导致河网在边界处乱跑甚至直接断裂。另外提醒一句拿到DEM先检查属性表里的像元大小和范围。ArcGIS的栅格分析对一致性非常敏感后面所有工具是否能顺利跑通很大程度上取决于原始数据干不干净。2.2 Spatial Analyst扩展模块与工具集位置水文分析这组工具位于ArcToolbox里的Spatial Analyst Tools下的Hydrology工具集。使用前要确保ArcMap或ArcGIS Pro里已经启用Spatial Analyst扩展模块。在ArcMap中路径是“自定义”菜单里的“扩展模块”勾选Spatial Analyst。在ArcGIS Pro中从“设置”进入“许可”页面启用Spatial Analyst。没有这个许可很多栅格分析工具会直接灰掉或者报错。企业版许可一般自带但个人使用时要特别注意别等到跑到一半才发现工具不可用。顺便说明一下ArcGIS 10.x中这些工具的名称和ArcGIS Pro 3.x基本一致区别主要在界面位置。ArcMap里在ArcToolbox中操作Pro里在“分析”选项卡下的“工具”面板中查找。下面讲的流程在两个平台通用差别只是面板叫法不同。3. 正向水文分析提取山谷线从填洼到矢量化的完整流程3.1 填洼先把DEM里的“坑”处理明白水文分析的第一步是填洼。DEM里因为数据噪声或真实地形原因会存在一些低洼区域。如果不填水流流到洼地就停住了后续流向计算会断掉河网自然提不出来。填洼工具在Hydrology工具集下名称就叫Fill。ArcMap里直接输入DEM就能跑默认参数会把所有洼地都填平。这里有一个容易被忽略的Z limit参数如果留空表示所有洼地都会被填掉。但实际地形中确实存在真实洼地比如喀斯特地区、采石坑、水库这些地方一味填平会把真实地形破坏掉导致提取的河网出现“穿过山体”的假象。我的习惯做法是先用Fill做一次全填然后用栅格计算器求原始DEM和填洼后DEM的差值差值大于一定深度的区域就是重点关注对象。如果研究区不大可以先把这些差值区域目视检查一遍再决定要不要限制Z limit。比如某个区域差值达到50米以上那很可能是真实洼地或人工地物填掉它会影响后续分析。这一步还有个小细节如果DEM边缘有NoData建议先用“按掩膜提取”把研究区边界裁好或者使用“消除NoData”处理掉边缘无效值再进入填洼流程。否则填洼工具在NoData边缘可能会产生不可预期的结果。3.2 流向计算D8算法给每个像元指路填洼完成后用Flow Direction工具计算流向。ArcGIS默认使用D8单流向算法它用一个3x3的窗口计算中心像元到周围8个邻域像元的坡度选坡度最大的方向作为该像元的水流去向。参数上重点说一下“流向类型”默认是D8适合河网提取。至于MF-D8多流向方向在平原区效果更好但后面做流量累积时算法需要配套调整不建议在基础流程里使用。D-Infinity连续流向多用于径流扩散研究也不常用。另一个选项Force all edge cells to flow outward意思是强制边缘像元向外流。默认不勾选因为如果DEM边缘就是研究区边界强行让边缘水流向外会生成排水方向异常的栅格。但如果你处理的是分块数据边缘确实还有地形延续可以考虑勾选。流向栅格生成后我习惯顺手检查一下它的属性表。注意流向栅格不是简单记录方向数值而是用2的幂次方编码表示8个方向分别是1、2、4、8、16、32、64、128。在可视化时你可以用唯一值渲染来看效果如果出现大片方向值异常大概率是前面填洼或DEM处理环节出了问题。3.3 流量累积与河网阈值数字越大线越少Flow Accumulation工具的输入是流向栅格输出结果表示每个像元上游累积了多少个像元的汇水量。比如某个像元的结果是1000意味着它上游有1000个像元的水最终汇到这个位置。在没有雨量权重的情况下可以把这个值理解为“上游汇水面积”。提取河网时关键环节是设置一个阈值把流量累积超过阈值的像元定义为中心线。那么阈值怎么选经验上先用流量累积最大值的1%作为起点。例如流量累积栅格最大值是50000就先试500。然后叠加到影像或等高线上看效果。阈值设得越低提取的沟谷越密集阈值越高只保留主沟谷。没有一个绝对正确的值取决于你要表达的是“完整山沟系统”还是“主要河谷”。实际工作中我通常先用一个比较低的阈值跑一版叠加到底图上看。如果发现很多“沟”其实只是斜坡上的细碎冲沟就调高阈值再跑。流量累积结果往往呈长尾分布主河谷区域值很大支沟的值相对小。如果你发现不管怎么调阈值主线附近的支沟总是乱糟糟的那可能是原始DEM里含有大量噪声比如林区雷达数据生成的DEM有树冠噪声这种情况下需要先对DEM做平滑滤波处理。3.4 栅格河网转矢量线Stream Order与Stream to Feature得到阈值后的河网栅格后我用栅格计算器写Con(flowacc 阈值, 1)把河网像元赋为1背景设为NoData。这一步也可以直接使用SetNullflowacc 阈值, flowacc实现。然后有两个选择。一种是把河网栅格做Stream Order分级再进行矢量化。Stream Order有两种常用分级方法Strahler和Shreve。Strahler分级是主流它把最上游支流定为1级两条同级支流交汇后级别加1。这样你可以把不同级别的河谷线分别存储、分别显示线状符号按级别区分粗细图面效果非常专业。另一种是直接用Stream to Feature工具。这个工具在实际调用时会自动执行Stream Order但前提是你的河网栅格像元值干净。我的建议是先把河网栅格跑一遍Stream Order再用Stream to Feature输入分级结果这样输出线的属性表里会带有Strahler等级字段gridcode方便后续按等级筛选和符号化。勾选Simplify选项可以去掉栅格转矢量时产生的锯齿但简化过度会牺牲真实位置精度一般保留默认设置后面再用Smooth Line做一次平滑。矢量化出来的线就是山谷线。4. 反向地形提取山脊线关键就在“DEM乘以-1”4.1 反地形DEM生成注意数据类型别被截断反向DEM其实就是地形翻转。在ArcGIS的栅格计算器里直接写DEM * -1或者使用“数学分析”工具里的“减”0 - DEM。这里有一个容易被忽视的问题反向后DEM的取值范围从原来的正值变成负值这没关系流向计算只关心相对高差。但如果你后续还有其他分析要用到高程排序负值会影响逻辑判断。还有一个数据格式陷阱。如果DEM是整型栅格直接乘以-1的结果可能仍然是整型像元值被截断精度会损失。所以我在栅格计算器里通常先加一步转浮点用Float函数处理一下确保精度不丢。这个细节在DEM分辨率较高时影响不大但在地势平缓区域微小的高程差异可能决定一条山脊线的走向。做到这一步原本高处的山脊变成了洼地原本深谷变成了高地整个地形被翻转过来。接下来对反向DEM再做一次完整的填洼、流向、流量累积流程。4.2 反向水文分析填洼、流向、累积全流程细节操作顺序和正向分析完全一样Fill反向DEM→ Flow Direction → Flow Accumulation → 阈值 → 栅格转矢量。但有几个细节值得单独拆开说。首先反向填洼非常关键。这个流程的本质是找反向DEM中的“汇水线”如果填洼过度很多真正反映山脊形态的细节洼地被填掉提取出的山脊线会明显偏离真实山脊往往偏向山脊的任一侧。解决方法是填洼时限制Z limit或者比较填洼前后的差异选择性地保留部分负地形。其次反向河网的阈值通常比正向河网难调。因为山脊线地形比山谷线地形更破碎同样的阈值下支脊数量会多很多。实际工作中我倾向于“主脊优先”策略先把阈值调高提取主要山脊线再逐步降低阈值看次级分支而不是一上来就追求把所有细碎山脊一次提取完。流向计算完成后我建议把反向流量累积图叠加到山体阴影或者等高线上目视验证一次。真正的山脊线在反向流量累积图上应该是连续的亮色线位置基本与等高线转折、山体阴影的分界线吻合。如果发现提取的线走在山坡中间多半是填洼深度过大或者原始DEM存在伪洼地。4.3 山脊线的后处理平滑、删短小伪线反向河网栅格转换矢量的操作跟正向一样用Stream Order Stream to Feature处理得到的线就是山脊线。由于反向DEM在地形翻转后相邻像元间的微小起伏会被放大提取的矢量线通常比山谷线更曲折、毛刺更多。所以矢量化之后我一般会再执行一次Smooth Line平滑工具。平滑使用PAEK算法容差可以设为DEM像元尺寸的2到5倍。比如30米DEM平滑容差设为60到150米。容差太大会把山脊线的关键拐点削平容差太小又没有实际效果。另一个优化是在栅格阶段做。Flow Accumulation工具支持输入权重栅格如果你手里有坡度数据可以把坡度作为权重让陡坡区域更容易累积出高流量从而突出陡峻山脊。不过这个方法不一定适合所有地形如果只是想快速出图可以先不加权重。在矢量阶段我还会根据线长筛选。提取出的山脊线中有些很短很碎基本属于伪脊线是噪声引起的。我通常用属性表里的长度字段做排序把几百米以下的短线删掉具体阈值看研究区尺度。这一步能显著提高图面质量。5. 高频问题排查这些坑我基本都踩过实际操作中总会碰到这样那样的问题。下面我把高频问题整理成一个速查表方便你对照排查。问题现象可能原因解决办法河网在山脚或平地处乱绕密密麻麻平行线平缓区域流量累积对微小地形起伏极其敏感先做坡度分析把坡度小于阈值的区域做掩膜排除或调大阈值山脊线偏离真实山脊常贴着山坡一侧走反地形填洼过度限制Fill的Z limit检查填洼前后差值只填浅洼地提取的山谷线不连续中间断了很多段DEM含NoData、边缘有无效值、洼地未填干净先处理NoData检查流向栅格是否有异常用“填洼Sink检测”确认线太细碎图面全是毛刺分辨率太高、阈值太低、原始DEM噪声大适当提高阈值增加平滑容差删除短小线对象山谷线和山脊线在鞍部交叉、串线鞍部地形复杂正反两次提取都容易误判将两类线叠加到山体阴影上人工检查必要时手动打断编辑5.1 提取线断裂八成问题出在DEM或流向“线不连续”是我在交流群里看到最多的一个问题。排查时我有一个固定套路先检查原始DEM范围和NoData边界再看填洼前后的差值栅格。如果DEM边缘某些位置完全没有水流覆盖提取结果就会在这些区域断掉。还有一种情况是流向栅格中存在循环流向比如DEM里有局部平台区域D8算法会把部分像元的水流方向指向自己导致流量累积出现断点。遇到这种情况可以用栅格计算器把流向值为0或异常的像元单独挑出来放大检查平台区域。如果DEM本身没问题那问题大概率出在阈值上。阈值设置太高会把一些本来连续的细沟全部滤掉导致主干线断断续续。这时候不是去改DEM而是把阈值调低再配合线长筛选。5.2 阈值真的不是玄学是按需调试的很多人喜欢问“阈值到底填多少”我理解因为默认值往往效果不好。但这个问题真没有标准答案。经验参考是先用流量累积最大值的1%作为初值。如果研究区是典型的高山峡谷主沟与支沟级别差异大可以设置较小阈值比如0.2%到0.5%让支沟也显示出来如果是平缓丘陵阈值设置要大一些比如2%以上甚至更高。注意流量累积最大值不是固定不变的。填洼深度变了最大汇流量也会变所以换了DEM后一定要重新看统计值不能拿上一个项目的阈值直接套用。我的习惯是把阈值做成一个可调参数记录在项目文档里每次出图时写明用的什么阈值。这样后续调整时非常高效而不是每次凭感觉乱填。如果你在做一个多期对比分析固定阈值还能让不同期次的提取结果具备可比性。5.3 山谷线与山脊线交叉、串线的处理正向提取的山谷线和反向提取的山脊线在正常情况下应该是相互交错的山谷线“夹”在山脊线之间。但实际操作中常常会在鞍部、垭口这些地形复杂的位置出现交叉、串线。鞍部本身是山脊的最低点也是两侧山谷的源头附近地形变化剧烈。正反两次提取在鞍部都容易误判正向提取可能把鞍部当成沟谷的一部分反向提取又可能把鞍部误认为连续山脊。解决办法没有捷径就是把山谷线和山脊线叠加到山体阴影或等高线底图上人工检查鞍部区域必要时手动打断线、删除错误线段。如果你需要做的是严格的拓扑分析比如把山脊线作为分水边界来划分子流域那还有另一个更严谨的替代方案用ArcGIS水文分析里的Basin或Watershed工具直接生成分水岭多边形再把多边形转线得到分水线。这个结果比单纯反向河网提取的山脊线更符合水文意义上的分水边界。不过它的缺点是边界会相对平滑细节不如反向河网丰富二者可以根据需求搭配使用。6. 最后补充几条实际工作中的心得体会如果只用一句话总结这个流程我会说水文分析提取山谷山脊线本质是两次“逆向思维”的叠加第一次把山谷当水沟第二次把山脊变成“假河谷”。掌握这个逻辑以后参数怎么调都不慌。再有几条实操层面的体会DEM的预处理要占整个流程一半的功夫把NoData、投影、填洼处理好后面基本不会出大问题。输出成果一定要叠加山体阴影做目视检查这是最快、最直观的质量验证手段不要跳过。还有做项目报告时建议保留每一版阈值对应的结果图这样方便论证参数选择的合理性也方便返工调整。如果后续你需要在多个区域批量提取可以试试ArcGIS Model Builder把这套流程做成一个模型以后换DEM输入直接跑。整个流程跑顺之后我最大的感受是ArcGIS的水文分析工具其实是被低估的它不仅能做常规的河网提取稍微转换一下思路就能解决很多地形分析里原本要手动勾绘的麻烦事。