QGIS三维地形展示全流程:从DEM数据到网页交互场景
做三维地形展示这活儿我在QGIS里前前后后折腾了好几轮。说句实在话QGIS处理DEM这种栅格高程数据本来就是看家本事但把DEM真正变成一个有立体感、能转着看的三维场景中间还是有不少门道。网上教程多数只教你怎么点几个按钮出张图没人告诉你坐标系单位不一致会导致地形变成“悬崖”也没人说清楚垂直拉伸系数到底该填多少。这篇文章把我自己从数据下载、色彩渲染到三维视图、网页导出的完整流程梳理一遍适合想用QGIS做三维地形展示、又不想一上来就上Cesium这类重型方案的朋友看完你至少能少走我踩过的那些弯路。1. 项目准备搞懂DEM数据选对工具链1.1 DEM里到底存了什么很多人拿到DEM文件双击打开一看是张灰不溜秋的图以为就是普通影像。其实DEM数字高程模型的每一个像元值代表的是该位置的高程单位通常是米。你看到的灰度图本质上就是把高程值映射到了0到255的灰度区间值越大越亮表示地势越高。这个本质认知很重要因为三维展示的原理说白了就一句话把DEM里每个像元的高程数值作为Z轴坐标再把影像或颜色作为表面纹理贴上去。DEM是栅格数据分辨率越高单个像元代表的地面尺寸越小地形细节就越丰富。常见的SRTM 30米分辨率、ALOS 12.5米分辨率、ASTER 30米分辨率都属于公开可下的档次做区域级三维展示完全够用。顺带说一句热词里有人提到“DSM生成DEM”DSM是地表模型上面带着树和房子顶部DEM是纯地面高程。如果拿DSM直接做三维城市区域会看到一片高低不平的“毛刺”山地森林区域更明显。做地形展示优先用DEM实在只有DSM就得做滤波处理这一步可以放到后续专门聊。1.2 DEM数据从哪下载最省事我日常常用的数据源有几个按推荐程度排一下OpenTopography这个平台可以直接框选范围下载DEM支持SRTM、ALOS等系列而且能自动裁剪成你需要的范围省去了后期拼接裁剪。界面友好数据质量可靠。地理空间数据云国内访问速度很快提供SRTM、ASTER GDEM等产品下载方式也比较贴合国内用户习惯注册后按经纬度或行政区划检索。USGS EarthExplorer数据最全但界面偏老派检索流程繁琐适合需要特定产品或者要做时间序列分析的进阶用户。下载格式我建议直接选GeoTIFF这是QGIS原生支持最好的格式拖进去就能用。如果下载到的是一些IMG或者浮点型二进制格式也不是不能用但大概率要先做格式转换建议下载时多看一眼格式选项能省不少事。1.3 QGIS版本选择与安装注意事项QGIS从3.0开始内置了3D地图视图功能所以我的建议很直接不要用2.x老版本直接装3.34 LTR或者更新的稳定版。LTR是长期支持版插件兼容性好适合干活用。安装方式Windows下推荐用OSGeo4W安装包它能管理QGIS及其依赖库的升级后续更新插件和运行时不太容易出幺蛾子。独立安装包虽然简单但后期想同时装多个版本或者升级组件会麻烦一些。macOS用户直接用官方dmg即可。安装完成后顺便在“插件-管理并安装插件”里检查一下QGIS2ThreeJS是否可用这个后面导出网页版三维场景要用到。2. 三维展示核心思路两条路线怎么选2.1 为什么平面图看不出地形起伏平面图再精细本质是二维投影人眼只能通过颜色渐变和山体阴影来“脑补”地形起伏。你在一张渲染得非常好的平面图上能感觉到山谷和山脊但没法直观判断坡度变化和遮挡关系。三维视图解决了这个问题它把高程值变成真实的Z轴位移加上光照阴影地形结构一眼就能看出来。说得更直白一点平面图是画画三维视图是捏泥巴。捏泥巴的时候你需要一个能自由旋转观察的视角而QGIS内置的3D地图视图和QGIS2ThreeJS导出插件都是把DEM这张“泥巴”捏出来的工具。2.2 两个技术方案对比我在项目里会用两条路线来处理三维展示各有用武之地方案浏览方式优点缺点典型场景QGIS内置3D视图软件内实时浏览和二维数据联动强调色方便不依赖外部环境必须在QGIS里操作不利于分享数据分析、调参、内部评审QGIS2ThreeJS导出网页浏览器打开结果可分享交互流畅无需装GIS软件需要插件导出场景是静态快照交付给客户、嵌入汇报材料内置3D视图适合我还在反复调整配色、探索数据的时候用。QGIS2ThreeJS适合最终成果输出——它会生成一个HTML文件夹里面基于Three.js渲染网页版三维地形发给谁都能用浏览器打开看不需要任何GIS基础。2.3 投影坐标系三维能不能“立起来”的关键这个坑我必须单独拿出来说因为新手几乎都会栽在这里。如果你的DEM是WGS84经纬度坐标系EPSG:4326那么X和Y的单位是度而高程Z的单位是米。1度经度大约对应111公里1米的高程差和这个比起来几乎可以忽略不计。直接按原始坐标去构建三维网格地形会完全“躺平”——看不出起伏或者反过来拉伸系数设大了又变成悬崖峭壁。正确做法先对DEM做重投影转成投影坐标系比如UTM投影或者高斯-克吕格投影让X、Y单位变成米这样X、Y、Z三个轴的单位才一致。重投影操作在QGIS里用“栅格-投影- warp重投影”工具目标坐标系选择适合你所在区域的投影带。如果你只是临时看看不想动数据也可以通过调整3D视图里的垂直夸张系数来缓解但单位不匹配问题始终存在分析坡度这类指标时结果会错得离谱。3. 实操第一站QGIS内置3D视图做实时三维3.1 加载DEM并完成基础渲染先把GeoTIFF拖进QGIS图层区默认显示往往是灰度拉伸很难看。右键图层进入“属性-符号系统”把渲染类型改成“单波段伪彩色”然后选一个适合地形的色带。我比较喜欢用“Turbo”或者自定义从绿到棕再到白的渐变——低海拔绿色、中海拔棕色、高海拔白色符合直觉也方便后面叠加影像一起看。配色之后还有一个关键操作设置拉伸范围。默认情况下QGIS会按直方图的累积计数裁剪容易把高海拔区域压成一片白。右键图层属性里“最小/最大值设置”选择“实际范围”确保色带完整覆盖DEM从最低到最高的所有高程值。这一步不做出图效果会很奇怪高山区和阴影区细节全丢。3.2 创建3D视图并配置地形参数菜单栏点“视图-新建3D地图视图”界面右侧会弹出一个3D面板。接下来是关键配置在这个3D视图面板里找到“配置”或者右键面板选“场景配置”地形类型选择“DEM栅格图层”然后指定高程图层为刚才加载的DEM。“垂直夸张”参数我一般先填5加载出来看效果再往上下调。垂直夸张作用是把地形起伏“竖着拉长”让平缓地区也能看出高低变化但拉过头就会显得假这是一个审美和经验并存的过程。同时建议在“地形”相关设置里开启“平滑”之类选项减少因数据分辨率低产生的棱角感。在“光照”设置里调整方位角和高度角默认值不一定好看山地场景多试几个光照方向找到阴影和向阳面层次最清楚的角度。3.3 三维与二维联动一边看平面一边看立体热词里有“二三维联动”这功能在QGIS内置3D视图里用起来极其顺手。在3D视图面板的顶部或右键菜单里有一个链接视角的开关打开后在二维主画布上平移或缩放三维视图会自动飞到对应位置反过来在三维里旋转视角主画布上的红框也会跟着移动。这功能在做对比分析的时候特别有用。比如我想看某条拟建道路经过区域的地形起伏我会在二维画布上把道路加载出来然后平移过去三维视图自动定位到附近再手动拉高视角看道路穿过的是山脊还是山谷。这个联动效率远高于对着两张不相关的图来回切换。3.4 从3D视图导出静态图三维视图调好后可以直接导出当前视角的图片在3D视图面板工具栏上找到“导出场景为图片”按钮设置输出分辨率。我一般导出宽度不低于2000像素否则打印或者放到PPT里会发虚。如果你只需要地形轮廓不需要真实纹理可以在图层设置里把DEM作为高度和颜色来源不加影像图层这就是所谓的“白模”效果适合做方案底图。顺带提一句如果你在3D视图里还加载了建筑物矢量数据并挤出高度就能做出简单的城市白模效果。原理和DEM三维一样不过那是另一个话题了本文不再展开。4. 实操第二站QGIS2ThreeJS导出网页版三维场景4.1 安装插件并理解其输出原理菜单栏“插件-管理并安装插件”搜索“QGIS2ThreeJS”安装后会在“Web”菜单下出现对应入口。这个插件做的事情并不复杂把DEM的高程值和纹理影像提取出来生成一个Three.js网页项目。它不依赖QGIS实时渲染而是把数据“烘焙”成静态网格。因此你需要理解一点导出之后场景是快照你在QGIS里后续做的任何修改都得重新导出才能同步到网页上。所以工作流应该是先在QGIS里把配色、光照、视野全部调好最后再导出。4.2 导出参数怎么设才合理打开QGIS2ThreeJS后面板里这几项最关键DEM图层选择高程源下拉框里会列出当前项目里的栅格图层。输出文件夹导出会生成一个包含HTML、JS和纹理图片的文件夹路径不要选在C盘系统目录避免权限问题。垂直夸张倍数这个和3D视图里的垂直夸张类似但注意它是独立参数需要重新调。我一般从3到5开始试。纹理图层可以选择影像底图或者继续用DEM本身经过颜色渲染的结果作为纹理。是否生成等高线/格网如果需要可以叠加叠等高线网格线但不建议开太多影响加载速度。设置完点击导出稍等片刻会提示完成。打开输出文件夹里的HTML文件浏览器会加载一个可拖动互动的三维地形。鼠标左键旋转右键平移滚轮缩放交互体验相当顺滑。我把这个HTML文件发给过完全不接触GIS的同事对方也能自己玩明白。4.3 导出网页的两种交付方式一种是直接把整个文件夹发给别人双击HTML就能看适合小规模和局域网环境。另一种是把这个文件夹扔到任意静态Web服务器上通过链接访问适合嵌入到公司内网系统或者汇报页面里。因为生成的内容是纯静态资源不需要后端接口部署极其简单。这里提醒一句如果你只是临时查看不需要装任何三维查看软件浏览器本身就是最好的“免费三维查看器”。网上有些搜索词把3dxml、EPS三维测图这类软件和地形展示混在一起其实它们分别是不同领域的工具QGIS2ThreeJS导出方案的优势恰恰在轻量和免安装。4.4 内置3D视图和QGIS2ThreeJS怎么配合用我自己的习惯是分析阶段用内置3D视图因为改参数即时反馈特别是调光照和垂直夸张的时候内置视图能快速试错。等到最终成果确认无误再开QGIS2ThreeJS导出。导出后哪怕网页里发现某个角度不好看也建议回到QGIS里调完再导不要试图直接改生成的JS代码那个代码结构是插件生成的手动改效率极低。5. 常见问题与排查技巧实录5.1 DEM加载后是黑的或者花斑一片这个八成是拉伸范围设置出了问题。右键图层属性找到符号系统把对比度拉伸的“最小/最大”设置为“实际范围”或者手动输入DEM的最小和最大高程值。如果仍然发黑检查一下是否有NoData值没被识别很多DEM在边缘区域有空值这些空值会被渲染成黑色或异常颜色。解决办法是在图层的透明度设置里把NoData值设为全透明。5.2 3D视图里地形“躺平”或者变成“悬崖”先确认坐标系。如果数据还是经纬度坐标系我建议直接重投影到投影坐标系这是治本之策。如果坐标系已经没问题那垂直夸张系数可能设得不对。地形太平时加大系数看起来太陡峭时调小系数。QGIS内置视图里这个参数可以边看边调直到地形起伏既明显又不失真。5.3 高程单位和坐标单位不一致怎么判断判断方法很简单在图层属性里看坐标系信息。如果是EPSG:4326几乎可以确定是经纬度坐标。如果是UTM带号之类说明已经是投影坐标。再者直接看图层范围数值经纬度的范围绝对值通常在几十到一百多投影坐标的范围通常是几十万到几百万。范围数值符合后者单位基本是米。“躺平”或“悬崖”两个极端都可以从这里排查。5.4 大范围DEM三维卡顿严重这是性能问题也是我实测中经常遇到的。解决思路有两个方向一个是给DEM构建金字塔在“栅格-金字塔”里选择构建之后QGIS会按缩放级别加载不同分辨率的预览另一个是干脆裁剪小范围再加载比如整个省范围的三维浏览真的没必要只保留重点区域。QGIS2ThreeJS导出时也建议先裁剪到目标范围导出过程会快很多生成网页在浏览器里也更流畅。5.5 导出网页后纹理模糊QGIS2ThreeJS导出时会在内部对纹理做重采样如果原DEM范围太大纹理细节会丢失很多。解决办法是在导出前把DEM重采样成一个合理的像素尺寸让最长边控制在2000到4000像素左右。数据量太小导出效果发虚太大导出过程卡死这个区间是实测下来的折中范围。最后再分享一个我自己比较固定的操作顺序拿到DEM先看坐标系不是投影坐标就重投影接着做伪彩色渲染并确认实际拉伸范围然后开3D视图调垂直夸张和光照定稿后导出静态图或者用QGIS2ThreeJS生成网页版。这套流程走顺以后从拿到数据到交付三维场景基本就在半小时以内。如果你拿到的数据是DSM或者有大量异常高程值记得先做一步去噪或滤波处理这一步单独拎出来又能讲不少等下次有机会再展开。