#原因
目前涉及在三维上叠加大量点位数据,考虑到使用场景不一样,同时结合以前Arcgis与Mapboxgl使用习惯顺便写了两个类
#思考
一个GEOJSON为一个图层(GrahicLayer),同时改造Cesium的聚合类(PrimitiveCluster,仅对点作了处理),实现放大小缩小时自动聚合显示提高流畅度,因为本人目前使用的每个图层点位不超过10万,因此没有对数据进行处理切割处理。
/**
* Defines how screen space objects (billboards, points, labels) are clustered.
*
* @param {Object} [options] An object with the following properties:
* @param {Boolean} [options.enabled=false] Whether or not to enable clustering.
* @param {Number} [options.pixelRange=80] The pixel range to extend the screen space bounding box.
* @param {Number} [options.minimumClusterSize=2] The minimum number of screen space objects that can be clustered.
* @param {Boolean} [options.clusterBillboards=true] Whether or not to cluster the billboards of an entity.
* @param {Boolean} [options.clusterLabels=true] Whether or not to cluster the labels of an entity.
* @param {Boolean} [options.clusterPoints=true] Whether or not to cluster the points of an entity.
* @param {Boolean} [options.show=true] Determines if the entities in the cluster will be shown.
*
* @alias PrimitiveCluster
* @constructor
*
* @demo {@link https://sandcastle.cesium.com/index.html?src=Clustering.html|Cesium Sandcastle Clustering Demo}
*/
function PrimitiveCluster(options) {
options = Cesium.defaultValue(options, Cesium.defaultValue.EMPTY_OBJECT);
this._enabled = Cesium.defaultValue(options.enabled, false);
this._pixelRange = Cesium.defaultValue(options.pixelRange, 80);
this._minimumClusterSize = Cesium.defaultValue(options.minimumClusterSize, 2);
this._clusterBillboards = Cesium.defaultValue(options.clusterBillboards, true);
this._clusterLabels = Cesium.defaultValue(options.clusterLabels, true);
this._clusterPoints = Cesium.defaultValue(options.clusterPoints, true);
this._labelCollection = undefined;
this._billboardCollection = undefined;
this._pointCollection = undefined;
this._clusterBillboardCollection = undefined;
this._clusterLabelCollection = undefined;
this._clusterPointCollection = undefined;
this._collectionIndicesByEntity = {};
this._unusedLabelIndices = [];
this._unusedBillboardIndices = [];
this._unusedPointIndices = [];
this._previousClusters = [];
this._previousHeight = undefined;
this._enabledDirty = false;
this._clusterDirty = false;
this._cluster = undefined;
this._removeEventListener = undefined;
this._clusterEvent = new Cesium.Event();
/**
* Determines if entities in this collection will be shown.
*
* @type {Boolean}
* @default true
*/
this.show = Cesium.defaultValue(options.show, true);
}
function getX(point) {
return point.coord.x;
}
function getY(point) {
return point.coord.y;
}
function expandBoundingBox(bbox, pixelRange) {
bbox.x -= pixelRange;
bbox.y -= pixelRange;
bbox.width += pixelRange * 2.0;
bbox.height += pixelRange * 2.0;
}
var labelBoundingBoxScratch = new Cesium.BoundingRectangle();
function getBoundingBox(item, coord, pixelRange, entityCluster, result) {
if (item &&
Cesium.defined(item._billboardCollection) &&
entityCluster._clusterBillboards
) {
result = Cesium.Billboard.getScreenSpaceBoundingBox(item, coord, result);
}
expandBoundingBox(result, pixelRange);
return result;
}
function addNonClusteredItem(item, entityCluster) {
item.clusterShow = true;
if (!Cesium.defined(item._labelCollection) &&
Cesium.defined(item.id) &&
hasLabelIndex(entityCluster, item.id.id) &&
Cesium.defined(item.id._label)
) {
var labelIndex =
entityCluster._collectionIndicesByEntity[item.id.id].labelIndex;
var label = entityCluster._labelCollection.get(labelIndex);
label.clusterShow = true;
}
}
function addCluster(position, numPoints, ids, entityCluster) {
var cluster = {
billboard: entityCluster._clusterBillboardCollection.add(),
label: entityCluster._clusterLabelCollection.add(),
// point: entityCluster._clusterPointCollection.add(),
};
cluster.billboard.show = true;
cluster.billboard.count = numPoints
//cluster.billboard.position = position
cluster.billboard.disableDepthTestDistance = Number.POSITIVE_INFINITY;
cluster.billboard.pixelOffset = new Cesium.Cartesian2(0.0, -20.0)
cluster.billboard.image = entityCluster.bpts.get(0).image
cluster.billboard.height = entityCluster.bpts.get(0).height
cluster.billboard.width = entityCluster.bpts.get(0).width
ids[0].data.ids = ids;
cluster.billboard.id = ids[0];
// cluster.point.show = false;
cluster.label.show = true;
cluster.label.showBackground = true
cluster.label.backgroundColor = new Cesium.Color(1, 1, 1, 0.8)
cluster.label.fillColor = Cesium.Color.GREEN;
cluster.label.font = "12px monospace"
cluster.label.horizontalOrigin = Cesium.HorizontalOrigin.CENTER
cluster.label.verticalOrigin = Cesium.VerticalOrigin.BOTTOM
cluster.label.pixelOffset = new Cesium.Cartesian2(0.0, -40.0)
cluster.label.text = ids[0].data.name;
cluster.label.id = ids[0];
cluster.billboard.position = cluster.label.position = position //= cluster.point.position = position;
}
function hasLabelIndex(entityCluster, entityId) {
return (
Cesium.defined(entityCluster) &&
Cesium.defined(entityCluster._collectionIndicesByEntity[entityId]) &&
Cesium.defined(entityCluster._collectionIndicesByEntity[entityId].labelIndex)
);
}
function getScreenSpacePositions(
collection,
points,
scene,
occluder,
entityCluster
) {
if (!Cesium.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 === Cesium.SceneMode.SCENE3D &&
!occluder.isPointVisible(item.position))
) {
continue;
}
var canClusterLabels =
entityCluster._clusterLabels && Cesium.defined(item._labelCollection);
var canClusterBillboards =
entityCluster._clusterBillboards && Cesium.defined(item);
var canClusterPoints =
entityCluster._clusterPoints && Cesium.defined(item._point);
if (canClusterLabels && (canClusterPoints || canClusterBillboards)) {
continue;
}
var coord = item.computeScreenSpacePosition(scene);
if (!Cesium.defined(coord)) {
continue;
}
points.push({
index: i,
collection: collection,
clustered: false,
coord: coord,
});
}
}
var pointBoundinRectangleScratch = new Cesium.BoundingRectangle();
var totalBoundingRectangleScratch = new Cesium.BoundingRectangle();
var neighborBoundingRectangleScratch = new Cesium.BoundingRectangle();
function createDeclutterCallback(entityCluster) {
return async function(amount) {
entityCluster._clusterEvent.raiseEvent({});
if (!entityCluster.show) return;
var scene = entityCluster._scene;
var labelCollection = entityCluster._labelCollection;
var billboardCollection = entityCluster._billboardCollection;
var pointCollection = entityCluster._pointCollection;
if (
(!Cesium.defined(labelCollection) &&
!Cesium.defined(billboardCollection) &&
!Cesium.defined(pointCollection)) ||
(!entityCluster._clusterBillboards &&
!entityCluster._clusterLabels &&
!entityCluster._clusterPoints)
) {
return;
}
var clusteredLabelCollection = entityCluster._clusterLabelCollection;
var clusteredBillboardCollection =
entityCluster._clusterBillboardCollection;
// var clusteredPointCollection = entityCluster._clusterPointCollection;
if (Cesium.defined(clusteredLabelCollection)) {
clusteredLabelCollection.removeAll();
} else {
clusteredLabelCollection = entityCluster._clusterLabelCollection = new Cesium.LabelCollection({
scene: scene,
});
}
if (Cesium.defined(clusteredBillboardCollection)) {
clusteredBillboardCollection.removeAll();
} else {
clusteredBillboardCollection = entityCluster._clusterBillboardCollection = new Cesium.BillboardCollection({
scene: scene,
});
}
var pixelRange = entityCluster._pixelRange;
var minimumClusterSize = entityCluster._minimumClusterSize;
var clusters = entityCluster._previousClusters;
var newClusters =