Cesium:Entity添加大批量point、billboard、label时界面卡顿问题解决(使用primitive添加并实现聚合功能)

前言

         在Cesium官方提供的沙盒实例中可以找到使用entity.add()接口添加三种数据的方法,但是在实际使用过程中由于数据量过大会出现数据加载耗时较长、页面卡顿等情况。于是想到解决该问题的方法使用primitive添加并利用原有的clustering 实现聚合。

一、数据添加

        添加数据时直接利用viewer.scene.primitives.add分别新建三种collection对象:PointPrimitiveCollection、BillboardClooection、LabelCollection然后分别向其中添加数据。文章使用的数据为Json格式。

代码如下

var pointCollection = viewer.scene.primitives.add(new Cesium.PointPrimitiveCollection());
var billboardsCollection = viewer.scene.primitives.add(new Cesium.BillboardCollection ());
var labelCollection = viewer.scene.primitives.add(new Cesium.LabelCollection());
var primitives = viewer.scene.primitives.add(new Cesium.PrimitiveCollection());
var url = "";//json文件路径
var datasource = Cesium.Resource.fetchJson();
//数据解析为异步操作
promise.then(function(jsonData){
    var geojson = jsonData;
    //读取数据后得到其中的坐标信息longitude、latitude、label的文本信息fontext
    billboardsCollection.add({
        position : Cesium.Cartesian3.fromDegress(longitude,latitude),
        image : "" //图片存储路径
    });
    labelCollection .add({
        position : Cesium.Cartesian3.fromDegress(longitude,latitude),
        text: fontext
        
    });
});

二、聚合

Cesium官方提供了原生的APIEntityCluster仅支持entity方式添加的point、billboard、label三种数据聚合。

官方API:跳转

那么我们如何才能使primitive添加的数据实现聚合呢。对EntityCluster进行一些修改即可

1、官方的entitycluster启用聚合时需要使用datasource进行调用。由于我们直接使用primitive添加跳过了datasource步骤那么我们可以直接新建一个Cluster对象然后对其参数进行逐一赋值(本文采用方法为新建一个相同的JS文件暂且命名为PrimitiveCluster该方法比较笨拙各位大佬有什么高见可以大家一起学习)代码如下

var scene = viewer.scene;
var primitivecluster = new Cesium.PrimitiveCluster();
primitives.add(primitivecluster);
//与entitycluster相同设置其是否聚合 以及最大最小值
primitivecluster.enabled = true;
primitivecluster.pixelRange = 50;
primitivecluster.minimumClusterSize = 5;
primitivecluster._pointCollection = pointCollection;
primitivecluster._billboardCollection = billboardsCollection;
primitivecluster._labelCollection = labelCollection;
//同时在赋值时调用_initialize方法
primitivecluster._initialize(scene);

//后面设置聚合的距离及聚合后的图标颜色显示与官方案例一样

PrimitiveCluster.js文件代码直接复制EntityCluster.js。有一下改动

1、getScreenSpacePositions方法 将其判定条件如下去掉 (由于原方法传递的item.id为entity对象为空会导致报错进不去points.push方法导致无法正常显示数据)

function getScreenSpacePositions(
  collection,
  points,
  scene,
  occluder,
  entityCluster
) {
  if (!defined(collection)) {
    return;
  }

  var length = collection.length;
  for (var i = 0; i < length; ++i) {
    var item = collection.get(i);
    item.clusterShow = false;

    if (
      !item.show ||
      (entityCluster._scene.mode === SceneMode.SCENE3D &&
        !occluder.isPointVisible(item.position))
    ) {
      continue;
    }

    //将该段直接注释
    /*var canClusterLabels =
      entityCluster._clusterLabels && defined(item._labelCollection);
    var canClusterBillboards =
      entityCluster._clusterBillboards && defined(item.id._billboard);
    var canClusterPoints =
      entityCluster._clusterPoints && defined(item.id._point);
    if (canClusterLabels && (canClusterPoints || canClusterBillboards)) {
      continue;
    }*/

    var coord = item.computeScreenSpacePosition(scene);
    if (!defined(coord)) {
      continue;
    }

    points.push({
      index: i,
      collection: collection,
      clustered: false,
      coord: coord,
    });
  }
}

最后就是在添加相机监听时相应也把

datas.clustering.clusterEvent.addEventListener修改为

primitivecluster.clusterEvent.addEventListener

        一起加油!!!!大佬们有更好的方法可以发出来大家一起学习。

祝各位升职加薪!!!!

  • 7
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 26
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 26
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值