点聚合说明
-
在Cesium中,点聚合功能是指将大量的点数据聚合成一个更大的点或者其他形状,以减少在地图上显示大量点数据时的视觉混乱和性能问题。点聚合功能通常用于在地图上显示大量的点标记,例如地图上的POI(兴趣点)、传感器数据等。
-
通过点聚合功能,可以将附近的点聚合成一个单独的点或者其他形状,当用户放大地图时,聚合的点会逐渐展开显示更详细的信息。这样可以在保持地图清晰的同时,有效地展示大量的点数据,提高用户体验。
-
点聚合功能在Cesium中是一种处理大量点数据的有效方式,可以提高地图的可读性和性能。
思路实现
- 定义变量,生成随机位置的点(根据个人需求需要绘制点或图标点坐标)
- 在地图上打点或绘制图标
- 对生成的点进行聚合功能(聚合对鼠标滚轮事件进行监听,根据点位的多少展示不同的聚合效果)
完成效果
实现
封装cesiumCluster.ts
let removeListener:any = null
import * as Cesium from 'cesium';
const cesiumCluster= (options:any) => {
// 根据业务来
// let itemList = options.data
// if (!itemList || itemList.length <= 0) return;
// const dataSource = new Cesium.CustomDataSource(options.name);
// for (let i = 0; i < itemList.length; ++i) {
// const lon = Number(itemList[i].longitude);
// const lat = Number(itemList[i].latitude);
// const height = Number(itemList[i].height ? itemList[i].height : 0);
// dataSource.entities.add({
// type: options.type,
// name: 'coverageControl',
// id: itemList[i].id,
// position: Cesium.Cartesian3.fromDegrees(lon+ Math.random() * 0.1, lat + Math.random() * 0.1, height),
// billboard: {
// image: options.billboardImg,
// scale: 1.2,
// horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
// verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
// }
// });
// }
// 测试生成随机数点
const dataSource = new Cesium.CustomDataSource(options.name);
for (let i = 0; i <5000; ++i) {
const lon = Number(112);
const lat = Number(22);
const height = Number(0);
dataSource.entities.add({
name: 'coverageControl',
position: Cesium.Cartesian3.fromDegrees(lon+ Math.random() * 0.2, lat + Math.random() * 0.2, height),
label: {
text: '樱桃水果',
pixelOffset: new Cesium.Cartesian2(10, -70), // 偏移方向
fillColor: Cesium.Color.WHITE,
backgroundColor: Cesium.Color.fromCssColorString('#e71236'),
showBackground: true,
font: '12px;'
},
billboard: {
image: '/img/樱桃水果.png',
scale: 0.5,
horizontalOrigin: Cesium.HorizontalOrigin.CENTER, // 相对于对象的原点(注意是原点的位置)的水平位置
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
}
});
}
dataSource.show = options.show
const dataSourcePromise = window.viewer.dataSources.add(dataSource);
dataSourcePromise.then(function (dataSource:any) {
const pixelRange = 15;
const minimumClusterSize = 3;
const enabled = true;
dataSource.clustering.enabled = enabled; //是否聚合
dataSource.clustering.pixelRange = pixelRange;
dataSource.clustering.minimumClusterSize = minimumClusterSize;
dataSource.type = options.type;
const pinBuilder = new Cesium.PinBuilder();
const pin1000 = pinBuilder
.fromText("1000+", Cesium.Color.RED, 48)
.toDataURL();
const pin500 = pinBuilder
.fromText("100+", Cesium.Color.RED, 48)
.toDataURL();
const pin100 = pinBuilder
.fromText("100+", Cesium.Color.RED, 48)
.toDataURL();
const pin50 = pinBuilder
.fromText("50+", Cesium.Color.RED, 48)
.toDataURL();
const pin40 = pinBuilder
.fromText("40+", Cesium.Color.ORANGE, 48)
.toDataURL();
const pin30 = pinBuilder
.fromText("30+", Cesium.Color.YELLOW, 48)
.toDataURL();
const pin20 = pinBuilder
.fromText("20+", Cesium.Color.GREEN, 48)
.toDataURL();
const pin10 = pinBuilder
.fromText("10+", Cesium.Color.BLUE, 48)
.toDataURL();
function customStyle(billboard:any , distance:any , bool:any ) {
let distanceCondition = new Cesium.DistanceDisplayCondition(3000.0, distance);
let offset1 = new Cesium.Cartesian2(-8, 0);
let offset2 = new Cesium.Cartesian2(-4, 0);
removeListener = dataSource.clustering.clusterEvent.addEventListener((clusteredEntities:any , cluster:any ) => {
cluster.billboard.disableDepthTestDistance = 10000000000;
if (!bool) {
cluster.label.show = true;
cluster.label.distanceDisplayCondition = distanceCondition;
cluster.label.showBackground = false;
cluster.label.text = clusteredEntities.length.toString();
if (clusteredEntities.length > 9) {
cluster.label.pixelOffset = offset1;
} else {
cluster.label.pixelOffset = offset2;
}
cluster.label.disableDepthTestDistance = 100000000000;
cluster.label.eyeOffset = new Cesium.Cartesian3(0, 0, -10);
cluster.label.font = '15px Arial';
cluster.label.style = Cesium.LabelStyle.FILL_AND_OUTLINE;
cluster.label.fillColor = Cesium.Color.WHITE;
cluster.label.outlineColor = Cesium.Color.WHITE;
cluster.label.outlineWidth = 4;
} else {
cluster.label.show = false;
}
cluster.billboard.distanceDisplayCondition = new Cesium.DistanceDisplayCondition(3000.0, distance);
cluster.billboard.show = true;
cluster.billboard.heightReference = Cesium.HeightReference.CLAMP_TO_GROUND;
cluster.billboard.id = cluster.label.id;
cluster.billboard.image = billboard;
cluster.billboard.scale = 0.7
});
let pixelRange = dataSource.clustering.pixelRange;
dataSource.clustering.pixelRange = 0;
dataSource.clustering.pixelRange = pixelRange;
}
customStyle(options.billboardImg2, 5000000000, false);
})
}
export default cesiumCluster;
使用
import cesiumClusterfrom './cesium/cesiumCluster';
cesiumClusterHelper(options)