cesium.js入门基础教程三 (地形)
地形简介
Cesium默认是不包含地形的,准确的说应该是Cesium默认加载的地形是没有起伏效果的,如下图所示,在包含山脉的地区是看不到地形起伏的:
默认使用的地形为 "WGS84 Ellipsoid":
地形提供者 TerrainProvider
与影像类似,在Cesium
中包含了一些地形提供者TerrainProvider
用于加载各类地形,举例如下,具体情况可参阅官方文档:
ArcGISTiledElevationTerrainProvider
:由ArcGIS提供的地形服务;CesiumTerrainProvider
:由Cesium官方提供的地形服务;CustomHeightmapTerrainProvider
:自定义高程的地形服务;EllipsoidTerrainProvider
:高程为 0 的地形服务,如果初始化时不指定地形,那么默认的就是使用的该地形服务;GoogleEarthEnterpriseTerrainProvider
:由GoogleEarth提供的地形服务;VRTheWorldTerrainProvider
:由VRTheWorld提供的地形服务。
加载地形的方法
与加载影像图层十分类似,加载地形的方法也有两种:
- 在初始化
viewer
的时候添加; - 通过
viewer.terrainProvider
赋值添加
注意,一个视图下只能加载一个地形;
而影像图层是可以加载多个的,同一视图下可以叠加多个影像;
另外,从语义上来说,每一个影像图层都是一个imageryLayer
,所有的imageryLayer
都是通过ImageryLayerCollection
来管理,添加一个影像图层用的方法是addImageryProvider
,注意add
而对于地形来说,是直接给viewer.terrainProvider
赋值的
初始化Viewer时添加地形
在初始化Viewer
时在第二个参数Viewer.ConstructorOptions
中添加terrainProvider
属性并提供一个TerrainProvider
对象:
const viewer = new Cesium.Viewer("cesiumContainer", {
terrainProvider: new Cesium.ArcGISTiledElevationTerrainProvider({
url: 'https://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer',
})
})
通过viewer.terrainProvider赋值添加
通过viewer.terrainProvider
赋值添加的代码如下:
const viewer = new Cesium.Viewer("cesiumContainer")
const ArcGisTerrainProvider = new Cesium.ArcGISTiledElevationTerrainProvider({
url: 'https://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer',
})
viewer.terrainProvider = ArcGisTerrainProvider
地形提供者示例
与影像类似,在Cesium中提供了一些地形提供者TerrainProvider用于加载各类地形,列举如下,具体情况请参阅官方文档:
ArcGISTiledElevationTerrainProvider
:由ArcGIS提供的地形服务;CesiumTerrainProvider
:由Cesium官方提供的地形服务;CustomHeightmapTerrainProvider
:自定义高程的地形服务;EllipsoidTerrainProvider
:高程为 0 的地形服务,如果初始化时不指定地形,那么默认的就是使用的该地形服务;GoogleEarthEnterpriseTerrainProvider
:由GoogleEarth提供的地形服务;VRTheWorldTerrainProvider
:由VRTheWorld提供的地形服务。
ArcGISTiledElevationTerrainProvider
加载Arcgis地形服务的代码如下:
const viewer = new Cesium.Viewer("cesiumContainer")
const terrainProvider = new Cesium.ArcGISTiledElevationTerrainProvider({
url: 'https://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer',
})
viewer.terrainProvider = terrainProvider
加载后的效果如下:
CesiumTerrainProvider
CesiumTerrainProvider
用于加载自行发布的地形服务或其他地形服务商发布的地形服务
自行发布的地形服务
加载自行发布的地形服务代码如下,其中https://localhost/terrain
为地形服务的URL
:
const viewer = new Cesium.Viewer("cesiumContainer")
viewer.terrainProvider = new Cesium.CesiumTerrainProvider({
url: "https://localhost/terrain"
})
火星科技地形 版权归火星科技所有,在此仅作为学习交流所用,侵删。
加载火星科技地形的代码如下:
const viewer = new Cesium.Viewer("cesiumContainer")
viewer.terrainProvider = new Cesium.CesiumTerrainProvider({
url: 'http://data.marsgis.cn/terrain',
})
加载后的效果如下:
maptiler地形
加载maptiler地形的伪代码如下,需要访问maptiler官网注册账号获取key:
const viewer = new Cesium.Viewer("cesiumContainer")
const maptilerKey = 'xxx'
viewer.terrainProvider = new Cesium.CesiumTerrainProvider({
url: `https://api.maptiler.com/tiles/terrain-quantized-mesh/?key=${maptilerKey}`,
requestVertexNormals: true
})
加载后的效果如下:
CustomHeightmapTerrainProvider
加载自定义高程地形的代码如下,通过回调函数callback
获取高程,这个TerrainProvider
用的很少:
const viewer = new Cesium.Viewer("cesiumContainer")
let width = 64
let height = 64
viewer.terrainProvider = new Cesium.CustomHeightmapTerrainProvider({
callback: (x, y, level) => {
let buffer = new Float32Array(width * height)
for (let yy = 0; yy < height; yy++) {
for (let xx = 0; xx < width; xx++) {
let v = (y + yy / (height - 1)) / Math.pow(2, level)
let heightValue = 8000 * (Math.sin(4000 * v) * 0.5 + 0.5)
let index = yy * width + xx
buffer[index] = heightValue
}
}
return buffer
},
width: width,
height: height,
})
EllipsoidTerrainProvider
EllipsoidTerrainProvider
是高程为 0 的地形,若初始化时不指定地形,那么默认的就是使用的该地形服务,加载EllipsoidTerrainProvider
的代码如下:
const viewer = new Cesium.Viewer("cesiumContainer")
viewer.terrainProvider = new Cesium.EllipsoidTerrainProvider()
Cesium ion 地形
加载Cesium ion提供的地形代码如下:
viwer.terrainProvider = Cesium.createWorldTerrain();
加载后的效果,能看到明显的起伏:
使用参数requestWaterMask还可以为虚拟地球的海面添加流动效果,代码如下:
const viewer = new Cesium.Viewer("cesiumContainer")
const terrainProvider = Cesium.createWorldTerrain({
requestWaterMask: true, // 请求水体效果所需要的海岸线数据
})
viewer.terrainProvider = terrainProvider
地形等高线
开启地形等高线后的效果如下:
开启地形等高线的代码如下:
/**
* @description:
* @param {*} width 等高线的线宽,单位px
* @param {*} spacing 等高线的高度间隔,单位m
* @param {*} color 等高线的颜色,Cesium.Color
* @return {*}
*/
function contourLine(width, spacing, color) {
let material = Cesium.Material.fromType("ElevationContour")
material.uniforms.width = width
material.uniforms.spacing = spacing
material.uniforms.color = color
viewer.scene.globe.material = material
}
// 等高线的线宽为2px,高度间隔为100m,颜色为红色
contourLine(2.0, 100, Cesium.Color.RED)