• cesium文字实现避让功能


    简介:

    cesium项目上,当文字特别多的时候,互相遮挡比较严重

    这个时候,可以通过“文字避让”来解决

    原始文字如下图:

    使用避让功能后

    实现思路:

    1、把文字加载到cesium中

    2、声明一个矩形集合,存储避让后的label的外包矩形,并提供了矩形相交的判断方法

    3、获取每个文字对象在像素坐标系下的中心点、宽和高,并组装成矩形对象

    4、对于步骤3中得到的矩形结果,与矩形集合的所有矩形进行相交判断

    5、如果相交,则隐藏文字,并计算下一个;如果不相交,则加入到矩形集合,并显示文字

    6、绑定相关事件,在每次camera改变的时候,重新计算

    代码实现:

    1、使用LabelCollection类来加载所有文字

    1. const labelCol = scene.primitives.add(new Cesium.LabelCollection());
    2. let oneLabel = labelCol.add({
    3. position: Cesium.Cartesian3.fromDegrees(-75.1641667, 39.9522222),
    4. text: "Philadelphia",
    5. });

    2、创建矩形集合对象

    let rectangleCollisionCheck = new Cesium.RectangleCollisionChecker();

    3、获取每个“文字对象”在像素坐标系下的宽和高

    注意:这里说的宽和高,是指label对象中所有文字占用的宽和高,不是单个字母的宽和高

    比如:“abc”这个文字对象,是指abc三个字母共同占有的范围,而不是对单个a、b、c的分别计算

    1. //1、
    2. //oneLabel的中心点,在屏幕坐标系下的坐标
    3. //其中,默认中心点是在文字左下角
    4. //可以通过horizontalOrigin、verticalOrigin这2个参数来改变中心点在文字的左下角还是右上角
    5. let ssPos = oneLabel.computeScreenSpacePosition(viewer.scene);
    6. //2、
    7. //拿到label对象中所有文字,在屏幕坐标系中占据的矩形大小
    8. let boundingRectangle = Cesium.Label.getScreenSpaceBoundingBox(
    9. oneLabel,
    10. ssPos
    11. );
    12. //3、
    13. //boundingRectangle转换为Rectangle
    14. 此时计算的Rectangle,并不是真实的wgs84坐标系
    15. //其本质还是屏幕坐标系,只是在形式上转换为Rectangle类型
    16. //这样方便rectangleCollisionCheck类的使用
    17. let { x, y, width, height } = boundingRectangle;
    18. const west = x;
    19. const south = y;
    20. const east = x + width;
    21. const north = y + height;
    22. const rectangle = new Cesium.Rectangle(west, south, east, north);

    4、相交判断

    1. //判断步骤3中计算的矩形,与“矩形集合”中的其他矩形是否相交
    2. let isCollide = rectangleCollisionCheck.collides(rectangle)

    5、相交结果处理

    1. if (isCollide) {
    2. //和集合中的其他rectangle有交集
    3. oneLabel.show = false;
    4. continue;
    5. } else {
    6. //和集合中的其他rectangle没有交集
    7. oneLabel.show = true;
    8. rectangleCollisionCheck.insert(id, rectanglePretend);//当前rectangle添加进矩形集合
    9. }

    6、绑定事件

    1. viewer.camera.moveEnd.addEventListener(function () {
    2. //rectangleCollisionCheck._tree.clear();
    3. //重新进行上述3、4、5的步骤
    4. })

  • 相关阅读:
    C++ 11 chrono
    L53.linux命令每日一练 -- 第八章 Linux磁盘与文件系统管理命令 -- dd和mount
    Java 函数式接口、lambda表达式、初识Stream
    React之组件的生命周期
    Android 左右滑屏,实现Back按键
    egg单元测试Mocha报错Error: Cannot find module ‘mocha‘解决办法
    数据结构--排序
    【爬虫】基于OSMnx库,获取国外POI数据
    驱动开发:内核枚举进程与线程ObCall回调
    人人皆知的人工智能真的稳定吗?它的发展前景如何?
  • 原文地址:https://blog.csdn.net/wzwxwc1987/article/details/134516135