Cesium学习笔记——dem/tif地形的分块与加载

前言

在Cesium的学习中,学会读文档十分重要!!!在这里附上Cesium中英文文档1.117

在Cesium项目中,在平坦坦地球中加入三维地形不仅可以增强真实感与可视化效果,还可以​​提升用户体验与交互性,今天,我们来学习一下如何将dem/tif格式的地形数据进行分块和加载。

一、dem/tif格式数据下载

DEM(​​Digital Elevation Model​​)是描述地表高程信息的数字模型,通过规则网格或点云数据记录地形起伏,广泛应用于地理信息系统(GIS)、遥感、三维可视化(如Cesium)等领域。

1.1、DEM常见数据格式

  1. GeoTIFF(.tif):地理参考的栅格格式,高程值存储为像素值,元数据(坐标、投影)嵌入文件头。其兼容性强,QGIS、ArcGIS、Python GDAL均支持。 如NASA SRTM数据(30米分辨率)常以GeoTIFF分发。
  2. ASCII Grid(.asc):纯文本格式,以行列数、网格尺寸、高程值矩阵定义地形。
  3. HGT(.hgt):SRTM任务专用格式,每文件覆盖1°×1°区域。
  4. DEM(.dem):USGS标准格式,含头文件(坐标、分辨率)和二进制高程数据。
  5. 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不能直接构造地形对象(可能其他的版本不一样),其支持两种格式的地形

我们上面的切片地形是第一种格式的。

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;

最后效果如下,如果大家喜欢我的文章的话,请点一个免费的赞和关注吧!

相关推荐
一朵好运莲几秒前
超详细mac上用nvm安装node环境,配置npm
前端·macos·npm
superior tigre2 分钟前
C++学习:六个月从基础到就业——内存管理:自定义内存管理(上篇)
c++·学习
大樊子9 分钟前
JavaScript 中的单例模式
开发语言·javascript·单例模式
天天扭码10 分钟前
一分钟解决 | 高频面试算法题——最小覆盖子串
前端·算法·面试
白飞飞11 分钟前
原生小程序工程化指北:从混乱到规范的进化之路
前端·vue.js·微信小程序
加油乐14 分钟前
JS判断当前时间是否在指定时段内(支持多时段使用)
前端·javascript
Epat18 分钟前
关于一个小菜鸡是如何通过自定义 postcss 插件解决 color-mix 兼容问题的
前端
小小小小宇19 分钟前
webComponent实现一个拖拽组件
前端
满怀101519 分钟前
【Python核心库实战指南】从数据处理到Web开发
开发语言·前端·python
PBitW27 分钟前
工作中突然发现零宽字符串的作用了!
前端·javascript·vue.js