
1. 项目概述为什么要用DEM做洪水淹没分析干GIS这行久了最常被问到的问题之一就是“这块地如果发洪水到底哪些地方会被淹淹到什么程度水有多深”过去很多人靠经验去圈范围或者干脆用等高线手工勾效率低不说精度完全看个人感觉。2018年之后随着高分辨率DEM数据越来越容易获取基于DEM的洪水淹没分析几乎成了水利、规划、应急、自然资源相关领域项目的标配。这篇文章要聊的分析方法和实操流程解决的就是上面那个问题。核心输入只有一个——DEM栅格文件Digital Elevation Model数字高程模型在此基础上通过ArcGIS的水文分析模块和栅格计算器模拟某一给定水位下的淹没范围再结合淹没区与DEM的高差关系把淹没区的水量一起算出来。整个过程不依赖任何昂贵插件纯ArcGIS标准工具箱就能完成。这套方法适合三类人去学一是做洪水风险图、灾害评估的工程师需要快速圈定不同频率洪水比如20年一遇、50年一遇的淹没边界二是规划院和咨询公司的分析师做海绵城市、防洪排涝专项规划时需要用淹没范围和水量评估现状三是高校和研究机构的学生课程设计、论文基础数据生产这套流程完全可以支撑起一个研究章节。不夸张地说弄懂这套流程你等于同时掌握了ArcGIS的填挖分析、流向计算、栅格代数运算、栅格转矢量、属性表统计这五类高频操作后面做任何水文相关分析比如汇水区划分、河流提取都能复用其中80%的思路。2. 方法论无源淹没与有源淹没的核心差异2.1 基本原理与算法思路先理清一个基本概念。基于DEM的洪水淹没分析主流做法分两大类无源淹没分析和有源淹没分析。无源淹没就是不考虑洪水从哪里来、如何漫延只假设在某一水位下所有高程低于这个水位的像元都被淹没。这是个纯数学判断——拿水位值去减DEM每一个像元的高程值得到负值或零值的区域就是淹没区。这种方法的计算速度极快适合大范围快速评估比如整条流域范围内不同水位条件下的最大淹没范围。有源淹没要复杂一些。它会考虑洪水从某个点入水口开始在重力作用下沿着地形坡面漫流只有那些与入水口“连通”的低洼区域才会被淹。比如一个孤立的山间洼地虽然高程低于水位但洪水根本流不过去那它就不该被算作淹没区。有源淹没的实现大多依赖种子蔓延算法ArcGIS中也有人写过Python库来模拟但流程相对复杂。我做过的项目里如果甲方要的是“理论最大淹没范围”无源淹没就够了如果涉及蓄滞洪区启用顺序、防洪调度方案这类需要考虑水流路径的场景就必须上输沙淹没或者至少用无源淹没结果再叠加人工校正。2.2 为什么推荐无源淹没作为第一版方案这篇文章展开讲的以无源淹没为主线。理由很朴实第一数据需求少只靠DEM就能跑通全流程第二结果稳健不依赖主观设定的入水点结果可复核性强第三计算效率高一个百万像元的DEM从填挖到算完水量常规配置的电脑几分钟内完成。当然无源淹没也有明显的局限性——它把淹没区看成“一碗水端平”的水平面忽略了真正洪水中水面并非绝对水平、上游水位高于下游、水流有流速和动能这些实际情况。但在洪水风险初筛、脆弱性评估、水资源配置测算这类场景中这种简化完全够用且业内认可。真正的精细化淹没模拟那是HEC-RAS、MIKE FLOOD这类二维水动力模型干的活工具不同解决的问题层级不同。实际操作中我通常这样处理先用无源淹没做全局扫描圈出敏感区域再针对重点区域用有源淹没或水动力模型细化。这个思路既保证了大范围评估的效率又不至于让结果在重点区域失真甲方也容易接受。2.3 淹没水量计算的数学原理再来看淹没区水量怎么算。公式并不复杂水量 淹没面积 × 平均水深但落实到栅格层面其实就是把淹没区内每一个像元的“水深”累加起来。每个像元的水深 目标水位 - 该像元的高程值。用栅格计算器做一次减法得到水深栅格再对水深栅格乘上单个像元面积分辨率 × 分辨率然后Statistics工具汇总求和就得到总水量。举个具体数字假设DEM分辨率为10m单一像元面积为100㎡某个像元高程为95.3m目标水位是100m则水深4.7m该像元水量为470m³。整片淹没区有多少个像元逐个累加即可。这里有个关键细节后面实操部分还会再展开DEM的类型决定了这个面积是否要修正。如果DEM是地理坐标系GCS单位是度那么一个像元在地面上的实际面积在高纬度地区和赤道地区差异巨大直接用“分辨率乘分辨率”算面积结果会有很大偏差。正确的做法是先做投影转换把DEM转到等面积投影比如Albers投影或UTM投影下再做淹没分析和水量计算。3. 数据准备与预处理这一步坑最多3.1 DEM数据获取与质量检查网上常见的DEM数据源主流的级有水经注万能地图下载器个人版免费可下载全球30m和90m高程、地理空间数据云的GDEMV330m分辨率覆盖全国、USGS EarthExplorer全球免费可下载SRTM和ASTER系列、NASA EARTHDATA可下载NASADEM等高精度数据。有条件的单位可以买商业高精度数据比如ALOS 12.5m、甚至机载LiDAR点云生成的1m级DEM但基本原理和流程完全一致。拿到数据第一件事不是直接开算而是检查质量。我总结了一个三查清单查范围图层属性里看数据范围是否覆盖研究区边缘是否缺块。查空值用“栅格计算器里的IsNull函数”或直接看属性表里Nodata像元数量空洞数量极多的话需要先做填充处理。查坐标系右键图层属性——源——查看栅格的空间参考。这一步很多人忽略后面算面积大概率得出离谱结果。这里要特别强调一下河流、水库、湖泊等水体在DEM上经常表现异常有时是“平底”大片高程一致的区域有时是“凸起”桥梁、堤坝导致的高程异常。这些情况会影响流向计算和淹没连通性分析。常用的修正手段是“DEM重 conditioning”比如用ArcGIS配套的ArcHydro工具里的DEM Reconditioning功能可以把河流矢量线“烧”进DEM里强制水流沿河网方向流动让后续的水文分析更接近真实。提示如果下载的DEM边缘有黑色区域那Nodata值一般是-32768或某个异常负数在填挖和计算前必须先用“按掩膜提取”或“条件函数”剔除否则整片区域的计算结果都会错掉。3.2 投影转换与重采样这一步相对基础但极其重要。选投影的原则很简单研究区如果是省级或跨省范围优先选Albers等积圆锥投影如果是市级或小流域选UTM对应分带。这两个都是等面积投影能最大限度保证面积和水量计算准确。实操路径ArcToolbox — 数据管理工具 — 投影和变换 — 栅格 — 投影栅格。这里需要输出坐标系里选择或者手动输入对应投影坐标系。重采样方法的选择逻辑是这样的对DEM这种连续表面数据推荐用双线性Bilinear或三次卷积Cubic Convolution它们会做插值保持地形过渡平滑千万别用最近邻Nearest那会把地形锯齿化后续提取的坡度坡向、流向都会出现明显问题。如果是分类数据土地利用、土壤类型等才必须用最近邻保持类别完整。3.3 填洼处理为什么一定要做DEM数据的天然缺陷在于即使在平坦区域由于数据本身的采样误差会存在大量虚假的“洼地”——明明现实中是平整的地面或完整的斜坡DEM里却出现了一个个低值像元。如果不处理水流方向计算时就会在这些洼地里打转根本流不到河网后续的流向分析、汇流累积全是错的。ArcGIS的填洼工具填塞位置在ArcToolbox — 空间分析工具 — 水文分析 — 填塞。操作界面非常简单输入DEM输出填洼后的DEM就完事了。但这里有个关键的参数——Z限制可选参数也就是设置“只填不超过该数值的洼地”。为什么这个参数有用如果你正在分析的区域里有些真真实实的自然洼地比如人工水库、池塘、喀斯特漏斗、采石坑它们的高程与周围有较大落差。如果不设Z限制填洼工具会把它们也一并填平流向计算时水就会直接沿着填平后的表面流向下游完全忽略掉这些“蓄水设施”结果偏离现实。我见过不少项目因为这一步没注意把水库直接“填没了”模拟出来的淹没范围比实际情况少了巨大的蓄洪空间。注意Z限制的值取决于你对研究区地形的理解。一般刚入门的做法是不填任何数直接跑如果要精细建议先用“坡向”或“等高线”工具看一下研究区哪里有真实的洼地边界再用Z限制只处理“虚假的浅洼地”。4. 核心技术实现从DEM到淹没区到洪水量4.1 第一步流向计算在做任何水文分析之前先得有流向栅格Flow Direction。这个栅格记录的是每个像元的水“流向哪个相邻像元”。操作ArcToolbox — 空间分析工具 — 水文分析 — 流向。输入填洼后的DEM输出流向栅格。ArcGIS的流向算法叫D8单流向算法简单说就是比较中心像元与周围8个相邻像元的高差选落差最大的方向作为流向。这个算法经典但也有局限遇到平缓地区就会产生平行水流所以前一步的填洼此时就能极大减少平坦区域出现的情况。流向栅格是受水文分析系列工具的标准输入后面无论是流域提取、河网分级还是想试有源淹没都绕不开它。建议为填洼后的DEM和流向栅格分别命名清晰比如Fill_DEM、FlowDir_Fill后续重跑参数时不用重新算一遍。4.2 第二步设定目标水位核心问题来了——目标水位怎么定。这取决于你的业务需求我大致分成几类。若做“固定水位方案”比如水利工程论证中常规定“当水位达到XXm时评估淹没”直接给一个常数以最常用。若做“频率洪水方案”如果有该断面的水位-流量关系曲线可以从设计洪峰流量值推求对应的水位值。若做“多年一遇”洪水的横断面分析往往要根据附近水文站的洪水位观测资料外推这个数据通常由水文部门提供。在项目里我们很多时候直接拿地方政府发布的洪水风险图成果、防洪规划报告里的设计洪水位作为输入。这里务必提一句水位值一定要基于统一的高程基准否则极其容易出问题。国内有的老数据用的是黄海高程有的是1985国家高程基准两者之间可能有几十厘米甚至更大的差异。做分析之前跟数据提供方确认好基准。4.3 第三步提取淹没区两种主流方法核心操作来了。这里我同时写下两种方法根据你的数据情况和精度需求选。方法一栅格计算器直接判定打开ArcToolbox — 空间分析工具 — 地图代数 — 栅格计算器输入表达式淹没区_判定 (填洼DEM 目标水位)这个表达式生成的是一个布尔栅格像元值为1的地方代表满足条件即被淹没像元值为0的地方代表不满足。此方法直白暴力是最快速的无源淹没判定方式。方法二重分类法用重分类工具ArcToolbox — 空间分析工具 — 重分类 — 重分类。对填洼DEM设置新旧值映射小于等于水位的赋值为1大于水位的赋值为0。两种结果完全等价只是有人习惯用重分类的界面觉得参数直观些。两个方法我都常用说实话栅格计算器更推荐因为表达式可复用性高改个水位值就能重跑一遍非常适合做多情景模拟比如分别计算100年一遇、50年一遇、20年一遇水位对应的淹没范围写个循环批量处理也很方便。拿真实项目举个例子某市防洪评价项目目标水位是185m填洼DEM某像元高程是182.7m那表达式判断为True淹没旁边一个山包像元高程是195m判定为False未淹。提取出布尔栅格后淹没区范围一目了然。但如果只想保留实际“被淹”的区域记得用“按属性提取”或“提取工具—按掩膜提取”把值为1的像元单独提出来方便后面的统计分析。4.4 第四步将淹没区转为矢量栅格适合计算但出图、叠加分析、出表格还是矢量方便。所以这一步要把淹没区从布尔栅格转成面状矢量。操作路径ArcToolbox — 转换工具 — 从栅格转出 — 栅格转面。输入淹没区判定栅格值为1的部分字段选择“Value”输出一个面要素类。到这一步有两个常见坑必须提醒栅格转面会把所有相连的像元合并成同一个面。如果研究区地形破碎一片淹没区可能被分割成成千上万个分散的小面这在属性表里是千行级的。要做“合并”处理吗不用太急先把几何数据转出来后续做统计时可以用“融合”工具按照属性字段进行融合。转面后要检查“孤岛”小面。栅格转面之后可能因为DEM的边界效应或Nodata值生成一些面积小到几乎可以忽略的碎面比如几个像元大小的“针尖”。统计时建议用“按属性选择”把面积小于某个阈值比如小于DEM分辨率介入的2×2像元面积的小面剔除否则最终“淹没面积”会偏大甲方如果做精确对比这误差有时会很难看。接下来记得算面积。Target面要素的坐标系如果是地理坐标系表格中的面积字段不是真正的平方米。正确做法是给面要素再做一个投影投影到UTM或Albers投影坐标系或用“计算几何”计算Area字段然后按照面积单位换算成公顷1公顷 10, 000㎡。4.5 第五步计算淹没区水深与洪水量现在进入计算洪水量环节。操作逻辑非常直接步骤一计算水深栅格栅格计算器里水深 目标水位 - 填洼DEM但注意并不是所有像元都有水深至少要在淹没区判定为真的地方才有意义。所以更严谨的表达式是水深_只在淹没区 Con(填洼DEM 目标水位, 目标水位 - 填洼DEM, NoData)这里用了Con条件函数意思是“当填洼DEM小于等于目标水位时水深为两者之差否则设为NoData”。NoData的像元在后续统计中会被自动忽略这比“把水位差为负值的区域直接赋0”要干净得多后面统计时少踩坑。步骤二逐个像元计算水量水量栅格 水深栅格 × 单个像元面积。栅格计算器单像元水量 水深_只在淹没区 * (像元宽度 * 像元高度)像元宽度和高度可以从DEM属性表——源中查到单位以投影坐标系为准UTM投影下单位是米。如果一个像元是10m×10m那面积为100㎡。步骤三汇总总水量ArcToolbox — 空间分析工具 — 综合分析 — 分区统计不这里要的不是分区统计而是全局汇总。更合适的工具是ArcToolbox — 空间分析工具 — 综合分析 — 以表格显示分区统计先不用这么复杂。最简单粗暴的方法是打开水深栅格或水量栅格的属性表在属性表里查看统计数据右键列标题——统计。如果用的是Classic界面更高效的办法是直接用“栅格计算器ZonalStatistics”组合但最简单的是使用“Spatial Analyst工具—综合分析—区域分析—以表格显示分区统计”先把淹没区布尔栅格值为1的区域设为分区数据。不过我用得最顺手的还是直接打开水深栅格属性表点“统计”看Sum求和——Sum就是总水量。等等这个逻辑严谨吗再核对一遍。水深_只在淹没区的栅格里每个像元的值就是“水深单位米”。属性表的Sum会把所有像元的水深从米累加成“米”。这时还没乘单个像元面积。所以把最终的Sum乘以DEM分辨率宽×高就是总水量单位m³。严谨流程应该这样写得到水深栅格depth_m栅格计算器生成volume depth_m * (cell_width * cell_height)打开volume栅格属性表查看Sum字段得到总水量单位m³。如果你手里是地理坐标系DEM没做投影单位是度这个乘出来的“面积”就严重失真了——这也是为什么前面反复强调必须先把DEM投影成等面积投影。4.6 一张流程图彻底理清逻辑你不需要任何高级插件核心步骤依次为DEM → 填洼 → 流向可能用于后续有源分析 → 栅格计算器判定淹没区 → 水深计算 → 水量计算 → 栅格转面出图。每一步对应一个可视化检查点填洼后DEM有没有损坏边界、流向栅格是否沿山脊线分布、淹没区边界是否顺滑、水深栅格是否存在负值如果有说明DEM某处高程异常超高需要回看原始DEM。5. 实操演示一个小流域的真实案例为了把抽象流程落到地面我拿一个虚拟但完整的例子从头到尾走一遍。研究区域假设是一个面积约60km²的小流域DEM采用30m分辨率SRTM数据投影坐标系为UTM 50N高程单位为米。项目需求模拟该流域出口断面水位达到245m时的淹没范围与总洪水量。5.1 环境与数据准备软件ArcGIS 10.8ArcMap界面工具完全一致ArcGIS Pro用户操作逻辑类似启用扩展模块菜单栏—自定义—扩展模块—勾选Spatial Analyst不勾选的话水文分析工具箱全灰无法运行原始数据文件DEM_RAW.tif地理坐标系WGS84投影文件DEM_UTM.tif先做投影填坑之前就把投影做完否则填洼会在网格大小不规则以度为单位下产生影响。工具位置数据管理工具—投影和变换—栅格—投影栅格。输出分辨率写30重采样Bilinear。生成后到图层属性里确认像元大小变成了30单位是米。5.2 执行填洼、流向计算工具路径空间分析工具—水文分析—填塞输入DEM_UTM输出Fill_DEM如果流域中有水库等真实洼地设置Z限制为经验值这里假设最大真实洼地高差是15m所以Z限制设为15。再对Fill_DEM运行流向得到FlowDir_Fill。检查一下流向栅格属性表方向值有1、2、4、8、16、32、64、128这些标称如果不慎算出0或负值说明DEM里还有Nodata要先去处理。5.3 提取淹没区在栅格计算器中写inund_bool (Fill_DEM 245)到这里得到布尔栅格。嫌布尔栅格命名不够直观可以重命名为inund_bool。接着右键该图层 — 数据 — 导出数据格式选GRID或TIFF注意把NoData值设为0后续转矢量才干净。用栅格转面工具转换工具—从栅格转出—栅格转面输入inund_bool字段Value输出inund_polygon。在属性表里选Value 1的面导出为inund_final。因为这个案例岸边地形相对规整碎面不多统计下来淹没区被分成了7个主要面。用“计算几何”算面积由于inund_final是UTM坐标直接算出面积约4.32km²也即约432公顷。5.4 计算水深与水量栅格计算器depth_m Con(Fill_DEM 245, 245 - Fill_DEM, NoData)接着volume_m3 depth_m * (30 * 30)打开volume_m3属性表的统计数据Sum值约2, 860, 000。对这个数字就是立方米总水量。为了验证是否大概合理手动估算一下面积4.32km²4, 320, 000㎡平均水深 总水量 ÷ 面积 ≈ 0.66m。对山区小流域来说局部洼地水深从0.2m到3.4m不等0.66m的平均水深在合理区间。提示如果算出来平均水深异常低比如0.1m以下或异常高超过几十米大概率是水位值填错了或者DEM高程基准不一致。别急着改参数回头做数据一致性检查。5.5 出图与汇报这一步是为了汇报。把inund_final矢量叠加在原始填洼DEM或彩色晕渲图上设置半透明蓝色填充边缘加点描边。布局视图里加图例、比例尺、指北针输出成果图。我还要多一步把淹没区分成水深等级0-1m、1-2m、2-3m、3m出图这种分层图的视觉效果和决策支持价值比单一淹没区好得多。在ArcGIS里重分类水深栅格或者用符号系统的分级显示都能实现关键是每级用不同透明度或色带让决策者一眼看清哪个区域风险最高。6. 常见问题与排查技巧实录6.1 结果面积异常偏大先查坐标系。如果DEM是地理坐标单位度淹没区面积是“平方度”实体意义混乱。把面要素投影到Albers或UTM后再算面积。我遇到过不止一次有人拿着WGS84的DEM直接算结果“淹没面积”出现几十亿平方公里的鬼数据。另一个可能原因是水位值把很多山脊“淹了”都没达到——检查水位是否输错。比如流域海拔从200m到1500m结果水位写成了1400m那当然半个流域都淹了。6.2 填洼工具报错填洼工具偶尔报错常见原因有两个输入DEM中存在过量NoData像元。解决方法用“栅格计算器”的Con函数先剔除NoData或者用数据管理—栅格—栅格数据集—复制栅格把NoData值设为可忽略的数值。计算机内存不足。30m分辨率覆盖全国范围的DEM填洼很吃内存。建议裁剪到研究区范围再跑用“按掩膜提取”或“裁剪”工具。6.3 栅格转面后出现无数碎面这几乎是每个项目都会遇到的事。原因DEM本身有噪声导致淹没区边界呈现锯齿状很多锯齿孤立成一个“单像元小岛”。对策在栅格转面前对布尔栅格做一次“众数滤波”焦点统计—多数把孤立像元剔除。转面后在属性表里按形状面积排序删掉那些面积小于若干像元总面积的碎面这里直接将小于900㎡即一个30m像元面积的面全部删掉即可。别小看这一步碎面对总面积的算量影响不大但会让图面非常丑汇报的时候解释不清对方可能质疑整个分析精度。6.4 计算出的洪水量和甲方/文献值对不上这可能是最棘手的。通常不是因为公式错了而是水位基准不一致。你用的245m是黄海高程甲方用的245m是1985国家基准差了好几十厘米自然对不上。DEM精度差异。甲方用的可能假设110000地形图生成的5m精度DEM而你用的SRTM 30m地形细节被平滑后水深分布和淹没范围肯定有差异。淹没区面积阈值设定不同。有些单位做淹没区提取时会把“水深小于0.1m”的区域去除因为它们是地表湿润而不算淹这个阈值直接影响水量就问一句你的阈值是多少建立统一口径结果才可对比。6.5 Archydro DEM Reconditioning报错热门搜索里高频出现这个词。DEM Reconditioning的作用是把河网数据“烧”进DEM里让水流更贴合实际河槽。报错常见原因是研究区域的河流矢量线与DEM范围不完全匹配导致工具在边缘处无法匹配到有效像元。解决方案先“裁剪”河流到DEM边界外一圈缓冲或对DEM先做“按掩膜提取”到河流覆盖范围。同时确保ArcHydro工具正确安装且DEM和河流坐标系统一。7. 进阶思考这套流程怎么扩展到真实项目讲完基础流程忍不住多说几句。这套方法在真实项目中的延伸方向比很多人想象的宽一是多情景模拟与动态风险图。把水位从低到高排一组比如每隔0.5m一个水位循环跑N次淹没分析把所有淹没区叠加出“不同水位下的风险等级”这在防洪减灾里直接用来做人口暴露评估。ArcGIS Model Builder或者Python脚本都能轻松实现批处理工作量从“一周出图”压缩到“半小时跑完”。二是与人口、土地利用、经济数据叠加。淹没区一旦以矢量方式拿到就可以做空间连接快速统计淹没区域内有多少户、多少耕地、多少基础设施资产。这是各类风险评估项目最核心的输出。三是结合雨量径流数据估算洪水总量。如果有多日降雨量、土壤类型等数据可以通过SCS-CN法等水文模型估算洪峰流量和水量再由水位-流量关系反推设计水位这其实是把水文学方法降雨推求径流和水力学方法水位推求淹没范围串联起来形成一套完整分析链条。四是从无源淹没到有源淹没的升级。遇到真正的防洪调度项目可以考虑用有源淹没在ArcGIS中可以通过水文分析工具计算“汇流累积量”在入水口位置做种子点用条件函数的迭代判断计算机模拟水流扩散或者使用Archydro工具与HEC-RAS联动做二维水动力模拟。8. 写在最后的一点个人经验我做过不少和洪水评估相关的项目最深的一个体会是这套流程的技术门槛真不高高的是你对地形、水文学和结果质量的判断力。很多项目里花半周时间在数据检查、坐标基准核对、填洼参数调整上远比多跑几组水位情景更能提升成果质量。数据分析这东西跑出来的结果永远漂亮但能不能让汇报对象信服取决于你背后的假设清楚不清楚、流程可不可复现、结果能不能解释。如果你第一次拿到DEM做洪水淹没分析强烈建议不要直接套参数。先打开属性表看一眼高程范围手动算一封中几个典型像元确认工具逻辑符合预期再全流程运行。跑完用Google Earth或者在线地形服务随机抽几个点验证正确率让人放心时再放心大胆地交付。还有个小技巧需要反复调整水位值时把目标水位设为变量用模型构建器建一个流水线模型。后续改水位只需要调数值整个流程自动重跑出图、出表一步到位这在多情景项目中能省下大量体力活。这行业里效率都是靠理顺流程省出来的而这套流程就是一个足够顺的起点。