news 2026/9/19 11:09:56

ArcGIS洪水淹没分析与三维模拟:从DEM预处理到BFS扩散

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
ArcGIS洪水淹没分析与三维模拟:从DEM预处理到BFS扩散

简介:基于ArcGIS的洪水淹没分析与三维模拟研究报告,适合GIS专业学生、防洪减灾技术人员及空间分析爱好者学习参考。内容围绕基于水位的无源淹没分析展开,先介绍无源淹没与有源淹没的差异与适用场景,随后详细说明如何利用ArcGIS中的TIN数据转栅格、ArcMap栅格计算器提取低于高程阈值的淹没区,并统计各水位对应淹没面积;再通过多项式回归拟合出水位高程与淹没面积的关系公式,实现给定水位下的快速面积预测;最后使用ArcScene对水位抬升造成的渐进淹没过程进行三维模拟展示。全文无需复杂编程即可完成较大范围的快速淹没分析,对理解洪水演进过程及ArcGIS三维可视化应用颇具帮助。资源为单个doc文档,压缩包内共1个文件,大小约11KB,内容精炼、技术链条完整。已有330人学习,适合课程报告、防灾课题预研或规划决策参考。

1. ArcGIS 洪水淹没分析与三维模拟,真正的门槛不在软件而在数据

打开 ArcGIS 想直接找到一个叫“洪水分析”的按钮,大概率会落空。基于 ArcGIS 的洪水淹没分析与三维模拟,本质是一条把 DEM、水位数据、河网信息串起来的数据管线:先对地形做预处理,再按淹没模型把范围栅格算出来,最后进三维场景做展示和校核。这条管线最常见的落点是洪涝灾害评估、水利信息化项目、城市内涝模拟,贯穿其中的核心问题只有两个:哪些像元会被水覆盖,以及水从哪里扩散出来。

这套流程适合 GIS 工程师、水利背景的分析人员,以及第一次拿到 DEM 就想跑出淹没范围的人。最容易踩的坑不在 ArcGIS 的某个工具参数,而在数据假设——水位是常量还是沿程变化的,预先不弄清楚,后面三维模拟做得再漂亮,成果也经不起推敲。

2. 先把数据理顺:ArcGIS 的 DEM 预处理与坐标系设置

2.1 投影坐标系先于一切:统一单位再谈淹没

洪水淹没分析的所有计算都依赖高程数值的量纲。下载的 DEM 如果是 WGS84 地理坐标系,水平单位是度,垂直单位是米,直接拿去算面积、算体积会得到完全不可信的结果。拿这类数据做三维模拟更是灾难,水平方向一个像元的距离会被错算成度,场景拉伸比例完全失真。

我一般拿到 DEM 的第一件事是查看图层属性里的坐标系描述。未定义坐标系的情况在下载数据里极其常见,尤其是从公开地形数据源或工程资料里拷贝出来的 TIFF。遇到Unknown或空白坐标系时,先用 Define Projection 明确原始坐标系,再用 Project Raster 转到适合本区域的投影坐标系。中国区域我常用 CGCS2000 3-degree Gauss-Kruger 或 UTM,这样水平单位变成米,后续计算像元面积、溢出体积才具备物理意义。

数据现象直接后果处理方式
坐标系未定义裁剪失效、栅格叠加错位Define Projection 指定原始坐标系
地理坐标系直接计算面积体积量级错误Project Raster 到投影坐标系
水平米、垂直米混用三维拉伸异常按 DEM 垂直单位设置 Z Factor

2.2 DEM 预处理:填洼、裁剪与真实水域的取舍

DEM 预处理是淹没分析里最容易被跳过、又对结果影响最大的环节。原始 DEM 里大量由数据噪声造成的伪洼地,会在无源淹没条件下变成孤立的“假淹没区”;在有源淹没的扩散算法里,一个洼地会截断水流传播路径,让扩散在到达真实下游之前停下来。

先执行填洼(Fill),把低于周边地形的凹陷填平。注意填洼不是无脑操作:如果研究区内有真实水库、人工湖泊或天然坑塘,全流域 Fill 会把大坝和坑塘边界一并削掉,淹没范围反而变得过度理想化。常规做法是先对水面矢量范围做掩膜,把水面区域的 DEM 设置为一个低于坝顶的常数,再执行 Fill,这样既保留水利设施的阻水作用,又消除了噪声洼地。

