此文梳理于
cesium@1.113.0
,所以旧版本API与此版本加载方式可能存在变化,并且写的过程中对于属性,方法等等可能只列举部分,详细文档可访问官方文档。
cesium中默认地球是光滑的椭球体,但是不是说cesium默认初始状态没有地形,而是一种高度为0的特殊地形状态。我们开发时可以调用真实地理高度的地形数据,也可以利用数字高程模型(DEM)数据生成地形并加载到cesium地球上。
www地形数据是描述地球表面和地形高度的数字模型或图像。在三维可视化应用中,地形数据通常用于创建真实感强的地形表面,以便用户可以更好地了解地球表面的特征和地貌。
Cesium 中的地形系统是一种由流式瓦片数据生成地形 mesh 的技术。像图层数据一样,Cesium引擎会从一个服务器上请求流式地形数据,仅请求那些基于当前相机能看到的需要绘制的图层上的数据。
cesium中定义了地形构造函数,可以通过调用terrainProvider接口直接调用地形。得注意一个项目只有一种地形数据。terrainProvider不支持地形叠加。如果使用Cesium官方地形服务,需要ion中申请令牌或者原有令牌中添加地形资源。
Cesium中的地形图层
一、地形图层
Cesium 支持两种类型的地形,STK World Terrain 和 Small Terrain。
STK World Terrain
STK World Terrain 是高分辨率, 基于 quantized mesh 的地形。这是一种基于网格的地形,可充分利用 GL 中的 Shader 来渲染,效果相当逼真。STK World Terrain 使用了多种数据源,分别适应不同地区和不同精度时的情形。比如对于美国本土使用 National Elevation Dataset (NED) 的高程,精度 3-30 米;对于欧洲使用 EU-DEM 高程,精度 30 米;对于澳洲使用 Australia SRTM-derived 1 Second DEM 高程,精度 30 米;对于 - 60 至 60 纬度段使用 CGIAR SRTM 高程,精度 90 米;对于整个地球使用 GTOPO30,精度 1000 米。STK World Terrain 地形是怎样生成的是不公开的,如需应用于封闭的局域网时,则需购买 AGI 的 STK terrain server。但是 AGI 提供了一个 webapi 可供因特网上调用,并提供了这种地形的格式细节。就是上面的 url
Small Terrain
Small Terrain 是中等高分辨率基于 heightmap 的地形,渲染出的地形效果不如 quantized mesh 的地形,但也基本能接受。 可以由 DEM 数据生成这种规范的. terrain 文件。
二、Cesium的地形加载方法
Cesium支持流式的、可视化的全球高程投影地形地势、水形数据,包括海洋、湖泊、河流、山峰、峡谷和其他能够被三维展示出来的地形数据。在Cesium中,可以使用Terrain
以及TerrainProvider
类的子类来加载地形数据,通过把某个子类实例化的TerrainProvider
赋值给Viewer.terrainProvider
来实现地形数据的显示。
Terrain
new Cesium.Terrain(terrainProviderPromise)
用于管理地形提供者的异步操作。可以看到它需要接收一个terrainProvider
Promise
对象。(后边我们可以看到如果直接使用terrainProvider相关类进行地形加载时,使用了await等等)
新版API中对于默认地形和自定义地形的添加也可以使用以下方法:
默认地形
Cesium.Terrain.fromWorldTerrain(options)
如果我们想要加载一个Cesium的默认地形,可以使用Terrain的静态方法。它创建一个 Cesium World Terrain 的地形实例,返回的对象是一个用于 CesiumTerrainProvider 的异步辅助对象。
// Create Cesium World Terrain with default settings
const viewer = new Cesium.Viewer("cesiumContainer", {
terrain: Cesium.Terrain.fromWorldTerrain()// 地形服务
});
// Create Cesium World Terrain with water and normals.
const viewer1 = new Cesium.Viewer("cesiumContainer", {
terrain: Cesium.Terrain.fromWorldTerrain({ // 地形服务
requestWaterMask: true, //添加地形光照
requestVertexNormals: true // 添加水面波浪效果
});
});
// Handle loading events
const terrain = Cesium.Terrain.fromWorldTerrain(); // 地形服务
scene.setTerrain(terrain);
terrain.readyEvent.addEventListener(provider => {
scene.globe.enableLighting = true;
terrain.provider.errorEvent.addEventListener(error => {
alert(`Encountered an error while loading terrain tiles! ${error}`);
});
});
terrain.errorEvent.addEventListener(error => {
alert(`Encountered an error while creating terrain! ${error}`);
});
自定义地形服务
Examples
// 创建一个地形
const viewer = new Cesium.Viewer("cesiumContainer", {
terrain: new Cesium.Terrain(Cesium.CesiumTerrainProvider.fromUrl("https://myTestTerrain.com"));
});
// 处理加载事件
const terrain = new Cesium.Terrain(Cesium.CesiumTerrainProvider.fromUrl("https://myTestTerrain.com"));
scene.setTerrain(terrain);
terrain.readyEvent.addEventListener(provider => {
scene.globe.enableLighting = true;
terrain.provider.errorEvent.addEventListener(error => {
alert(`Encountered an error while loading terrain tiles! ${error}`);
});
});
terrain.errorEvent.addEventListener(error => {
alert(`Encountered an error while creating terrain! ${error}`);
});
TerrainProvider
new Cesium.TerrainProvider()
为椭球体的表面提供地形或其他几何数据。表面几何数据按照切片方案(TilingScheme)组织成金字塔形的瓦片结构。这个类型描述了一个接口,不应直接实例化。TerrainProvider有多个子类,每个子类都支持不同类型的地形数据源或渲染技术。
TerrainProvider类是Cesium中用于加载地形数据的基本类。它定义了一组接口,用于请求和获取地形高度数据以及其他地形信息。
Members
availability
: 获取一个可用于确定该提供者地形的可用性的对象,例如在特定点和矩形区域内。如果没有可用的可用性信息,该属性可能未定义。credit
: 获取在使用TerrainProvider时显示的标识信息。通常用于标识地形数据的来源。errorEvent
:获取地形提供程序遇到异步错误时引发的事件。通过订阅事件,您将收到错误通知,并可能去修复它。事件监听器将接收到一个TileProviderError
实例.hasVertexNormals
: 指示该TerrainProvider是否提供每个顶点的法向量(垂直于表面)hasWaterMask
: 指示该是否提供水体区域掩码,即指示哪些区域是水体的二进制图像。获取一个值,指示TerrainProvider是否包含水域掩码(water mask)。水域掩码指示地球上哪些区域是水域而不是陆地,因此可以将其呈现为具有动态波浪的反射表面。tilingScheme
: 获取提供者使用的切片方案(tiling scheme)。
Methods
getLevelMaximumGeometricError(level)
:获取指定层次级别的最大几何误差getTileDataAvailable(x, y, level)
:获取瓦片是否可用loadTileDataAvailability(x, y, level)
:确保我们加载切片的可用性数据requestTileGeometry(x, y, level, throttleRequests)
:请求一个指定层次级别(x, y, level)的瓦片的几何数据
TerrainProvider
在Cesium中,可以使用TerrainProvider类的子类来加载地形数据,通过把某个子类实例化的TerrainProvider赋值给Viewer.terrainProvider来实现地形数据的显示。
1. CesiumTerrainProvider
new Cesium.CesiumTerrainProvider(options)
要构建一个 CesiumTerrainProvider
,请调用 CesiumTerrainProvider.fromIonAssetId
或 CesiumTerrainProvider.fromUrl
方法。不要直接调用构造函数。
CesiumTerrainProvider是Cesium默认的地形提供者。在Cesium中常用的TerrainProvider子类主要是CesiumTerrainProvider
类。
CesiumTerrainProvider使用STK World Terrain数据源加载高程数据,支持地形纹理贴图。数据源提供全球30米分辨率的高程数据和地表覆盖材料图层。支持动态地形数据获取、卸载和缓存,并可以在运行时更改LOD级别和地形贴图。其适用于需要高精度和高性能地形渲染的应用程序。
Options
名字 | 类型 | 属性 | 默认值 | 描述 |
---|---|---|---|---|
requestVertexNormals | boolean | 可选 | 假 | 指示客户端是否应从服务器请求其他照明信息的标志,如果可用,则以每个顶点法线的形式提供。 |
requestWaterMask | boolean | 可选 | 假 | 指示客户端是否应从服务器请求每个磁贴遮罩(如果可用)的标志。 |
requestMetadata | boolean | 可选 | 真 | 指示客户端是否应从服务器请求每个磁贴元数据(如果可用)的标志。 |
ellipsoid | Ellipsoid | 可选 | 椭球体。如果未指定,则使用 WGS84 椭球体。 | |
credit | Credit|string | 可选 | 数据源的信用额度,显示在画布上。 |
Members
requestVertexNormals
:布尔类型,表示是否请求顶点法线信息requestWaterMask
:一个布尔类型,表示是否请求水面遮罩信息hasVertexNormals
:只读布尔值,表示该地形提供器是否包含顶点法线信息hasWaterMask
:只读布尔值,表示该地形提供器是否包含水面遮罩信息errorEvent
:Event类型,当地形数据请求错误时触发availability
:定义地形数据可用性的TimeIntervalCollection对象
Methods
Cesium.CesiumTerrainProvider.fromIonAssetId(assetId, options)
:从 Cesium ion的assetId创建TerrainProvider
,该 TerrainProvider以 Cesium地形格式来访问地形数据。Cesium.CesiumTerrainProvider.fromUrl(url, options)
:通过terrain 服务器的 URL创建一个TerrainProvider
,用于访问 Cesium地形格式的地形数据。requestTileGeometry(x, y, level, request)
:请求给定坐标和级别的地形几何数据。该方法返回Promise对象,可以在其完成时获得地形几何数据getLevelMaximumGeometricError(level)
:获取指定级别的最大地形几何误差getTileDataAvailable(x, y, level)
:查询给定坐标和级别的地形数据是否可用loadTileDataAvailability(x, y, level)
:确保我们加载切片的可用性数据
Examples
新版api取消了url参数,采用fromUrl
或者fromIonAsstld
来调用,详见常用方法。我们可以采取初始化配置以及调用方法两种方式来创建地形图层。
// fromIonAssetId使用初始化配置
try {
const viewer = new Cesium.Viewer("cesiumContainer", {
terrainProvider: await Cesium.CesiumTerrainProvider.fromIonAssetId(3956, {
requestVertexNormals: true
})
});
} catch (error) {
console.log(error);
}
// fromIonAssetId使用方法模式加载
var viewer = new Cesium.Viewer("cesiumContainer");
const terrainProvider = await Cesium.CesiumTerrainProvider.fromIonAssetId(3956, {
requestVertexNormals: true
})
viewer.terrainProvider = terrainProvider;
// fromUrl使用初始化配置
var url = 'http://example.com/terrainData'
try {
const viewer = new Cesium.Viewer("cesiumContainer", {
terrainProvider: await Cesium.CesiumTerrainProvider.fromUrl(
url, {
requestVertexNormals: true
})
});
} catch (error) {
console.log(error);
}
// fromUrl使用方法模式加载
const terrainProvider = await Cesium.CesiumTerrainProvider.fromUrl('http://xxx/tilesets/china', {
requestVertexNormals: true
})
viewer.terrainProvider = terrainProvider;
注意:如果我们加载Cesium默认地形图层,其实还可以使用createWorldTerrainAsync方法,他的返回创建的CesiumTerrainProvider的promise,两个参数可选。
try {
const viewer1 = new Cesium.Viewer("cesiumContainer", {
terrainProvider: await Cesium.createWorldTerrainAsync({
requestWaterMask: true, // 照明,可选
requestVertexNormals: true // 水面遮罩,可选
});
});
} catch (error) {
console.log(error);
}
2. GoogleEarthEnterpriseTerrainProvider
new Cesium.GoogleEarthEnterpriseTerrainProvider(options)
要构建一个 GoogleEarthEnterpriseTerrainProvider
,请调用 GoogleEarthEnterpriseTerrainProvider.fromMetadata
方法。不要直接调用构造函数。
加载Google Earth Enterprise服务器上的高程和图像数据。
Options
Name | Type | Attributes | Description |
---|---|---|---|
ellipsoid | Ellipsoid | <optional> | 椭球体。如果未指定,将使用WGS84椭球体。 |
credit | Credit | string | <optional> | 数据源的标识,将显示在画布上。 |
Examples
const geeMetadata = await GoogleEarthEnterpriseMetadata.fromUrl("http://www.example.com");
const gee = Cesium.GoogleEarthEnterpriseTerrainProvider.fromMetadata(geeMetadata);
3. CustomHeightmapTerrainProvider
new Cesium.CustomHeightmapTerrainProvider(options)
一个简单的 TerrainProvider,通过回调函数获取高度值。它可以用于程序生成的地形或用于加载自定义高度图数据,而无需创建 TerrainProvider 的子类。它有一些限制,例如没有水域蒙版、没有顶点法线和可用性,因此对于这些更复杂的用例,最好使用一个完整的 TerrainProvider 子类来实现。
Cesium中用于自定义高程数据的地形提供器,它允许开发人员使用程序生成或者从其他来源导入高程数据来创建自定义的地形。
CustomHeightmapTerrainProvider继承自HeightmapTerrainProvider类,因此具有HeightmapTerrainProvider的所有功能,如同步和异步请求高程瓦片、获取最大几何误差等。此外,CustomHeightmapTerrainProvider还实现了requestHeightmapTerrain方法。这个方法应该由子类实现,以便返回自定义高程数据。
在自定义高程数据时,需要确定数据的分辨率、范围和格式。可以使用数字高程模型(DEM)文件、图像文件、数据库或其他格式存储高程数据,并将其转换为CustomHeightmapTerrainProvider可以处理的格式。
使用CustomHeightmapTerrainProvider可以实现各种自定义地形效果,例如在虚拟环境中加载真实世界的高程数据、制作类似Minecraft的方块式地形等
CustomHeightmapTerrainProvider类的常用属性和方法与CesiumTerrainProvider相似,这里不再赘述,详细内容请参考官方文档
Options
Name | Type | Description |
---|---|---|
callback | CustomHeightmapTerrainProvider.GeometryCallback | 请求瓦片几何数据的回调函数。 |
width | number | 每个高度图瓦片的列数。 |
height | number | 每个高度图瓦片的行数。 |
tilingScheme | TilingScheme | 可选参数,指定椭球面如何划分为瓦片。如果未提供此参数,则使用GeographicTilingScheme 。 |
ellipsoid | Ellipsoid | 可选参数,指定椭球体。如果指定了tilingScheme参数,则忽略此参数,并使用tiling scheme的椭球体。如果两个参数都未指定,则使用WGS84椭球体。 |
credit | Credit | string | 可选参数,用于数据源的标识,会显示在画布上。 |
Example
const viewer = new Cesium.Viewer("cesiumContainer", {
terrainProvider: new Cesium.CustomHeightmapTerrainProvider({
width: 32,
height: 32,
callback: function (x, y, level) {
return new Float32Array(32 * 32); // all zeros
},
}),
});
4. ArcGISTiledElevationTerrainProvider
new Cesium.ArcGISTiledElevationTerrainProvider(options)
使用ArcGIS Server提供的切片瓦片服务作为高程数据的地形。它可以访问由ArcGIS Server发布的预先生成的高程切片,并支持动态获取和缓存切片。
要构建一个 CesiumTerrainProvider
,请调用 ArcGISTiledElevationTerrainProvider.fromUrl
方法。不要直接调用构造函数。
Options
Name | Type | Attributes | Default | Description |
---|---|---|---|---|
requestVertexNormals | boolean | <optional> | false | 一个指示客户端是否应该从服务器请求额外的光照信息的标志,如果可用的话,以每个顶点法线的形式。 |
requestWaterMask | boolean | <optional> | false | 一个指示客户端是否应该从服务器请求每个瓦片的水域蒙版(水面遮罩)的标志,如果可用的话。 |
requestMetadata | boolean | <optional> | true | 一个指示客户端是否应该从服务器请求每个瓦片的元数据的标志,如果可用的话。 |
ellipsoid | Ellipsoid | <optional> | 椭球体。如果未指定,则使用 WGS84 椭球体。 | |
credit | Credit | string | <optional> | 一个显示在画布上的数据源标识。 |
Members
errorEvent
:一个事件,当地形数据请求错误时触发credit
:一个Credit对象,描述了数据源和/或版权信息availability
:定义地形数据可用性的TimeIntervalCollection对象
Methods
Cesium.ArcGISTiledElevationTerrainProvider.fromUrl(url, options)
:创建一个 TerrainProvider,通过细分从 ArcGIS ImageService 的高度瓦片中获取的高度图来生成地形几何数据。Name Type Description url
Resource | String | Promise.<Resource> | Promise.<String> ArcGIS ImageServer 服务的 URL。 options
ArcGISTiledElevationTerrainProvider.ConstructorOptions 可选参数。可以是一个 URL 或一个描述初始化选项的对象。 Name Type Attributes Description options.token
string <optional> 连接到服务时使用的授权令牌。 options.ellipsoid
Ellipsoid <optional> 椭球体。如果指定了切片方案(tilingScheme),则忽略此参数,并使用切片方案的椭球体。如果两个参数都未指定,则使用 WGS84 椭球体。 requestTileGeometry(x, y, level, request)
:请求给定坐标和级别的地形几何数据。该方法返回Promise对象,可以在其完成时获得地形几何数据getLevelMaximumGeometricError(level)
:获取指定级别的最大地形几何误差getTileDataAvailable(x, y, level)
:查询给定坐标和级别的地形数据是否可用
Examples
const terrainProvider = await Cesium.ArcGISTiledElevationTerrainProvider.fromUrl("https://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer", {
token: "KED1aF_I4UzXOHy3BnhwyBHU4l5oY6rO6walkmHoYqGp4XyIWUd5YZUC1ZrLAzvV40pR6gBXQayh0eFA8m6vPg.."
});
viewer.terrainProvider = terrainProvider;
5. VRTheWorldTerrainProvider
new Cesium.VRTheWorldTerrainProvider(options)
加载VR-TheWorld的高程和图像数据。
要构建一个 VRTheWorldTerrainProvider
,请调用 VRTheWorldTerrainProvider.fromUrl
方法。不要直接调用构造函数。
Options
Name | Type | Attributes | Description |
---|---|---|---|
ellipsoid | Ellipsoid | <optional> | 椭球体。如果未指定,则使用 WGS84 椭球体。 |
credit | Credit | string | <optional> | 数据源的标识,将显示在画布上。 |
Methods
Cesium.VRTheWorldTerrainProvider.fromUrl(url, options)
:创建一个 TerrainProvider,通过细分从 VT MÄK VR-TheWorld 服务器获取的高度图来生成地形几何数据。
Name | Type | Description |
---|---|---|
url | Resource | String | VR-TheWorld TileMap 的 URL。 |
options | VRTheWorldTerrainProvider.ConstructorOptions | VRTheWorldTerrainProvider的构造参数。见上面Options; |
Examples
const terrainProvider = await Cesium.VRTheWorldTerrainProvider.fromUrl(
"https://www.vr-theworld.com/vr-theworld/tiles1.0.0/73/"
);
viewer.terrainProvider = terrainProvider;
6. EllipsoidTerrainProvider
new Cesium.EllipsoidTerrainProvider(options)
一个非常简单的 TerrainProvider,通过对椭球体表面进行细分来生成几何图形,使用椭球体作为地形模型,不提供任何高程数据。
EllipsoidTerrainProvider是Cesium中的一个内置地形提供器,它提供了一个基于椭球体的模型来呈现地球表面的近似几何形状。与其他地形提供器不同的是,EllipsoidTerrainProvider并不依赖于实际的地形数据,而是根据其定义的椭球体模型生成地球表面的高程网格。
EllipsoidTerrainProvider继承自TerrainProvider类,具有TerrainProvider的所有功能,例如异步加载地形数据、请求地形数据等
EllipsoidTerrainProvider适用于需要快速渲染地球表面的应用场景,例如在展示全球范围的卫星图像或者天气数据时,可以通过EllipsoidTerrainProvider快速生成一个近似的地球表面几何模型,并将数据贴合到这个模型上,从而实现快速、流畅的地球表面展示效果。
Options
- tilingScheme:切片方案,用于指定如何将椭球体表面划分为瓦片。如果未提供该参数,将使用地理切片方案(GeographicTilingScheme)。
- ellipsoid: 椭球体。如果指定了切片方案(tilingScheme),则忽略此参数,并使用切片方案的椭球体。如果两个参数都未指定,则使用 WGS84 椭球体。
Members
tilingScheme
:一个TileTilingScheme对象,描述了该地形提供器使用的切片方案。ellipsoid
:描述地球近似几何形状的Ellipsoid对象
Methods
getLevelMaximumGeometricError(level)
:获取指定级别的最大地形几何误差requestTileGeometry(x, y, level, request)
:请求给定坐标和级别的地形几何数据。该方法返回Promise对象,可以在其完成时获得地形几何数据