前言
在Cesium的学习中,学会读文档十分重要!!!在这里附上Cesium中英文文档1.117。
在Cesium项目中,在平坦坦地球中加入三维地形不仅可以增强真实感与可视化效果,还可以提升用户体验与交互性,今天,我们来学习一下如何将dem/tif格式的地形数据进行分块和加载。
一、dem/tif格式数据下载
DEM(Digital Elevation Model)是描述地表高程信息的数字模型,通过规则网格或点云数据记录地形起伏,广泛应用于地理信息系统(GIS)、遥感、三维可视化(如Cesium)等领域。
1.1、DEM常见数据格式
- GeoTIFF(.tif):地理参考的栅格格式,高程值存储为像素值,元数据(坐标、投影)嵌入文件头。其兼容性强,QGIS、ArcGIS、Python GDAL均支持。 如NASA SRTM数据(30米分辨率)常以GeoTIFF分发。
- ASCII Grid(.asc):纯文本格式,以行列数、网格尺寸、高程值矩阵定义地形。
- HGT(.hgt):SRTM任务专用格式,每文件覆盖1°×1°区域。
- DEM(.dem):USGS标准格式,含头文件(坐标、分辨率)和二进制高程数据。
- Point Cloud(.las/.laz):离散点云记录高程,精度极高但需栅格化生成DEM。
1.2、DEM数据的获取
在国内,我们可以使用地理空间数据云来获取DEM数据。
地理空间数据云(GSCloud)旨在通过云计算、大数据等技术,解决科研人员在地理空间数据全流程(搜索、获取、分析等)中的需求,推动数据开放共享与高效利用。其服务理念为“开放共享、创新服务”,已发展成为国内最具影响力的地学数据平台之一。
在左上角的数据集中,我们可以选择想要的DEM类型,然后选择其空间位置,将其下载下来,一般这里的格式为dem或tif,如果是其他格式如img,可以在gis软件中将其转换,方便后续切片的处理。
下载好的数据直接预览可能一片漆黑,要专业的gis软件预览的效果会好一点。
二、数据切片
切片是指将原始DEM数据(如整块GeoTIFF或HGT文件)切割成多层级瓦片金字塔(Tile Pyramid),每个瓦片(Tile)覆盖特定地理范围和分辨率,按需动态加载,提升性能。
而全球30米分辨率DEM未经切片的原始数据可能高达数十GB,直接加载会耗尽内存和网络带宽。
这里,我们使用cesiumlab来进行切片(也可以用gdal+python)。CesiumLab是一个基于WebGL技术的3D地理信息系统(GIS)平台,主要用于在浏览器中呈现和分析地理空间数据。它由Cesium平台设计,旨在最大化提升三维数据可视化效率。最重要的是,其基础功能基本上免费。
这里,存储类型记得改成散列,在提交处理时,有可能会让你登录,若未登录,点击上面的网站注册一下就好了,然后第一次登录的账号密码就是注册的账号密码,默认密码是手机号后8位。
切片好的文件夹如下,其中meta是其元数据,我们可以从中获取此DEM的范围等信息。
{"bounds": {"east": 117.00018882751465,"north": 30.00014305114746,"south": 28.99970054626465,"west": 115.99974632263184},"contentType": "quantizedmesh","latLonBounds": {"east": 117.00018882751465,"north": 30.00014305114746,"south": 28.99970054626465,"west": 115.99974632263184},"maxzoom": 14,"minzoom": 0,"proj": 4326,"tiletrans": "tms","type": "terrain","ziped": false
}
三、TerrainProvider的介绍
在Cesium中,一般使用Cesium.TerrainProvider来加载地形。TerrainProvider是Cesium的一个接口,负责从服务器或本地获取地形瓦片数据。
它有几个子类,EllipsoidTerrainProvider,CesiumTerrainProvider VRTheWorldTerrainProvider,GoogleEarthEnterpriseTerrainProvider,ArcGISTiledElevationTerrainProvider。其中EllipsoidTerrainProvider是用来加载椭球模型(无真实的地形),CesiumTerrainProvider可以用来加载cesium自带的地形或者是用户的地形,VRTheWorldTerrainProvider支持从VT MAK VR-TheWorld Server服务器请求的高度地图地形图,最后两个是谷歌和ArcGIS的地形。
这里,我们主要学习用CesiumTerrainProvider加载地形。
四、CesiumTerrainProvider加载默认地形
在这个文档中,CesiumTerrainProvider不能直接构造地形对象(可能其他的版本不一样),其支持两种格式的地形
- Quantized Mesh
- Height Map
我们上面的切片地形是第一种格式的。
CesiumTerrainProvider提供了两种加载地形的方法CesiumTerrainProvider.fromIonAssetId 和 CesiumTerrainProvider.fromUrl,其中第一种可以用来加载Cesium的资源,但在这之前,记得先申请一个Ion。Cesium.Ion.defaultAccessToken =‘你的Ion’
其有两个参数,第一个是资源id,比如说地形是1,第二个是对象,其有如下参数,第一个是真实的地球光照,第二个是水的渲染,但是需要从服务器获取。
let terrainProvider1 = Cesium.CesiumTerrainProvider.fromIonAssetId(1, {requestVertexNormals: true,requestWaterMask: true,});viewer.terrainProvider = terrainProvider1;
效果如下,但是默认的地形受网络影响大,有时候加载不出来。
五、CesiumTerrainProvider加载本地地形
5.1、直接加载
本地地形则是通过CesiumTerrainProvider.fromUrl函数来加载。它的参数也和上面的类似,但是第一个路径需要是相对路径,在本地Cesium无法读取绝对路径。
注意这个路径所在文件夹terrain是打开里面一个有json文件的文件夹,这里我把terrain放在public里。
let terrainProvider = Cesium.CesiumTerrainProvider.fromUrl('/terrain',);viewer.terrainProvider = terrainProvider;
5.2、服务器代理加载
但是上面那种方法无法用于实际生产,因为我们切片的目的就是提高性能,减少页面体积,如果直接放在public里,这些地形切片会直接和前端页面一起全部发送给浏览器,相当于没有解决问题。
而且,这些地形通常是不变的静态数据,因此我们可以用一个服务器来进行发布。这里,我用nginx,也可以用python,tomcat等。
我们先去nginx官网下载一个nginx。下载好后,其目录结构如下。terrain是我们的切片地形,需要我们复制过来(terrain1是我的另一个)。
接下来,我们要对其进行代理配置,进入第一个文件夹,里面有一个nginx.conf文件,这是其配置文件。其配置内容大概如下。
- 全局块(main):设置工作进程数(worker_processes auto;匹配CPU核心数)、错误日志路径及级别(建议生产环境用warn级别)
- events块:定义连接处理模型(如use epoll;优化Linux性能)、单个进程最大连接数(高并发场景需调高worker_connections)
- http块:包含全局HTTP设置(如MIME类型、日志格式)、多个server虚拟主机配置
- server块:定义监听端口(listen 80;)、域名(server_name)、访问控制规则,内部嵌套location路径匹配规则
这里,我们要配置的是server这一块,其默认端口号为 80,这里我改成了9999。
然后就是location路径匹配规则,root里面的是根路径,如何不修改,nginx默认访问的就是这个文件夹,这里要改成我们代理的文件夹terrain。
atuoindex on在Nginx配置中用于开启目录浏览功能。当设置autoindex on时,Nginx会在访问指定目录时显示该目录下的文件列表,类似于文件管理器中的目录浏览功能,这里我们要开启才能访问我们的资源。
最后就是一些跨域请求问题,全部允许。
server {listen 9999;server_name localhost;#charset koi8-r;#access_log logs/host.access.log main;location / {root terrain;autoindex on;# 支持跨域add_header Access-Control-Allow-Origin *;add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';}
最后点击nginx.exe启动,浏览器访问http://localhost:9999/就可以访问到文件里面的内容。
最后,将这个路径填入即可。
let terrainProvider = Cesium.CesiumTerrainProvider.fromUrl('http://localhost:9999/',);viewer.terrainProvider = terrainProvider;
最后效果如下,如果大家喜欢我的文章的话,请点一个免费的赞和关注吧!