CesiumJS 海底地形可视化指南
【免费下载链接】cesiumAn open-source JavaScript library for world-class 3D globes and maps :earth_americas:项目地址: https://gitcode.com/GitHub_Trending/ce/cesium
海洋工程与 GIS 工作中最常见的动作之一,是把水深数据叠加到三维地球上,用颜色直接读出海底坡度与地貌。本文讲解如何做 CesiumJS 海底地形可视化:从准备水深数据、跑通一个基础海洋场景,到按高程完成着色,最后讨论三个容易踩坑的细节。读完后,你可以独立写出一份"水深 → 颜色"的可视化页面。
从实际场景出发(数据与准备)
示例场景:项目组要查看某片海域的坡度和海山分布,需要把多波束测深导出的水深网格叠加到地球上,再按水深深浅着色。
需要准备的数据有两类:
- 地形数据:CesiumJS 地形以瓦片组织,可以直接使用 Cesium ion 提供的全球海底地形服务(仓库示例调用
createWorldBathymetryAsync请求,需要一个 ion token);如果有自己的水深网格,也可以封装成 QuantizedMesh 或 3D Tiles 地形瓦片。 - 叠加数据:矢量要素、工程设施位置等。仓库在 Apps/SampleData/ 下提供了 CZML、GeoJSON、3D Tiles 等格式的样本数据,换成自己的数据即可直接测试。
下面这张灰度全球地貌纹理,可以作为理解海底地形源数据分布的直观参照(陆地亮、海洋暗)。
跑通你的第一份海底地形
环境搭建与启动
只需安装依赖并启动本地服务。克隆仓库后执行:
git clone https://gitcode.com/GitHub_Trending/ce/cesium cd cesium && npm install && npm run start服务启动后在浏览器打开 http://localhost:8080/(端口以终端输出为准),首页即可浏览仓库内置的各类示例。
创建基础海洋场景
创建一个 Viewer 并指定海底地形,核心代码只有几行:
const viewer = new Cesium.Viewer("cesiumContainer", { terrainProvider: await Cesium.createWorldBathymetryAsync({ requestVertexNormals: true }) }); viewer.scene.globe.maximumScreenSpaceError = 1.0; viewer.scene.globe.enableLighting = true;createWorldBathymetryAsync请求全球海底地形;requestVertexNormals让瓦片携带顶点法线,海底起伏才有光影可表现;maximumScreenSpaceError控制瓦片精度阈值(LOD 即按视角距离切换瓦片精度);enableLighting打开光照,让地形凹凸更明显。
加载地形数据并着色
给地球挂一个按高程取色的材质就完成了水深着色:
const material = Cesium.Material.fromType("ElevationRamp"); material.uniforms.image = colorRamp; // 用 canvas 画出的色带 material.uniforms.minimumHeight = -10000; material.uniforms.maximumHeight = 2000; viewer.scene.globe.material = material;ElevationRamp是引擎内置材质:传入一张色带图和上下界高度,把每个顶点的高程映射到色带上的对应颜色。代码里的colorRamp是用 canvas 画了渐变的画布,完整绘制代码在 Bathymetry 示例中;想组合等高线或坡度着色,可参考 Globe Materials 示例。
三个容易踩坑的细节
水深与色彩的映射:先归一化再查色带
现象:按水深原始值直接取色,海底变成一大片单色,浅水区细节丢失。原因:水深量级跨度大,海底主体在几千米以下,浅水只占一小段区间,色带按深度均分会被深海"吃掉"。规避方法:先做归一化,即(height - minimumHeight) / (maximumHeight - minimumHeight),再按归一化结果取色;示例在 -500、-2000、-5000、-8000 等深度各设一个颜色节点(采用 matplotlib cmocean 的 deep 配色),保证浅水区仍有足够的色阶区分。
坐标系与投影对齐:让地形和数据同处一个基准
现象:自己的水深网格或矢量数据与地形对不齐、整体偏移。原因:CesiumJS 默认使用 WGS84 椭球经纬度基准,若数据是投影坐标系(如 UTM)导出而未做转换,必然错位。规避方法:封装瓦片前统一转到经纬度,发布前用已知控制点或海岸线轮廓核对一遍;只叠加矢量时用 GeoJSON(本身即经纬度)可以省去重投影这一步。
大范围海域性能:LOD 阈值与缓存要分开调
现象:横跨大洋飞行时卡顿,回到已看过的区域又要重新加载。原因:CesiumJS 按屏幕空间误差决定每块瓦片的精度,误差阈值设得过小会让高精度瓦片数量激增;另一部分是缓存没生效,同一瓦片被反复请求。规避方法:把globe.maximumScreenSpaceError调到合适值(示例提高到 1.0 换取更精细的海底,前提是带宽允许);同时启用磁盘缓存,网络面板里会看到瓦片请求标记为 (disk cache),二次访问不再发请求。
还能往哪走
- 叠加海洋工程设施:平台、海底管道等可以 glTF 或 3D Tiles 模型放到海底地形上,仓库
Apps/SampleData/models/下有大量可直接引用的模型样本。 - 时间序列动态展示:潮流、温度这类随时间变化的数据可用 CZML 时间动态方案,仓库有 TimeDependentPaths_Whole.czml 这类现成示例。
- 水面材质:想表现海面而非只画海底,可以给水层加法线贴图,仓库自带这张纹理,效果如右图。
去哪找现成参考
- Bathymetry 示例:本文主线对应的完整例子,含海底地形、色带绘制、等高线与垂直夸大。
- Globe Materials 示例:高程等高线、坡度、坡向等一套地形材质示例。
- 引擎源码:想深入地形瓦片调度与材质 Fabric 实现时从这里入手。
- 样本数据目录:CZML、GeoJSON、3D Tiles 等格式的样本,替换成自己的数据即可复用。
本文覆盖了从准备水深数据、跑通海洋场景、完成高程着色到映射/坐标系/性能三个细节的完整链路;下一步可以把自己的水深网格封装成瓦片,接进上面的着色流程。
【免费下载链接】cesiumAn open-source JavaScript library for world-class 3D globes and maps :earth_americas:项目地址: https://gitcode.com/GitHub_Trending/ce/cesium
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考