Cesium重复添加geojson

我想实现的效果是:

在vue2中当我切换组件且viewer被重置的情况下,能够保留在切换之前已经添加的geojson数据,在新一次初始化viewer的时候将之前由GeoJSON添加而来的Entity重新加回来。

首先说几个坑:

1、Cesium中确实提供了一个EntityCollection

// 创建一个 EntityCollection 对象
var entities = new Cesium.EntityCollection();

但是它只能够处理普通的Entity,不能对由geojson数据处理而来的Entity对象进行添加。简单的说就是遍历它的values时,使用viewer.entities.add(xxx)是无法加载的。只有使用下面的方法添加的Entity可以通过遍历这个EntityCollection来进行添加。

// 这样使用可以正常添加普通的Entity
// 创建一个 EntityCollection 对象
var entities = new Cesium.EntityCollection();

// 创建一个新实体
var entity = entities.add({
  position: Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883),
  point: {
    pixelSize: 10,
    color: Cesium.Color.YELLOW,
  },
});
// 遍历实体集合
entities.values.forEach(function (entity) {
  viewer.entities.add(entity);
});
// 这样无法正常添加由GeoJson生成的Entity
// 创建一个 EntityCollection 对象
var entities = new Cesium.EntityCollection();

// 创建一个新实体
let dataSource = Cesium.GeoJsonDataSource.load(
"xxx.json",
{
  stroke: Cesium.Color.RED,
  fill: Cesium.Color.SKYBLUE.withAlpha(0.3),
  strokeWidth: 4,
});

entities.add(dataSource)
entities.values.forEach(function (entity) {
  viewer.entities.add(entity);
});

而在这个无法正常使用的例子中:1、它不会报错。2、如果输出这个forEach中的entity,它确实长得很像能够正常添加的那种,很容易受到干扰。

于是转换思路,正确的添加方式应该是长这样

// 创建一个新实体
let dataSource = Cesium.GeoJsonDataSource.load(
  "xxx.json",
  {
    stroke: Cesium.Color.RED,
    fill: Cesium.Color.SKYBLUE.withAlpha(0.3),
    strokeWidth: 4,
  }
);
viewer.dataSources.add(dataSource);
let dataSource2 = Cesium.GeoJsonDataSource.load(
  "xxx.json",
);
viewer.dataSources.add(dataSource2);
// 这个定时器纯粹是用来验证猜想的
setTimeout(() => {
  // 如果之前使用了viewer.dataSources.add进行添加,viewer.dataSources._dataSources中将会存储所有已经添加过的entity对象
  const geoJsonDataSource = viewer.dataSources._dataSources;
  // 只需要遍历这个geoJsonDataSource再使用viewer.dataSources.add就可以正常添加了
  geoJsonDataSource.forEach((geoEntity) => {
    viewer.dataSources.add(geoEntity)
  })
}, 5000)

而想实现我的预想就还需要注意另一点:

由于我使用的是vue2,所以很容易碰到的一点就是viewer可能会存在重复初始化。于是我在beforeDestroy中使用viewer.destroy()销毁了viewer,用来避免重复初始化。

在这个过程中,如果的确需要保存viewer.dataSources._dataSources,请一定要记得在destroy()之前进行保存。

同时请不要随意去保存viewer.dataSources。原因有二:1、viewer.dataSources属于浅拷贝,使用viewer.destroy()之后这个地方就是undefined,根本达不到保存的效果。2、如果使用深拷贝,不论是递归拷贝还是有点受诟病的JSON.stringify,当再一次初始化viewer的时候,就会出现重复初始化的问题。这里的缘由我还没有弄清楚。有知道的大佬可以告诉我一下。

总而言之,想保存直接使用viewer.dataSources._dataSources就行了。想添加(仅限于geojson),就用我上面写的可以正常添加的代码即可。最后再说一句:输出的时候注意异步的问题!不然也有可能是undefined哦!

猜你喜欢

转载自blog.csdn.net/XFIRR/article/details/129655785