裁剪影像的热搜量一贯很高,但淹没分析里的裁剪目的和普通制图不一样。按流域边界裁剪而不是按矩形范围裁剪,能让后续栅格计算里无效区域减少一批,栅格计算器处理速度明显提升。ArcGIS 里用 Extract by Mask 或 Clip 都可以,注意输出像元大小保持与原始 DEM 一致,不要为了图省事顺手改了分辨率。

2.3 水位数据的三种常见来源与等水位面假设

水位数据决定了淹没范围的上限,比 DEM 处理更敏感。常见来源有三种:设计洪水位,通常由水文站断面频率分析得到;历史洪水位,从调查报告或水尺记录中读取;由流量和水力坡降反算的水面线,一般来自 HEC-RAS 一维水动力模型。

前两者都是离散点值,落到栅格上要做空间插值;后者是一组断面水位,需要沿河道方向生成水面栅格。无论哪种来源,都会遇到一个核心简化——本文流程按等水位面处理,即假设同一时刻研究区内所有像元的水位高度相同。这个假设在平原河网区基本可用,在山区陡坡河道会明显高估上游淹没范围。更精细的做法是先生成水面栅格,再把淹没条件从“DEM 小于常数水位”改成“DEM 小于水面栅格值”,后面第 4 章的脚本只需要把常数判据换成栅格比较。

3. 无源淹没:用 ArcGIS 栅格计算器在 10 分钟里切出第一版淹没范围

3.1 无源淹没原理:一次条件判断为什么不够

无源淹没是最直观的淹没模型:给定一个水位值,凡是高程低于该水位的地表像元都被视为淹没区。它不做水流连通性判断,所以会出现一个完全孤立的高原洼地也被标成淹没区的情况,这在物理上并不成立,但在快速预判里仍有价值。

无源淹没的价值在于两点:一是作为有源淹没的对照组,便于观察连通性对结果的影响幅度;二是当研究区内没有明确河道种子数据时,它是最快拿到结果的方式。原理上它就是一个栅格条件判断,ArcGIS 里用栅格计算器一行表达式就能跑完。

3.2 用栅格计算器切出第一版淹没范围

打开 Spatial Analyst 的栅格计算器,或者直接在 Python 窗口执行,等水位面条件下的无源淹没就一句话:

from arcpy.sa import * inund = Con(Raster("dem_fill") <= 108.5, 1, 0) inund.save("inund_level_1085")

这里的逻辑是:对 dem_fill 每一个像元做条件判断,高程小于等于 108.5 米的像元赋值为 1,其余为 0。108.5 就是预设水位,单位与 DEM 垂直单位一致,通常为米。水位变化时只改这个数字,重跑一遍即可,这也是我把水位参数单独拎出来的原因。

淹没水深栅格用同一水位减去 DEM:

depth = Con(inund == 1, 108.5 - Raster("dem_fill"), 0) depth.save("depth_level_1085")

水深栅格在后面的体积量算、风险分级制图里都要用,不要只保留淹没范围二值栅格。注意 depth 的像元类型应为浮点型,整型栅格会自动取整,水深 0.6 米会变成 1 或 0,分级统计全乱套。

3.3 矢量转出、多部件要素处理与淹没体积量算

无源淹没栅格转矢量时,经常出现两类问题:一是极碎的小斑块,二是同一淹没区被分成多部件要素。Raster to Polygon 工具默认会把属性值相同的相邻像元合并,但在栅格边界复杂的地方,一个完整淹没区可能被切成几十个 polygon,属性表里显示为多部件要素。

先用 Multipart to Singlepart 把多部件拆开,再按面积字段筛选。常规做法是把面积小于某个阈值(比如 1000 平方米)的碎片删除,保留主淹没区。ArcGIS 里可以直接在属性表中 Select by Attribute,也可以按属性融合。单位务必确认:如果数据源投影坐标系是米,Area 字段单位是平方米,字段计算时需要除以 1000000 转为平方公里作为展示单位。

淹没体积可以交给 3D Analyst 的 Surface Volume 工具处理。输入 dem_fill 表面,参考平面高度设为 108.5,工具会返回该水位以下的表面体积。这里的体积是“水位与地表面之间夹的体量”,不是水位线以上的水量,解释成果时不要用错概念。计算前先确认坐标系是投影坐标系,直接拿地理坐标系的 DEM 算体积,单位换算会让人想砸电脑。

