本文主要是介绍cesium文字实现避让功能,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
简介:
cesium项目上,当文字特别多的时候,互相遮挡比较严重
这个时候,可以通过“文字避让”来解决
原始文字如下图:
使用避让功能后
实现思路:
1、把文字加载到cesium中
2、声明一个矩形集合,存储避让后的label的外包矩形,并提供了矩形相交的判断方法
3、获取每个文字对象在像素坐标系下的中心点、宽和高,并组装成矩形对象
4、对于步骤3中得到的矩形结果,与矩形集合的所有矩形进行相交判断
5、如果相交,则隐藏文字,并计算下一个;如果不相交,则加入到矩形集合,并显示文字
6、绑定相关事件,在每次camera改变的时候,重新计算
代码实现:
1、使用LabelCollection类来加载所有文字
const labelCol = scene.primitives.add(new Cesium.LabelCollection());
let oneLabel = labelCol.add({position: Cesium.Cartesian3.fromDegrees(-75.1641667, 39.9522222),text: "Philadelphia",
});
2、创建矩形集合对象
let rectangleCollisionCheck = new Cesium.RectangleCollisionChecker();
3、获取每个“文字对象”在像素坐标系下的宽和高
注意:这里说的宽和高,是指label对象中所有文字占用的宽和高,不是单个字母的宽和高
比如:“abc”这个文字对象,是指abc三个字母共同占有的范围,而不是对单个a、b、c的分别计算
//1、
//oneLabel的中心点,在屏幕坐标系下的坐标
//其中,默认中心点是在文字左下角
//可以通过horizontalOrigin、verticalOrigin这2个参数来改变中心点在文字的左下角还是右上角
let ssPos = oneLabel.computeScreenSpacePosition(viewer.scene);//2、
//拿到label对象中所有文字,在屏幕坐标系中占据的矩形大小
let boundingRectangle = Cesium.Label.getScreenSpaceBoundingBox(
oneLabel,ssPos
);//3、
//boundingRectangle转换为Rectangle
//此时计算的Rectangle,并不是真实的wgs84坐标系
//其本质还是屏幕坐标系,只是在形式上转换为Rectangle类型
//这样方便rectangleCollisionCheck类的使用
let { x, y, width, height } = boundingRectangle;
const west = x;
const south = y;
const east = x + width;
const north = y + height;
const rectangle = new Cesium.Rectangle(west, south, east, north);
4、相交判断
//判断步骤3中计算的矩形,与“矩形集合”中的其他矩形是否相交
let isCollide = rectangleCollisionCheck.collides(rectangle)
5、相交结果处理
if (isCollide) {//和集合中的其他rectangle有交集 oneLabel.show = false;continue;
} else {//和集合中的其他rectangle没有交集oneLabel.show = true;rectangleCollisionCheck.insert(id, rectanglePretend);//当前rectangle添加进矩形集合
}
6、绑定事件
viewer.camera.moveEnd.addEventListener(function () {//rectangleCollisionCheck._tree.clear();//重新进行上述3、4、5的步骤
})
这篇关于cesium文字实现避让功能的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!