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 }

  }
相关推荐
llq_3503 分钟前
pnpm / Yarn / npm 覆盖依赖用法对比
前端
麦当_6 分钟前
ReAct 模式在 Neovate 中的应用
前端·javascript·架构
折七6 分钟前
告别传统开发痛点:AI 驱动的现代化企业级模板 Clhoria
前端·后端·node.js
程序0077 分钟前
纯html实现商品首页
前端
coderlin_7 分钟前
BI磁吸布局 (2) 基于react-grid-layout扩展的布局方式
前端·react.js·前端框架
Ankkaya9 分钟前
vue3 实现自定义模板表单打印
前端
itslife10 分钟前
vite源码 - 开始
前端·javascript
Achieve - 前端实验室10 分钟前
【每日一面】React Hooks闭包陷阱
前端·javascript·react.js
张愚歌11 分钟前
Leaflet行政区划边界开发全攻略
前端
Asort12 分钟前
JavaScript设计模式(四)——建造者模式:优雅构建复杂对象的实用指南
前端·javascript·设计模式