项目中可能会有大量的label文本文字显示在地图上,如果不做任何处理,文本文字会都堆叠在一起,用户体验也特别差,解决这一问题的思路是:将label文本文字的经纬度转成屏幕坐标,检测文本文字之间的屏幕坐标差值,以第一个label文件文字的位置为起始点,逐一比较后面的label文本文字,如果差值小于设定的某一个值,则将后面的label文本文字设置为隐藏,直到距离大于设定的某一个值,记录此时的index,然后再以该label文本文字为起点,递归处理后面的数据。
function labelToggleByCameraChange(map, labels, minZoom = 13.5) {
console.log("map, labels", map, labels);
let viewer = map.map;
let scene = viewer.scene;
map.labelToggleByCameraChangeFlag = false;
const labelToggleByCameraChangeEvent = () => {
if (map.labelToggleByCameraChangeFlag) {
return;
}
map.labelToggleByCameraChangeFlag = true;
let zoom = map.getZoom();
console.log("zoom", zoom);
if (zoom > minZoom) {
for (let i = 1; i < labels.length; i++) {
labels[i].show();
}
map.labelToggleByCameraChangeFlag = false;
} else {
// 视高 km
let alt = (viewer.camera.positionCartographic.height / 1000).toFixed(2);
// 方位角
let heading = Cesium.Math.toDegrees(viewer.camera.heading).toFixed(2);
// 俯仰角
let pitch = Cesium.Math.toDegrees(viewer.camera.pitch).toFixed(2);
// 翻滚角
let roll = Cesium.Math.toDegrees(viewer.camera.roll).toFixed(2);
// 级别
let level = 0;
let tileRender = viewer.scene._globe._surface._tilesToRender;
if (tileRender && tileRender.length > 0) {
level = viewer.scene._globe._surface._tilesToRender[0]._level;
}
let str = `级数:${level} 视高:${alt}km 方位角:${heading}° 俯仰角:${pitch}° 翻滚角:${roll}°`;
// console.log(str);
let showIndex = 0;
let windowCoord0 = Cesium.SceneTransforms.wgs84ToWindowCoordinates(
scene,
Cesium.Cartesian3.fromDegrees(...labels[0].getPosition())
);
if (!windowCoord0) {
map.labelToggleByCameraChangeFlag = false;
} else {
let temX = windowCoord0.x;
let temY = windowCoord0.y;
for (let i = 1; i < labels.length; i++) {
let position = labels[i].getPosition();
let windowCoord = Cesium.SceneTransforms.wgs84ToWindowCoordinates(
scene,
Cesium.Cartesian3.fromDegrees(...position)
);
let text = labels[i].options.text;
// console.log("windowCoord", windowCoord);
if (windowCoord) {
if (
Math.abs(windowCoord.y - temY) < 50 &&
Math.abs(windowCoord.x - temX) < text.length * 10
) {
labels[i].hide();
} else {
labels[i].show();
temY = windowCoord.y;
temX = windowCoord.x;
}
}
}
map.labelToggleByCameraChangeFlag = false;
}
}
};
console.log("map.cameraChangedHandler", map.cameraChangedHandler);
if (map.cameraChangedHandler) {
map.cameraChangedHandler();
}
labelToggleByCameraChangeEvent()
let cameraChangedHandler = viewer.camera.changed.addEventListener(
labelToggleByCameraChangeEvent
);
map.cameraChangedHandler = cameraChangedHandler;
}