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

相关推荐
腾讯TNTWeb前端团队8 分钟前
helux v5 发布了,像pinia一样优雅地管理你的react状态吧
前端·javascript·react.js
范文杰4 小时前
AI 时代如何更高效开发前端组件?21st.dev 给了一种答案
前端·ai编程
拉不动的猪4 小时前
刷刷题50(常见的js数据通信与渲染问题)
前端·javascript·面试
拉不动的猪4 小时前
JS多线程Webworks中的几种实战场景演示
前端·javascript·面试
FreeCultureBoy4 小时前
macOS 命令行 原生挂载 webdav 方法
前端
uhakadotcom5 小时前
Astro 框架:快速构建内容驱动型网站的利器
前端·javascript·面试
uhakadotcom5 小时前
了解Nest.js和Next.js:如何选择合适的框架
前端·javascript·面试
uhakadotcom5 小时前
React与Next.js:基础知识及应用场景
前端·面试·github
uhakadotcom5 小时前
Remix 框架:性能与易用性的完美结合
前端·javascript·面试
uhakadotcom5 小时前
Node.js 包管理器:npm vs pnpm
前端·javascript·面试