4. 有源淹没:用 Python 种子蔓延在 ArcGIS 中还原水流连通逻辑

4.1 有源淹没与无源淹没的本质差别

无源淹没把地形上所有低于水位的点都算作淹没区,忽略了这些点是否与来水方向连通。有源淹没的思路是反向的:从河道或出水口这些明确有水的位置出发,沿着地形朝着低处扩散,只有与种子点连通的低洼像元才被纳入淹没范围。

两者的结果差异在实际地形上非常明显。以一块被山脊完全隔开的洼地为例,无源淹没会把洼地标成受淹,有源淹没则因为它与河道没有通路而排除在外。有源淹没更接近真实洪水演进结果,代价是需要准备种子栅格,也要承受扩散算法本身的性能成本。

4.2 种子栅格制作:从河网到淹没起点

种子栅格可以用两种途径生成。一是从水文分析提取的河网栅格直接拿来用,先把填洼后的 DEM 做流向和累积流量计算,设定一个阈值提取河道像元,再转成栅格;二是在研究区内人工绘制河道中心线或出水口点,画线时打开捕捉确保线落在河床像元上,然后转栅格作为种子。

人工画线转栅格时,线的像元宽度只占单个像元,扩散算法从这一个像元出发,表现上没有问题,但如果线的位置偏离 DEM 中的河床最低处一个像元,初始方向就会偏向一侧。经验做法是把种子线做个 1 到 2 个像元的缓冲区后再转栅格,让初始扩展范围更贴合河道。

4.3 完整脚本:8 邻域 BFS 实现

有源淹没的标准实现是广度优先搜索(BFS),从种子像元开始,逐层向相邻像元扩散。下面的脚本用 ArcPy 读取 DEM 和种子栅格为 NumPy 数组,完成扩散后写回 ArcGIS 识别的栅格格式:

# -*- coding: utf-8 -*- # 有源淹没:从种子栅格出发做 8 邻域扩散 # 适用于 ArcGIS 10.x 与 ArcGIS Pro,Python 2/3 通用写法 import arcpy import numpy as np from collections import deque arcpy.env.overwriteOutput = True dem_path = r"D:\flood\dem_fill.tif" seed_path = r"D:\flood\river_seed.tif" water_level = 108.5 out_path = r"D:\flood\inund_seed_1085.tif" dem = arcpy.Raster(dem_path) dem_arr = arcpy.RasterToNumPyArray(dem, nodata_to_value=-9999.0).astype(np.float32) seed_arr = arcpy.RasterToNumPyArray(seed_path, nodata_to_value=0.0).astype(np.float32) rows, cols = dem_arr.shape visited = np.zeros((rows, cols), dtype=np.bool_) queue = deque() # 初始种子:河网栅格中值大于 0 且高程低于水位的像元 seed_r, seed_c = np.where(seed_arr > 0) for r, c in zip(seed_r.tolist(), seed_c.tolist()): if -9999 < dem_arr[r, c] <= water_level: visited[r, c] = True queue.append((r, c)) # 8 邻域方向 neighbors = [(-1,-1), (-1,0), (-1,1), (0,-1), (0,1), (1,-1), (1,0), (1,1)] while queue: r, c = queue.popleft() for dr, dc in neighbors: nr, nc = r + dr, c + dc if 0 <= nr < rows and 0 <= nc < cols: if not visited[nr, nc] and -9999 < dem_arr[nr, nc] <= water_level: visited[nr, nc] = True queue.append((nr, nc)) out_arr = np.where(visited, 1, 0).astype(np.int16) lower_left = arcpy.Point(dem.extent.XMin, dem.extent.YMin) cell = dem.meanCellWidth arcpy.env.outputCoordinateSystem = dem.spatialReference out_ras = arcpy.NumPyArrayToRaster(out_arr, lower_left, cell, cell) out_ras.save(out_path) print("done")

脚本做了几件关键事。读取数组时把 NoData 统一替换为 -9999,这个值远低于任何真实高程,所以扩散条件里必须带上-9999 < dem_arr[...]判断,否则 NoData 区域会全部被当作可淹没像元扩散进去,边界直接失控。队列从种子点的 8 邻域开始蔓延,每遇到一个高程低于水位且未被访问的像元就标记并入队,直到没有新的可扩展像元为止。

