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 }

  }
相关推荐
有事没事实验室17 分钟前
书写腾讯天气遇到的问题
前端·css·html
xulihang19 分钟前
如何在网页中嵌入PDF
前端·javascript·html
玖伍贰零壹肆24 分钟前
前端偶尔需要—Vue3+Vuetify国际化
前端
玊米粒24 分钟前
基础交互 三目运算 if、switch、while 、do while、for、continue、break
javascript
张元清25 分钟前
二分查找的艺术:`left <= right` 与 `left < right` 的终极抉择
前端·javascript·算法
蒋星熠1 小时前
Vue 3 + TypeScript 现代前端开发最佳实践(2025版指南)
前端·vue.js·人工智能·pytorch·深度学习·ai·typescript
狂炫一碗大米饭1 小时前
JavaScript 中 Fetch API 的完整指南
前端·api
coding随想1 小时前
还没用过就要被弃用了?深度解析浏览器中的App Cache缓存管理事件
前端
Flyfreelylss1 小时前
前端实现解析【导入】数据后调用批量处理接口
前端·reactjs
小彭努力中1 小时前
164.在 Vue3 中使用 OpenLayers 加载 Esri 地图(多种形式)
开发语言·前端·javascript·vue.js·arcgis