Cesium 中拾取 3DTiles 交点坐标

javascript 复制代码
   this.handler.setInputAction(
          (e: Cesium.ScreenSpaceEventHandler.PositionedEvent) => {
            this.CloseDelete()
            this.MapLeftClick(e)
          },
          Cesium.ScreenSpaceEventType.LEFT_CLICK,
        )
javascript 复制代码
 private MapLeftClick(e: Cesium.ScreenSpaceEventHandler.PositionedEvent) {
    const r = this.GetPickAndPosition(e.position)
 // var cartesian2Coordinates = e.position;//获取鼠标位置的屏幕坐标
        // var ray = this.viewer.camera.getPickRay(cartesian2Coordinates);//生成射线:
        // var pickedObject = this.viewer.scene.pick(ray);//该方法会返回射线与场景中对象的交点信息
        // 方法2:直接拾取3DTiles特征
        const pickedFeature = this.viewer.scene.pick(e.position);
        let earthPosition = null
        if (pickedFeature && pickedFeature.primitive instanceof Cesium.Cesium3DTileset) {
          // 获取点击位置的世界坐标
           earthPosition = this.viewer.scene.pickPosition(e.position);
          // this.pointsList.push(earthPosition)
          console.log('earthPosition', earthPosition);
          if (Cesium.defined(earthPosition)) {
            console.log('ooooookkkkkk', earthPosition);
          }
          if (earthPosition) {
            // 转换为经纬度
            const cartographic = Cesium.Cartographic.fromCartesian(earthPosition);
            const longitude = Cesium.Math.toDegrees(cartographic.longitude).toFixed(6);
            const latitude = Cesium.Math.toDegrees(cartographic.latitude).toFixed(6);
            const height = cartographic.height.toFixed(2);

            console.log(`交点坐标: 经度 ${longitude}°, 纬度 ${latitude}°, 高度 ${height}米`);

            // 在点击位置添加点标记
            this.viewer.entities.add({
              position: cartesian,
              point: {
                pixelSize: 10,
                color: Cesium.Color.RED,
                outlineColor: Cesium.Color.WHITE,
                outlineWidth: 2
              },
              label: {
                text: `(${longitude}, ${latitude}, ${height})`,
                font: '14pt monospace',
                style: Cesium.LabelStyle.FILL_AND_OUTLINE,
                outlineWidth: 2,
                verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
                pixelOffset: new Cesium.Cartesian2(0, -10)
              }
            });
}
  1. Cesium.defined():

    • 这是 Cesium 提供的一个工具函数,用于安全地检查变量是否已定义且不为 nullundefined

    • 相当于 earthPosition !== undefined && earthPosition !== null 的简写

    • 更健壮,可以避免 JavaScript 的某些边缘情况

  2. 判断逻辑:

    • 只有当 earthPosition 存在(已定义且非 null)时,才会执行花括号内的代码

    • 如果 earthPositionundefinednull 或未声明,条件判断会返回 false

方法 适用对象 特点 典型场景
viewer.scene.pick(ray) 场景中所有可拾取对象(3D Tiles、模型、实体等) 返回包含对象信息的PickedObject(含位置、对象类型等) 需区分拾取的是 3D 模型、实体还是其他对象时
viewer.scene.pickPosition(ray) 场景中所有可交互对象(包括 3D Tiles、地球表面等) 直接返回交点坐标(Cartesian3),不区分对象类型 仅需坐标,不关心拾取的是模型还是地表时
viewer.scene.globe.pick(ray, scene) 仅地球表面(globe) 强制拾取地表坐标,忽略 3D 模型遮挡(除非模型在地下) 专门需要获取地表坐标时(如地形测量)
javascript 复制代码
  private GetPickAndPosition(sp: Cesium.Cartesian2) {
    const pick = this.viewer.scene.pick(sp)//场景中所有可拾取对象(3D Tiles、模型、实体等)返回包含对象信息的PickedObject(含位置、对象类型等)
    let ray = this.viewer.camera.getPickRay(sp) as any;//场景中所有可交互对象(包括 3D Tiles、地球表面等)
    let tp = this.viewer.scene.globe.pick(ray, this.viewer.scene);//仅地球表面(globe)
    return { pick, tp }

  }
相关推荐
linweidong1 小时前
C++ 模块化编程(Modules)在大规模系统中的实践难点?
linux·前端·c++
leobertlan4 小时前
2025年终总结
前端·后端·程序员
子兮曰5 小时前
OpenClaw架构揭秘:178k stars的个人AI助手如何用Gateway模式统一控制12+通讯频道
前端·javascript·github
百锦再5 小时前
Reactive编程入门:Project Reactor 深度指南
前端·javascript·python·react.js·django·前端框架·reactjs
莲华君5 小时前
React快速上手:从零到项目实战
前端·reactjs教程
百锦再5 小时前
React编程高级主题:测试代码
android·前端·javascript·react.js·前端框架·reactjs
易安说AI6 小时前
Ralph Loop 让Claude无止尽干活的牛马...
前端·后端
颜酱7 小时前
图结构完全解析:从基础概念到遍历实现
javascript·后端·算法
失忆爆表症7 小时前
05_UI 组件库集成指南:Shadcn/ui + Tailwind CSS v4
前端·css·ui
小迷糊的学习记录7 小时前
Vuex 与 pinia
前端·javascript·vue.js