注意聚合功能只对label标签,point点和广告牌billboard生效
可以看到 使用聚合前帧数在40左右,使用后在55左右
const loadCustom = () => {
//聚合属性只对label标签,point点和广告牌billboard生效
const dataSource = new Cesium.CustomDataSource("myData");
for (let i = 0; i < 2000; ++i) {
dataSource.entities.add({
position: Cesium.Cartesian3.fromDegrees(103.769644 + Math.random() * 0.1, 31.097718 + Math.random() * 0.1),
// point: {
// color: Cesium.Color.RED,
// },
label: {
text: '车辆编号-' + i,
pixelOffset: new Cesium.Cartesian2(10, -70), // 偏移方向
fillColor: Cesium.Color.BLACK.withAlpha(0.65),
backgroundColor: Cesium.Color.YELLOW,
showBackground: true,
font: '12px;'
},
billboard: {
image: 'icons/icon_chezai_m_d.png',
width: 64,
height: 64,
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
horizontalOrigin: Cesium.HorizontalOrigin.CENTER, // //相对于对象的原点(注意是原点的位置)的水平位置
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
pixelOffset: new Cesium.Cartesian2(12.5, 0), // 偏移
}
});
}
const dataSourcePromise = viewer.dataSources.add(dataSource);
dataSourcePromise.then(function (dataSource) {
const pixelRange = 15;
const minimumClusterSize = 3;
const enabled = true;
dataSource.clustering.enabled = enabled; //是否聚合
dataSource.clustering.pixelRange = pixelRange;
dataSource.clustering.minimumClusterSize = minimumClusterSize;
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();
const singleDigitPins = new Array(8);
for (let i = 0; i < singleDigitPins.length; ++i) {
singleDigitPins[i] = pinBuilder
.fromText(`${i + 2}`, Cesium.Color.VIOLET, 48)
.toDataURL();
}
function customStyle() {
if (Cesium.defined(removeListener)) {
removeListener && removeListener();
removeListener = undefined;
} else {
removeListener = dataSource.clustering.clusterEvent.addEventListener(
function (clusteredEntities, cluster) {
cluster.label.show = false;
cluster.billboard.show = true;
cluster.billboard.id = cluster.label.id;
cluster.billboard.verticalOrigin =
Cesium.VerticalOrigin.BOTTOM;
if (clusteredEntities.length >= 1000) {
cluster.billboard.image = pin1000;
} else if (clusteredEntities.length >= 500) {
cluster.billboard.image = pin500;
} else if (clusteredEntities.length >= 100) {
cluster.billboard.image = pin100;
} else if (clusteredEntities.length >= 50) {
cluster.billboard.image = pin50;
} else if (clusteredEntities.length >= 40) {
cluster.billboard.image = pin40;
} else if (clusteredEntities.length >= 30) {
cluster.billboard.image = pin30;
} else if (clusteredEntities.length >= 20) {
cluster.billboard.image = pin20;
} else if (clusteredEntities.length >= 10) {
cluster.billboard.image = pin10;
} else {
cluster.billboard.image =
singleDigitPins[clusteredEntities.length - 2];
}
}
);
}
const pixelRange = dataSource.clustering.pixelRange;
dataSource.clustering.pixelRange = 0;
dataSource.clustering.pixelRange = pixelRange;
}
customStyle();
const handler = new Cesium.ScreenSpaceEventHandler(
viewer.scene.canvas
);
handler.setInputAction(function (movement) {
const pickedLabel = viewer.scene.pick(movement.position);
if (Cesium.defined(pickedLabel)) {
const ids = pickedLabel.id;
if(ids.length > 1) {
let PoRay = viewer.camera.getPickRay(ray);
const car3 = viewer.scene.globe.pick(PoRay, viewer.scene);
let cartographic = Cesium.Cartographic.fromCartesian(car3);
let longitudeString = Cesium.Math.toDegrees(cartographic.longitude);
let latitudeString = Cesium.Math.toDegrees(cartographic.latitude);
viewer.camera.flyTo({
destination: Cesium.Cartesian3.fromDegrees(longitudeString , latitudeString , height / 1.8),
duration: 1.0
});
}
console.log(pickedLabel)
// if (Array.isArray(ids)) {
// for (let i = 0; i < ids.length; ++i) {
// ids[i].billboard.color = Cesium.Color.RED;
// }
// }
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
})
}
拾取
handler.setInputAction(function (movement) {
const pickedLabel = viewer.scene.pick(movement.position);
if (Cesium.defined(pickedLabel)) {
const ids = pickedLabel.id;
console.log(ids)
}
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
添加弹窗-核心代码
let pos = (props.trackEntity.position && props.trackEntity.position.getValue(Cesium.JulianDate.now())) || Cesium.Cartesian3.ZERO; screenPos = Cesium.SceneTransforms.wgs84ToWindowCoordinates( Viewer.scene, pos );
const handler = new Cesium.ScreenSpaceEventHandler();
const onUpdate = () => {
if (element == null) return;
let screenPos;
if (trackCursor) {
screenPos = mousePos;
} else if (props.trackEntity) {
let pos =
(props.trackEntity.position &&
props.trackEntity.position.getValue(Cesium.JulianDate.now())) ||
Cesium.Cartesian3.ZERO;
screenPos = Cesium.SceneTransforms.wgs84ToWindowCoordinates(
Viewer.scene,
pos
);
} else if (props.trackPos) {
screenPos = Cesium.SceneTransforms.wgs84ToWindowCoordinates(
Viewer.scene,
props.trackPos
);
}
if (screenPos) {
if (element.value) {
element.value.style.display = "";
switch (props.alignX) {
case "left":
element.value.style.left = screenPos.x + "px";
break;
case "center":
element.value.style.left =
screenPos.x + element.value.clientWidth * 0.5 + "px";
break;
case "right":
default:
element.value.style.left =
screenPos.x - element.value.clientWidth * 0.5 + "px";
}
switch (props.alignY) {
case "top":
element.value.style.top =
screenPos.y - element.value.clientHeight + "px";
break;
case "bottom":
// this.element.style.top = (screenPos.y + this.element.clientHeight * 0.5) + "px";
element.value.style.top = screenPos.y + "px";
break;
case "center":
default:
element.value.style.top =
screenPos.y - element.value.clientHeight * 0.5 + "px";
}
}
} else {
if (element.value) element.value.style.display = "none";
}
};
onMounted(() => {
handler.setInputAction((event) => {
let offsetToLeftTop = Viewer.container.getBoundingClientRect();
mousePos = Cesium.Cartesian2.subtract(
event.endPosition,
new Cesium.Cartesian2(offsetToLeftTop.left, offsetToLeftTop.top),
new Cesium.Cartesian2()
);
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
Viewer.scene.preUpdate.addEventListener(onUpdate);
});