前言
在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
一起加油!!!!大佬们有更好的方法可以发出来大家一起学习。
祝各位升职加薪!!!!