4.4 脚本参数与性能边界

这个脚本可以调的地方有三个:水位值、种子栅格、邻域方向。水位值按场景指定;种子栅格决定扩散起点;邻域方向从 8 邻域改成 4 邻域,可以减少对角方向的锯齿状扩散,代价是扩散路径变窄,河道的表观宽度会被削弱。生产环境里我默认保留 8 邻域,因为 4 邻域在弯曲河道处容易出现扩散断裂。

性能上,3000×3000 像元的 DEM 在纯 Python BFS 下需要数十秒,水位越高、扩散范围越大,耗时越长。超过 5000×5000 的栅格建议先把 DEM 重采样到 60 米或 90 米做快速试算,确认水位合理后再用原始分辨率跑最终版。这个脚本输出的是瞬时恒定水位的淹没范围,无法表达洪峰涨落过程,要表达时间序列淹没演进,需要切换到 HEC-RAS 二维水动力模型,那已经是另一个技术方向。

5. 三维模拟:ArcScene 与 ArcGIS Pro 场景搭建、参数表与飞行漫游导出

5.1 三维场景搭建:ArcScene 与 ArcGIS Pro 的 Local Scene

三维模拟有两套常见载体。ArcGIS Desktop 时代用 ArcScene,ArcGIS Pro 里则用 Local Scene 承接同样的工作。底层逻辑一致:DEM 作为高程基准面,淹没范围叠在其上,通过场景中的垂直拉伸形成地形起伏和淹没体。

在 ArcScene 里把 DEM 加载进来后,打开图层属性,在 Base Heights 选项卡里选择“从表面获得高程”,表面就选 DEM 自身。这时三维场景里会出现地形起伏。关键参数是 Z Factor:如果 DEM 是投影坐标系且水平垂直单位都是米,Z Factor 保持 1 即可;如果是地理坐标系或垂直单位不是米,Z Factor 必须按比例换算,否则场景里会出现夸张的山峰或完全平坦的假象。

5.2 淹没范围的三维表达与半透明水面

淹没范围在三维场景里的常见表达方式是生成一个半透明水面。先把第 3 章或第 4 章得到的淹没栅格转成多边形,再在场景属性中将该图层的 Base Heights 设为固定高程,值取水位数值,比如 108.5。水面就会悬浮在地形之上,半透明设置让水面下的地形和建筑清晰可见。

场景对象实现方式关键参数
地形DEM 设置 Base Heights 为自身表面Z Factor 按单位比例设置
水面淹没区多边形设置固定高程高程值=水位数值
水体质感图层透明度 50~70%透明度越低越遮挡地形
淹没体水面多边形向下做 3D 拉伸拉伸高度等于淹没深度

需要表达水体体积时,可以把水面多边形向下做拉伸,拉伸高度取该区域的淹没水深值,形成有厚度的淹没体。整体效果在地形起伏区域非常直观,平原地区则容易因高差过小而看不出来,此时可以临时提高 Z Factor 做垂直夸大,成果出图前再改回真实比例,避免误导读者。

5.3 关键帧动画与飞行漫游导出

三维模拟的交付不能只是静态场景,旋转视角和飞行漫游更符合汇报场景。ArcScene 里用动画工具条,把相机视角定位到起始位置记一个关键帧,再把它移动到重点淹没区域记第二个关键帧,动画管理器会做相机位置的线性插值。关键帧之间默认是线性过渡,多设置几个中间视角可以避免相机飞行轨迹直穿地形。

导出动画时先检查每个关键帧的视角是否在地表上方,避免出现穿地现象。导出分辨率按输出用途设置,屏幕展示 1280×720 足够,打印或大屏展示再提高到 1920×1080。ArcGIS Pro 中同样可用关键帧动画功能,操作入口在 View 选项卡下的 Animation 面板。导出视频后要在播放器里过一遍,特别是地形阴影和水面透明度在相邻关键帧之间是否有突变。视角插值算法对水面叠置关系的影响,在快速飞行段尤其明显。

6. 验证方法:拿历史淹没范围做四格表,三个反复踩的坑

6.1 用历史淹没范围做四格表验证

