> 文章列表 > Cesium 实战-最新版(1.104.0)通过异步方式初始化地球,加载影像以及高程图层

Cesium 实战-最新版(1.104.0)通过异步方式初始化地球,加载影像以及高程图层

Cesium 实战-最新版(1.104.0)通过异步方式初始化地球,加载影像以及高程图层

Cesium 实战-最新版(1.104.0)通过异步方式初始化地球,加载影像以及高程图层

    • 遇到问题
    • 初始化底图
    • 初始化高程(监听载入完成事件,开启关闭高程)
    • 初始化 3dtile
    • 在线示例

Cesium 最新版(1.104.0)变动还是挺大的,尤其是涉及图层的渲染加载,差不多是重构级别的变化。

Cesium 1.104.0 开始支持并建议使用异步的方式加载渲染图层。


以下是 官方更新 主要说明:

大意是:为了更好的异步流和图层渲染错误处理,自 1.104.0 开始,readyPromise 模式被弃用,并且从 1.107.0 开始会移除此方法

因此,为了体验新版功能,最好还是及时更新影像、高程等初始化方法。

Cesium 实战-最新版(1.104.0)通过异步方式初始化地球,加载影像以及高程图层
受影响的主要是图层相关、地形相关、3dtile 相关,如下:

Cesium 实战-最新版(1.104.0)通过异步方式初始化地球,加载影像以及高程图层


本文主要介绍一下,新版 Cesium(1.104.0)如何加载影像图、高程数据以及 3dtile 数据。

本文包括:遇到问题、初始化底图、初始化高程(监听载入完成事件,切换高程)、初始化 3dtile 四部分。

提示:想快速了解新版如何 加载图层和高程,可以直接跳转至 初始化底图和初始化高程 查看!


遇到问题

看完官方更新之后,想着直接按照官方示例来修改就行,结果也是遇到一些问题。

由于作者使用的是 TMS 资源,因此之前是使用 new Cesium.TileMapServiceImageryProvider() 的方式来加载图层。

但是现在官方建议是使用 Cesium.TileMapServiceImageryProvider.fromUrl 来加载图层。

Cesium 实战-最新版(1.104.0)通过异步方式初始化地球,加载影像以及高程图层

1. 第一个问题:初始化地图时,不能直接使用 imageryProvider 加载图层。

作者本来以为直接替换就行,结果可想而知:图层不会进行渲染!

Cesium 实战-最新版(1.104.0)通过异步方式初始化地球,加载影像以及高程图层

Cesium 实战-最新版(1.104.0)通过异步方式初始化地球,加载影像以及高程图层

原因也比较简单,因为 imageryProvider 需要的是 ImageryProvider 对象,

TileMapServiceImageryProvider.fromUrl 创建的是 Promise.<TileMapServiceImageryProvider> 对象,因此图层不会渲染。

Cesium 实战-最新版(1.104.0)通过异步方式初始化地球,加载影像以及高程图层
Cesium 实战-最新版(1.104.0)通过异步方式初始化地球,加载影像以及高程图层

2. 第二个问题:跟图层一样,terrainProvider 直接使用 CesiumTerrainProvider.fromUrl 替换也会出问题。

地形高程不会加载,并且地图会变黑!

原因同加载图层,这里不过多解释。

Cesium 实战-最新版(1.104.0)通过异步方式初始化地球,加载影像以及高程图层

Cesium 实战-最新版(1.104.0)通过异步方式初始化地球,加载影像以及高程图层

Cesium 实战-最新版(1.104.0)通过异步方式初始化地球,加载影像以及高程图层

还有个需要注意的地方,如果想做版本(1.104.0之前版本)兼容,terrainProviderterrain 属性只能设置一个,否则会提示错误!

Cesium 实战-最新版(1.104.0)通过异步方式初始化地球,加载影像以及高程图层

3. 第三个问题:设置开启关闭地形高程问题。

按照以前的方式:

const terrainProvider = viewer.terrainProvider;
// 关闭高程
viewer.terrainProvider = new Cesium.EllipsoidTerrainProvider();
// 开启高程
viewer.terrainProvider = terrainProvider ;

新版环境下,关闭地形比较容易,但是开启有变化,几乎把错都试遍了,比如(以下均不可取,新版方法见下文):

