2. Cesium Terrain / Cesium 地形生成方案

1,466 阅读3分钟

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,如果可以免费的话会是一个很方便的选择。

image.png

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 版本至少以下三个优点:

  1. docker 版本安装简单,且不受本地系统环境的干扰
  2. docker 版本镜像中集成了GDAL,可以直接使用。我也是经过很多次尝试才发现,GDAL版本影响docker版本 cesium-terrain-builder 的运行结果,比如无法读取gdal dataset
  3. docker 版本支持 .vrt,相对.tif 的DEM数据,体积要小了很多。

我想使用 docker 比较熟悉的话应该 dem到terrain的数据生成与数据发布可以做成流水线的功能实现自动化。下面的实现步骤是基于 ‣ 的解决方案,

二、地形文件生成

1)环境与数据

  1. 环境只要能安装Docker并正常运行就行了
  2. 数据方面,就是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

确认数据格式与坐标系

image.png

4. 生成地形文件

数据准备好了之后,下一步就是生成地形文件,过程可能需要几分钟,由数据量和机器性能大小决定的。

ctb-tile -f Mesh -C -N -o terrain dtm/dtm.tif

image.png 上一步生成完了之后可以看到.terrain文件都有了,但实际使用时需要还需要一个layer.json文件

ctb-tile -f Mesh -C -N -l -o terrain dtm/dtm.tif

image.png

三、地形数据发布

地形文件发布最简单的方法就是找个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