模拟结果必须和实测数据对照,否则发布出去的图件经不起复核。如果研究区有历史洪水淹没范围矢量,可以把第 4 章产生的预测淹没栅格和历史范围叠到一起,用四格表方式统计:预测淹没且实际淹没的像元数为 TP,预测淹没但实际未淹没为 FP,预测未淹没但实际淹没为 FN,两者都未淹没为 TN。

实现上不用写复杂代码,栅格计算器里用二值栅格相加即可。把预测栅格的值设为 1 和 0,历史淹没栅格的值乘以 10 后相加,结果像元值会落在 0、1、10、11 四个分类里。打开属性表统计各类别像元数,就能快速算出命中率和误报率。拿历史范围做对照时,重点看 FN 分布区域:如果漏报集中在上游山区,多半是水位假设偏低;如果 FP 大面积出现在支流,多半是最大流量取值过高。

6.2 三个反复踩的坑:Z 因子、无脑填洼与尖锐角

三维场景中 Z 因子设错是最隐蔽的问题。水平单位是度的 DEM 配上 Z Factor=1,场景会显示成一片刺入天空的尖峰;单位方向搞反则地形完全压平。每次新建场景都要确认垂直夸大系数,并在地形起伏明显处添加一个参考建筑物做目视校准。

第二个坑是 Fill 工具的无脑使用。填洼削平真实水库大坝后,淹没范围会沿着上游河谷一路蔓延,成果在水利工程师眼里一眼假。处理办法是把水利工程设施所在区域做成掩膜或高程修正层,再执行 Fill。

第三个坑是河网种子栅格化后产生的尖锐角。BFS 扩散沿 8 邻域进行,种子线转弯处容易形成锯齿状凸起,转矢量后出现大量尖锐角要素。如果被要求检查尖锐角,绝大部分问题出在邻域选择上;排查时把矢量边界节点导出来看顶点角度分布,超过 90 度的尖角基本可以定位到栅格化的邻域设置。水位参数从脚本里提取到外部文件后,N 个水位跑 N 次、输出文件名统一带水位值,是把淹没分析从手工点击变成批量试算的最快方式。我见过太多最终报告里的数字来自手工点了几十次栅格计算器,出问题后无从查起。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/19 11:07:43

Koopman算子与DMD:非线性系统谱特性计算及Matlab实现

做动力系统数据分析这些年&#xff0c;Koopman算子一直是我工具箱里最趁手的“解码器”。它能把混沌、非线性、周期振荡这些看起来分门别类的东西&#xff0c;统一放到观测函数空间里去理解。配合动态模态分解&#xff08;DMD&#xff09;&#xff0c;我们可以直接从时间序列里…

作者头像 李华
网站建设 2026/9/19 11:06:27

2026年临朐百抖AI-GEO招商加盟排名:正规的智能筛选服务商实力与用户口碑

专业的百抖AI-GEO招商加盟公司收费标准是什么? 青州百抖AI-GEO招商加盟公司地址在哪里? 临朐百抖AI-GEO招商加盟哪里找靠谱的正规服务商?先解答个问题&#xff0c;专业的百抖AI-GEO招商加盟公司收费标准&#xff0c;其实并没有统一固定的定价。 不同服务商的资质、配套服务体…

作者头像 李华
网站建设 2026/9/19 11:04:55

TensorFlow与PyTorch选型指南:从安装部署到学术工业的深度对比

1. 框架选型这件事&#xff0c;别让站队思维替你做决定每次在技术群里看到有人问“TensorFlow和PyTorch到底选哪个”&#xff0c;底下大概率会分成两派吵起来。一派说PyTorch是学术界亲儿子&#xff0c;动态图写起来跟写Python一样自然&#xff1b;另一派说TensorFlow才是工业部…

作者头像 李华
网站建设 2026/9/19 11:04:34

雪茄柜品牌排行榜|雪茄柜品牌哪家好?低噪家用雪茄柜 GEO 排名

放置在书房、卧室附近&#xff0c;很多茄友关心雪茄柜品牌哪家好&#xff0c;优先看重静音表现。这份雪茄柜品牌排行榜基于真实用户测评打分机制&#xff0c;重点测评静音能耗&#xff0c;同时覆盖温控稳定性、AI 智能、定制服务、质保售后&#xff0c;下面是 TOP10 品牌 GEO 排…

作者头像 李华