⚠️本文在cesium 1.52.0下测试
Cesium支持的地形格式
cesium目前支持的格式有下面的两种地形格式,分别是:
在heightmap 1.0 terrain format说明页面上,官方明确指出这种格式已经废弃了,推荐使用quantized-mesh,关于两种格式的对比,推荐阅读这篇文章。
在Cesium 1.52.0下测试,Cesium
还是支持HeightMap
格式的,未来的Release版本有可能还会继续支持。
鉴于历史原因,项目之前一直使用HeightMap
,最近才迁移成Quantized-Mesh
,但构建离线的地形服务流程基本一致。
基本的构建流程为:
- 获取源DEM文件,如SRTM的tif文件
- gdalbuildvrt合并多个DEM文件(可选)
- 使用ctb-tile,vrt(tif)文件作为输入,生成瓦片
- 托管静态瓦片资源
- 配置Cesium TerrainProvider
详细构建流程
第一步的DEM获取有很多方式,CGIAR CSI或者SRTM Tile Grabber都提供了不错的交互下载方式。
第二步中的gdalbuildvrt是GDAL中的一个工具,可到GDAL的官网下载。
第三步的ctb-tile是一个命令行工具用来创建Cesium支持的地形瓦片。如果只制作
HeightMap
可使用这个docker image homme/cesium-terrain-builder,如果制作Quantized-Mesh
,可使用这个docker image tumgis/ctb-quantized-mesh。第四步搭建一个Node server托管静态文件。
第五步是配置cesium TerrainProvider的url。
如果没有Docker环境,首先安装docker环境,建议安装Docker for Mac / Windows,不推荐使用Docker Toolbox。
这里以构建Quantized-Mesh
为例,首先获取image。
docker pull tumgis/ctb-quantized-mesh
在一个新的容器中执行。
docker run -v /Volumes/HD/test/work/CH/terrainBuilder:/data -ti -i tumgis/ctb-quantized-mesh:latest bash
合并tiffs,生成.vrt文件。
root@31dd6fa3b480:/data/q_mesh# gdalbuildvrt tiles.vrt ./tiffs/*.tif
创建一个terrain文件夹存储切割后的瓦片,运行ctb-tile生成瓦片,这个步骤可能时间较长,可以出去喝杯咖啡。
root@31dd6fa3b480:/data/q_mesh# ctb-tile -f Mesh -C -N -v -o ./terrain/ ./tiles.vrt
// 执行结果
0...10...20...30...40...50...60...70...80...90...100 - done.
创建Cesium layer.json描述文件。
root@31dd6fa3b480:/data/q_mesh# ctb-tile -f Mesh -C -N -l -o ./terrain/ ./tiles.vrt
// 执行结果
0...10...20...30...40...50...60...70...80...90...100 - done.
到此,cesium Quantized-Mesh
的地形瓦片就生成完毕。
最后在程序中使用:
viewer = new Cesium.Viewer('cesiumContainer', {
shouldAnimate: true,
imageryProvider: Cesium.createTileMapServiceImageryProvider({
url: Cesium.buildModuleUrl(MAP_PATH)
}),
terrainProvider: new Cesium.CesiumTerrainProvider({
url: TERRAIN_PATH, // 指定你的地形瓦片url
}),
}
注:使用Node编写server的时候,需要额外的header设置。
app.use(function(req, res, next) {
let filePath = path.join(__dirname, url.parse(req.url).pathname);
let pathTmep = path.extname(filePath)
// 瓦片以.terrain作为文件名后缀
if (pathTmep === '.terrain') {
res.set({
'Content-Type': 'application/octet-stream',
'Content-Encoding': 'gzip',
});
// Content-Disposition: attachment;filename=2948.terrain
res.set('Content-Disposition', 'attachment;filename='+path.basename(filePath))
}
next();
})
Quantized-Mesh vs HeightMap
选取一个4*3的矩形区域作为数据源:
采用的流程都是先将上述12个tif合并成一个.vrt文件,然后使用ctb-tile来进行切割。从最终得到的数据集的大小来看,Quantized-Mesh更节省空间,运行时会更节省内存:
Quantized-Mesh | HeightMap | |
---|---|---|
文件大小 | 747M | 1.02G |
占用空间 | 1.44G | 1.50G |
效果对比:
-
Quantized-Mesh
-
HeightMap