const url = '地形服务地址'// 创建地形高程对象
const terrain = new Cesium.Terrain(Cesium.CesiumTerrainProvider.fromUrl(url));
const terrainProvider= new Cesium.CesiumTerrainProvider(url));viewer.terrain = terrainProvider;viewer.terrain = terrain;viewer.terrainProvider = terrain;viewer.terrainProvider = terrain.provider;

初始化底图

Cesium 提供了使用 Promise.<TileMapServiceImageryProvider> 加载图层对象的方法,通过此方法可以直接加载图层。

核心代码(关键是 Cesium.ImageryLayer.fromProviderAsync):

const url = '图层地址'const baseLayer = new Cesium.ImageryLayer.fromProviderAsync(Cesium.TileMapServiceImageryProvider.fromUrl(url,{// 最小级别minimumLevel: 1,// 最大级别maximumLevel: 18,
}))
// 设置监听事件
baseLayer.readyEvent.addEventListener(provider => {console.log(`已经创建 provider! `);provider.errorEvent.addEventListener(error => {console.log(`加载瓦片出错!原因:`, error);});
});
const viewer = new Cesium.Viewer("cesiumContainer", {// Use OpenStreetMapsbaseLayer: baseLayer,// Show Columbus View map with Web Mercator projectionmapProjection: new Cesium.WebMercatorProjection()});

除此之外,也可以通过设置异步方法(async function)来创建 imageryProvider 对象,提供给 viewer 进行初始化。

Cesium 实战-最新版(1.104.0)通过异步方式初始化地球,加载影像以及高程图层


初始化高程(监听载入完成事件,开启关闭高程)

1. 初始化地形高程的方式跟图层比较类似。

核心代码(关键是 new Cesium.Terrain):

const url = '地形服务地址'const terrain = new Cesium.Terrain(Cesium.CesiumTerrainProvider.fromUrl(url));terrain.readyEvent.addEventListener(provider => {console.log(`已经创建 provider! `);
});const viewer = new Cesium.Viewer("cesiumContainer", {// Use Cesium World Terrainterrain: terrain,// Show Columbus View map with Web Mercator projectionmapProjection: new Cesium.WebMercatorProjection()
});

2. 关于切换地形高程(开启或关闭地形高程)。

由于地形高程加载改为异步,不能再像以前那样直接替换就行。

作者尝试了多次之后,才偶然想到解决办法,之前也是属于走弯路。

核心代码(关键是 terrain.readyEvent):

const url = '地形服务地址'// 创建地形高程对象
const terrain = new Cesium.Terrain(Cesium.CesiumTerrainProvider.fromUrl(url));// 定义 terrainProvider
let terrainProvider;// 创建平面地形
const ellipsoidTerrain = new Cesium.EllipsoidTerrainProvider();// 加载完成之后,记录 terrainProvider 对象
terrain.readyEvent.addEventListener(provider => {terrainProvider = provider;
});const viewer = new Cesium.Viewer("cesiumContainer", {// Use Cesium World Terrainterrain: terrain,// Show Columbus View map with Web Mercator projectionmapProjection: new Cesium.WebMercatorProjection()
});// 分割线 ===================================================================// 切换地形高程
// 关闭高程
viewer.terrainProvider = ellipsoidProvider;
// 开启高程
viewer.terrainProvider = terrainProvider ;

Cesium 实战-最新版(1.104.0)通过异步方式初始化地球,加载影像以及高程图层


初始化 3dtile

Cesium 对于 3dtile 加载调整让作者开始有点不适应。

同样,也是异步加载,但是好像没有像图层和高程类那样,提供一个接受者,因此只能使用异步方法(async function)来创建。
Cesium 实战-最新版(1.104.0)通过异步方式初始化地球,加载影像以及高程图层

这里需要注意一下,需要用异步方法!

// 使用异步关键字
async function addCesium3DTileset(url,options) {try {const tileset = await Cesium.Tileset.fromUrl(url, options);viewer.scene.primitives.add(tileset);} catch (error) {console.log(`Failed to load tileset: ${error}`);}
}
addCesium3DTileset();

Cesium 实战-最新版(1.104.0)通过异步方式初始化地球,加载影像以及高程图层


在线示例

镜像沙盒示例:Cesium 1.104.0 初始化

红酒品牌