效果图:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Cesium聚合</title>
<!-- 在这里引入Cesium -->
<script src="./lib/Cesium/Cesium.js"></script>
<link rel="stylesheet" href="./lib/Cesium/Widgets/widgets.css" rel="stylesheet">
<style>
html,
body {
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<!-- https://blog.csdn.net/weixin_45782925/article/details/123054390 -->
<!-- 放置地球的容器 -->
<div id="cesiumContainer"></div>
<!-- 设置tooken -->
<script>
Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJlMDczMzQ0NC1lZmRkLTQ0ODEtOGZhMy01MDU3NzAzM2E5YmIiLCJpZCI6MTg2MDgsInNjb3BlcyI6WyJhc3IiLCJnYyJdLCJpYXQiOjE1NzQxNDMwNTB9.LJcpHG4SJ8DI1mCHd1aabofkvS-9WrxeWVul7Axw_Kw';
</script>
<script>
var viewer = new Cesium.Viewer('cesiumContainer', {
//关闭一些UI
baseLayerPicker: false, //右上角的图层选择按钮
animation: true, //左下角的动画仪表盘
infoBox: false, //点击要素之后显示的信息
geocoder: false, //搜索框
homeButton: false, //home按钮
sceneModePicker: true, //模式切换按钮
timeline: true, //底部的时间轴
fullscreenButton: false,//右下角的全屏按钮
shouldAnimate: true,
navigationHelpButton: false, //右上角的帮助按钮,
});
/**
* @description: 点聚合功能效果
* @param {*} viewer
* @return {*}
*/
function initCluster(viewer) {
new Cesium.GeoJsonDataSource().load("./data/cluster.geojson").then(dataSource => {
viewer.dataSources.add(dataSource);
// 设置聚合参数
dataSource.clustering.enabled = true;
dataSource.clustering.pixelRange = 60;
dataSource.clustering.minimumClusterSize = 2;
// foreach用于调用数组的每个元素,并将元素传递给回调函数。
dataSource.entities.values.forEach(entity => {
// 将点拉伸一定高度,防止被地形压盖
entity.position._value.z += 50.0;
// 使用大小为64*64的icon,缩小展示poi
entity.billboard = {
image: './img/car.png',
width: 32,
height: 32,
};
entity.label = {
text: 'POI',
font: 'bold 15px Microsoft YaHei',
// 竖直对齐方式
verticalOrigin: Cesium.VerticalOrigin.CENTER,
// 水平对齐方式
horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
// 偏移量
pixelOffset: new Cesium.Cartesian2(15, 0),
}
});
var pinBuilder = new Cesium.PinBuilder();
var singleDigitPins = new Array(8);
for (var i = 0; i < singleDigitPins.length; ++i) {
singleDigitPins[i] = pinBuilder.fromText('' + (i + 2), Cesium.Color.VIOLET, 48).toDataURL();
}
// 添加监听函数
dataSource.clustering.clusterEvent.addEventListener(
function (clusteredEntities, cluster) {
// 关闭自带的显示聚合数量的标签
cluster.label.show = false;
cluster.billboard.show = true;
cluster.billboard.verticalOrigin = Cesium.VerticalOrigin.BOTTOM;
// 根据聚合数量的多少设置不同层级的图片以及大小
if (clusteredEntities.length >= 50) {
// cluster.billboard.image = combineIconAndLabel('./img/car.png', clusteredEntities.length, 64);
// cluster.billboard.width = 72;
// cluster.billboard.height = 72;
cluster.billboard.image = pinBuilder.fromText(clusteredEntities.length, Cesium.Color.RED, 48).toDataURL();
} else if (clusteredEntities.length >= 40) {
// cluster.billboard.image = combineIconAndLabel('./img/car.png', clusteredEntities.length, 64);
// cluster.billboard.width = 56;
// cluster.billboard.height = 56;
} else if (clusteredEntities.length >= 30) {
// cluster.billboard.image = combineIconAndLabel('./img/car.png', clusteredEntities.length, 64);
// cluster.billboard.width = 48;
// cluster.billboard.height = 48;
cluster.billboard.image = pinBuilder.fromText(clusteredEntities.length, Cesium.Color.YELLOW, 48).toDataURL();
} else if (clusteredEntities.length >= 20) {
// cluster.billboard.image = combineIconAndLabel('./img/car.png', clusteredEntities.length, 64);
// cluster.billboard.width = 40;
// cluster.billboard.height = 40;
cluster.billboard.image = pinBuilder.fromText(clusteredEntities.length, Cesium.Color.GREEN, 48).toDataURL();
} else if (clusteredEntities.length >= 10) {
cluster.billboard.image = pinBuilder.fromText(clusteredEntities.length, Cesium.Color.BLUE, 48).toDataURL();
} else {
cluster.billboard.image = singleDigitPins[clusteredEntities.length - 2];
}
}
)
});
}
/**
* @description: 将图片和文字合成新图标使用(参考Cesium源码)
* @param {*} url:图片地址
* @param {*} label:文字
* @param {*} size:画布大小
* @return {*} 返回canvas
*/
function combineIconAndLabel(url, label, size) {
// 创建画布对象
let canvas = document.createElement('canvas');
canvas.width = size;
canvas.height = size;
let ctx = canvas.getContext("2d");
let promise = new Cesium.Resource.fetchImage(url).then(image => {
// 异常判断
try {
ctx.drawImage(image, 0, 0);
} catch (e) {
console.log(e);
}
// 渲染字体
// font属性设置顺序:font-style, font-variant, font-weight, font-size, line-height, font-family
ctx.fillStyle = Cesium.Color.WHITE.toCssColorString();
ctx.font = 'bold 20px Microsoft YaHei';
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillText(label, size / 2, size / 2);
return canvas;
});
return promise;
}
initCluster(viewer)
</script>
</body>
</html>