Skip to content

地形是三维场景中的重要三维效果,能看到山峰的高低起伏效果,是三维场景的"骨骼", 如果想要看到真实感,地形数据(DEM)不可或缺。

Mars3D 支持流式的、可视化的全球高程投影地形地势、水形数据,包括海洋、湖泊、河流、山峰、峡谷和其他能够被三维展示出来的且效果比二维好的地形数据。像图层数据一样, Mars3D 引擎会从一个服务器上请求流式地形数据,仅请求那些基于当前相机能看到的需要绘制的图层上的数据。

目前一个三维场景只支持一个地形服务图层。

image

1. DEM 地形数据介绍

DEM 数据就是 数字高程模型,就是描述每个点位的高程数据而已,没有其他附加信息,更不会包含影像图,单独展示是看不出什么名堂的。DEM 数据在 ArcGIS 中打开只能看到是灰度图。

1.1.terrain 格式介绍

通常地形是*.tif格式,我们平台中需要处理转换为terrain瓦片格式才能使用。 terrain 地形也是瓦片地图金字塔模型结构组成。 image

terrain 瓦片的根目录有个layer.json的地形服务入口文件,来描述地形服务的基本信息和结构,如:http://data.mars3d.cn/terrain/layer.json

terrain 有 2 种格式:

  • Heightmap-1.0 :是 Cesium 早期使用的地形切片格式,每个瓦片存储 65*65 个高度值,通过 Cesium API 进行解析、构网、渲染、查询等。优点是切片简单,存储小,缺点是精度不高等。heightmap 官方文档

  • Quantized-Math-1.0 : 是 Cesium 现在及未来使用的地形切片格式,会慢慢的替代 Heightmap-1.0 格式,因此,我们应该优先掌握该格式。quantized-mesh 官方文档

tif 转 terrain: 地形数据处理教程

2. 加载地形

地形数据集是巨大的,通常都是 GB 或者 TB 级别。在普通 3D 引擎中,使用底层图形 API 去高效实现地形数据的可视化需要做很多事情。幸好 Mars3D 已经完成了这个体力活,而我们只需要写几行代码。地形数据单独是没法展示出来看的,只是一堆高程数据而已。结合影像图来展示,效果最佳。

2.1. 快速开始(初始化 new Map 时传入)

在构造 Map 时传入terrain 参数说明

js
var map = new mars3d.Map('mars3dContainer', {
  terrain: {
    //type:'xyz',//默认未传入时代表 'xyz'
    url: 'http://data.mars3d.cn/terrain',
    show: true
  }
});

//关闭或开启地形,只需要修改下面属性
map.hasTerrain = false;
var map = new mars3d.Map('mars3dContainer', {
  terrain: {
    //type:'xyz',//默认未传入时代表 'xyz'
    url: 'http://data.mars3d.cn/terrain',
    show: true
  }
});

//关闭或开启地形,只需要修改下面属性
map.hasTerrain = false;

2.2. 通过修改 map.terrainProvider 属性控制地形。

在创建完 map 后,通过 mars3d.LayerUtil.createTerrainProvider 创建地形服务对象,并赋值给 map.terrainProvider

js
//设置新的地形服务
map.terrainProvider = mars3d.LayerUtil.createTerrainProvider({
  type: 'arcgis',
  url: 'https://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer'
});
//设置新的地形服务
map.terrainProvider = mars3d.LayerUtil.createTerrainProvider({
  type: 'arcgis',
  url: 'https://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer'
});

3. 深度检测

默认是可以看到地下的物体,如果需要看不到地形下面的矢量对象或模型,那么可以开启深度检测来达到需求。

javascript
// Enable depth testing so things behind the terrain disappear.
viewer.scene.globe.depthTestAgainstTerrain = true;
// Enable depth testing so things behind the terrain disappear.
viewer.scene.globe.depthTestAgainstTerrain = true;