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 }

  }
相关推荐
Rhi63719 分钟前
从零搭建项目:React 19 + Vite 8 + Tailwind CSS v4 实战配置
前端
竹林81826 分钟前
用Viem替代ethers.js:从一次签名失败到完整迁移的实战记录
前端·javascript
之歆31 分钟前
DAY08_CSS浮动与行内块布局实战指南(上)
前端·css
light blue bird1 小时前
主子端台二分法任务汇总组件
前端·数据库·.net·桌面端winform
不可能的是2 小时前
Claude Code 子 Agent 机制全解:怎么跑起来、怎么被管理、怎么互不干扰
javascript
jeffwang2 小时前
我做了个让 AI 看屏幕跑测试的工具,因为 Playwright 测不了我的 Flutter Web
前端
HSunR2 小时前
dify 搭建ai作业批改流
开发语言·前端·javascript
代码不加糖2 小时前
2026 跨境电商独立站实战:从 0 到 1 搭建高转化 SaaS 商城(附源码)
开发语言·前端·javascript
亲亲小宝宝鸭3 小时前
拖一拖控件,拖出个问卷(低代码平台)
前端·低代码
江南十四行3 小时前
ReAct Agent 基本理论与项目实战(一)
前端·react.js·前端框架