Cesium Terrain / Cesium 地形生成方案
在成功渲染出Cesium三维视图之后,接下来必不可少的一步就是加载三维地形。根据官方GitHub仓库的Cesium Terrain的定义如下
A terrain tileset in quantized-mesh-1.0 format is a simple multi-resolution quadtree pyramid of meshes. All tiles have the extension .terrain
详细技术规格和实现原理可以参考 github.com/CesiumGS/qu…
一、Cesium Terrain 生成方案
1) Cesium Lib
网络上找到最多的生成 Cesium 地形的方法就是下载 CesiumLab,我之前参与过的项目合作方也是使用CesiumLab,如果可以免费的话会是一个很方便的选择。
2)Cesium-Terrain-Builder
我找到了2个版本的 Cesium-Terrain-Builder
1. cesium-terrain-builder
我直接直接装在机器上可以运行对应的命令来切片的,参考GitHub下的文档成功等到了terrian tiles。然后这个功能却未能生成 layer.json。在 issues 里面看到说推荐使用dokcer版本的 cesium-terrain-builder
2. cesium-terrain-builder-docker
Docker 版本的工具安装也很难简单,使用文档中的方法确实也等到terrain tiles,使用 Docker 版本至少以下三个优点:
- docker 版本安装简单,且不受本地系统环境的干扰
- docker 版本镜像中集成了GDAL,可以直接使用。我也是经过很多次尝试才发现,GDAL版本影响docker版本 cesium-terrain-builder 的运行结果,比如无法读取gdal dataset
- docker 版本支持
.vrt
,相对.tif
的DEM数据,体积要小了很多。
我想使用 docker 比较熟悉的话应该 dem到terrain的数据生成与数据发布可以做成流水线的功能实现自动化。下面的实现步骤是基于 ‣ 的解决方案,
二、地形文件生成
1)环境与数据
- 环境只要能安装Docker并正常运行就行了
- 数据方面,就是DTM,DEM,DSM都行,我自己测试的时候用的DTM
2)操作步骤
1. 安装好Docker后拉取CTB的镜像, 镜像地址:tumgis/ctb-quantized-mesh
docker pull tumgis/ctb-quantized-mesh
2. 运行镜像
# 第一运行容器,成功后会进到容器里面
docker run --name ctb -t -i tumgis/ctb-quantized-mesh:latest /bin/bash
# 如果退出了之后,再次进入容器里面可以用下面的命令
# 如果容器运行需要先启动容器
docker start ctb
# 进入到容器
docker exec -it ctb bash
3. 拷贝数据到容器
数据就是上面提到的DTM,数据格式可以是.tif
或者.vrt
,我测试的时候两个都试过都能成功生产地形数据。
坐标最好是WGS84-EPSG:4326,这个是Cesium支持的坐标系,如果数据是其他坐标需要统一到这个。
⚠️ 特别注意,如果需要做数据处理,如格式转换,坐标系转换等操作最好都用这个镜像里面已经有的 GDAL
来做,否则在后面生成地形数时,CTB工具会报错说不认识这GDAL数据集。
docker cp /$PATH_TO_YOUR/dtm.tif ctb:/data
确认数据格式与坐标系
4. 生成地形文件
数据准备好了之后,下一步就是生成地形文件,过程可能需要几分钟,由数据量和机器性能大小决定的。
ctb-tile -f Mesh -C -N -o terrain dtm/dtm.tif
上一步生成完了之后可以看到.terrain文件都有了,但实际使用时需要还需要一个
layer.json
文件
ctb-tile -f Mesh -C -N -l -o terrain dtm/dtm.tif
三、地形数据发布
地形文件发布最简单的方法就是找个WebServer把数据发出去就是了,我自己就是用的Nginx。上面数据生成之后也很容易就能用Nginx发布,但是前端调用的时候却报错。
经过一波猛烈的Google之后,最后定位到问题,也找到了解决方案。上面步骤是没有问题的,问题是在nginx的配置。
因为CTB生成的地形文件是gzip
压缩文件,所以WebServer里面也需要添加想要的gzip
配置保证数据能在前端被正确解析。下面就是我测试用的nginx配置
# 文件路径:/etc/nginx/nginx.conf
user root;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
# 文件路径: /etc/nginx/conf.d/default.conf
server {
listen 80;
listen [::]:80;
server_name localhost;
#access_log /var/log/nginx/host.access.log main;
location / {
root /root/;
index index.html;
}
# !!!!!!!
# !!!!!!!
# 重点就下吗的配置,处理跨域和gzip
location /terrain {
alias /root/terrain;
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept";
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
location ~* .terrain$ {
add_header Content-Disposition 'attachment;filename=$arg_filename';
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept";
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
add_header Content-Encoding "gzip";
add_header Content-Type "application/octet-stream";
}
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
综上,生产地形就实现了,大家可以按照步骤实际操作一次,如果有问题可以留言。下面是我解决问题用到的问题,感觉兴趣可以进去看看。后面会陆续出更多,关于CesiumJS的分享。
四、参考文档
1. https://github.com/geo-data/cesium-terrain-builder/blob/master/docker/README.md
2. https://blog.csdn.net/dongdong9223/article/details/71425077
3. https://registry.hub.docker.com/r/homme/cesium-terrain-builder
4. https://help.hcltechsw.com/commerce/9.0.0/developer/tasks/tigentercontainer.html
5. https://github.com/geo-data/cesium-terrain-builder
6. *https://github.com/tum-gis/cesium-terrain-builder-docker
7. https://github.com/geo-data/cesium-terrain-builder/issues/96