三维地图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;

相关推荐
excel3 小时前
Three.js 实现高分辨率地球边界可视化
前端
LaoZhangAI4 小时前
Google Gemini AI图片编辑完全指南:50+中英对照提示词与批量处理教程(2025年9月)
前端·后端
用户11481867894844 小时前
从零搭建 Vue3 + Nest.js 实时通信项目:4 种方案(短轮询 / 长轮询 / SSE/WebSocket)
前端·后端
LaoZhangAI4 小时前
Google Gemini Nano与Banana AI完整部署指南:2025年轻量级AI解决方案
前端·后端
用户11481867894844 小时前
基于 Webpack Module Federation 的 Vue 微前端实践
前端
怪可爱的地球人4 小时前
Pinia状态管理有哪些常用API?
前端
小高0074 小时前
🤔函数柯里化:化繁为简的艺术与实践
前端·javascript·面试
却尘4 小时前
React useMemo 依赖陷阱:组件重挂载,状态无限复原
前端·javascript·react.js
Asort4 小时前
JavaScript 从零开始(三):浏览器控制台与VS Code协同工作环境搭建详解
前端·javascript
跟橙姐学代码4 小时前
自动化邮件发送的终极秘籍:Python库smtplib与email的完整玩法
前端·python·ipython