三维地图Cesium中,如何监听地图点击事件,实现在实体上面鼠标右击时做处理。

在 Cesium 中,如果你想在实体(Entity)上实现鼠标右击(右键点击)的处理,你需要使用 Cesium 的事件系统来监听鼠标事件,并结合一些逻辑来判断点击是否发生在实体上。由于 Cesium 没有直接提供"点击实体"的事件,你需要自己实现这个逻辑。

以下是一个基本的步骤和示例代码,用于在 Cesium 中实现鼠标右击实体时的处理:

  1. 监听全局的鼠标右击事件 :使用 Cesium 的 ScreenSpaceEventHandler 来监听鼠标右击事件。
  2. 判断点击位置是否位于实体上 :这通常涉及到射线投射(ray-casting)或其他形式的拾取(picking)技术。Cesium 提供了 Scene.pick 方法,它可以用于获取在指定位置上的对象。
  3. 执行处理逻辑:如果点击位置上有实体,执行相应的处理逻辑。

示例代码:

javascript 复制代码
var viewer = new Cesium.Viewer('cesiumContainer');

// 创建一个 ScreenSpaceEventHandler 实例来监听鼠标事件
var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);

// 监听右键点击事件
handler.setInputAction(function(click) {
    // 使用 pick 方法获取点击位置上的对象
    var pickedObject = viewer.scene.pick(click.position);

    // 检查 pickedObject 是否是 Entity 或与 Entity 相关的对象(如 Primitive)
    // 注意:直接 pick 可能不会直接返回 Entity,而可能是与 Entity 相关的其他对象
    // 你可能需要遍历 EntityCollection 或使用其他方法来确认点击的 Entity

    if (pickedObject && /* 这里添加你的逻辑来判断 pickedObject 是否是你关心的 Entity */) {
        // 执行你的处理逻辑
        console.log('Right-clicked on an entity!');
        // 例如:显示一个提示框、改变实体的颜色等
    }
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);

注意

  • 直接使用 pick 方法可能不会直接返回 Entity 对象。它可能会返回与 Entity 相关的其他对象,如 Primitive、Geometry 等。你可能需要遍历你的 EntityCollection 或使用其他方法来确认点击的 Entity。
  • 如果你的 Entity 使用了 Billboard、Label 或其他不直接参与射线投射的可视化元素,那么你可能需要使用其他方法来检测点击,如检查鼠标位置是否在 Billboard 的边界框内。
  • 你可以使用 Cesium 的其他事件(如鼠标移动、左键点击等)来增强你的交互体验。

例:要在Cesium三维地图上点击某个点,在该点加一个自定义图标的实体,并且鼠标右击这个实体时,我要做一些操作。添加一个自定义图标的实体,并为该实体添加一个myData自定义数据,后面根据这个数据做是否点击该实体的判断。

javascript 复制代码
    // 点击地图,添加一个自定义实体
    function clickCesiumMapAddEntities() {
      let ellipsoid = window.viewer.scene.globe.ellipsoid;
      dropHandler = new Cesium.ScreenSpaceEventHandler(window.viewer.scene.canvas);
      dropHandler.setInputAction((move) => {
        let cartesian = window.viewer.camera.pickEllipsoid(move.position, ellipsoid);
        if (cartesian) {
          // 苗卡尔椭球体的三维坐标 转 地图坐标(弧度)
          let cartographic = window.viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian);
          // 地图坐标(弧度) 转 十进制度数 toFixed保留小数点后几位
          let lon = Cesium.Math.toDegrees(cartographic.longitude).toFixed(8);//拿到经度
          let lat = Cesium.Math.toDegrees(cartographic.latitude).toFixed(8);//拿到纬度
          //自动获取模型高度
          let position = window.viewer.scene.pickPosition(move.position);
          //如果对象已定义,将度转为经纬度
          let lableHeight = Cesium.Cartographic.fromCartesian(position);
          let height = lableHeight.height.toFixed(2);//模型高度
          addBillboardEntities(lon,lat,height)
        }
      }, Cesium.ScreenSpaceEventType.LEFT_CLICK)
    },
    function addBillboardEntities(lon,lat,height){
      let myEntities = window.viewer.entities.add({
        name: 'myEntities',
        //给初始点位设置一定的离地高度,否者会被压盖
        position: Cesium.Cartesian3.fromDegrees(lon, lat, height),
        billboard: {
          image: baseUrlIcon, // 图片服务器完整的图片地址 如:static/images/mybaseUrlIcon.img
          width: 60,
          height: 60,
        },
        myData: {
          name: 'myEntities',
          lon: lon,
          lat: lat,
        },
      })

      // 添加完实体,左键监听事件,判断点击的实体
      let handler = new Cesium.ScreenSpaceEventHandler(window.viewer.scene.canvas);
      handler.setInputAction(function (movement) {
        var picked = window.viewer.scene.pick(movement.position)
        if (Cesium.defined(picked) && picked.id.id) {
          if (!picked.id.myData) return;
          // myData就是我们在添加实体时,自己添加的自定义标识,在这里我们就可以做自己的事情了
          console.log('我当前点击的是那个实体:',picked.id.myData)
        }
      }, Cesium.ScreenSpaceEventType.RIGHT_CLICK)
    }

删除某个实体 window.viewer.entities.remove(entitys[i]);

删除所有实体:window.viewer.entities.removeAll();

拿到当前已添加所有的实体window.viewer.entities._entities._array;

相关推荐
心.c1 分钟前
JavaScript单线程实现异步
开发语言·前端·javascript·ecmascript
爱分享的程序员8 分钟前
前端面试专栏-前沿技术:31.Serverless与云原生开发
前端·javascript·面试
姜 萌@cnblogs1 小时前
Saga Reader 0.9.9 版本亮点:深入解析核心新功能实现
前端·ai·rust
gnip1 小时前
实现elementplus官网主题切换特效
前端·css
Darling02zjh1 小时前
HTML5
前端·html·html5
成长ing121382 小时前
闪白效果
前端·cocos creator
Lazy_zheng2 小时前
React架构深度解析:从 Stack 到 Fiber,解决 CPU 和 I/O 瓶颈问题
前端·react.js·前端框架
张元清2 小时前
什么是React并发模式中的Tearing(撕裂)
前端·面试
AndyLaw2 小时前
统计字符数错一半,我被 length 坑了两次
前端·javascript
关羽的小刀2 小时前
Element-UI最新版暗藏Lodash漏洞?一次真实项目安全排查记录
前端