Cesium使用flyToBoundingSphere实现倾斜相机视角观察物体

之前有一篇文章介绍如何使用Cesium倾斜相机视角观察物体,后面发现了一个API viewer.camera.flyToBoundingSphere,能直接实现我想要的效果。

所以我封装了一个函数,通过使用 Cesium.Camera.flyToBoundingSphere API,自动调整相机的位置和视角,实现相机飞向指定的包围球并观察目标物体的效果。该函数可根据目标的边界自动计算最佳的相机距离,实现便捷的倾斜视角观察。

功能特点

  • 自动计算目标的包围球并调整相机距离
  • 支持自定义相机俯仰角和缩放因子
  • 使用 Promise 异步处理,操作完成后触发回调

参数说明

参数 类型 默认值 必填 说明
boundary Array 边界点数组,每两个元素表示一个经纬度坐标
pitch Number 相机俯仰角(以度为单位),用于设置相机观察角度
scaleFactor Number 0.5 缩放因子,用于调整目标在视野中的大小

返回值

返回一个 Promise 对象,在相机飞行完成后解析。

示例代码

javascript 复制代码
// 使用示例
flyToBoundingSphere({
  boundary:[116.3913, 39.9075, 116.4013, 39.9175], // 北京坐标示例
  pitch: 45, // 设置俯仰角为45度
  scaleFactor: 0.7 // 缩小视图中的物体大小
}).then(() => {
  console.log('相机飞行完成');
}).catch(error => {
  console.error('相机飞行失败:', error);
});

函数源码

js 复制代码
/**
 * 将相机飞向指定的包围球,并自动调整相机位置和视角。
 * 
 * @param {Object} options - 配置选项
 * @param {Array} options.boundary - 边界点数组,每两个元素表示一个经纬度坐标
 * @param {Number} options.pitch - 相机俯仰角(以度为单位)
 * @param {Number} [options.scaleFactor=0.5] - 缩放因子,用于调整目标的观察大小
 * @returns {Promise} - 返回一个Promise对象,在相机飞行完成后解析
 */
function flyToBoundingSphere(options) {
  return new Promise((resolve, reject) => {
    try {
      const { boundary, pitch, scaleFactor = 0.5 } = options;

      const boundingSphere = getBoundingSphere(boundary);

      // 调整包围球的半径,根据 scaleFactor 放大或缩小视图中的物体大小
      boundingSphere.radius *= 1 / scaleFactor;
      // 计算合适的相机高度
      const distance =
        boundingSphere.radius / Math.sin(viewer.camera.frustum.fov / 2);

      // 自动调整相机以确保包围球在视野内
      viewer.camera.flyToBoundingSphere(boundingSphere, {
        duration: 2, // 单位秒
        offset: new Cesium.HeadingPitchRange(
          Cesium.Math.toRadians(360),
          Cesium.Math.toRadians(pitch), // 设置相机俯仰角
          distance, // 计算合适的距离
        ),
        complete: () => {
          resolve();
        },
      });
    } catch (e) {
      reject(e);
    }
  });
}

/**
 * 计算包含指定边界点的包围球。
 *
 * @param {Array} boundary - 边界点数组,每两个元素表示一个经纬度坐标
 * @returns {Cesium.BoundingSphere} - 包围球对象
 */
function getBoundingSphere(boundary) {
  // 将边界点转换为 Cartesian3 坐标
  const positions = [];
  for (let i = 0; i < boundary.length; i += 2) {
    const lon = boundary[i];
    const lat = boundary[i + 1];
    const position = Cesium.Cartesian3.fromDegrees(lon, lat);
    positions.push(position);
  }

  // 计算包含所有边界点的包围球
  return Cesium.BoundingSphere.fromPoints(positions);
}
相关推荐
优雅永不过时·2 分钟前
three.js实现地球 外部扫描的着色器
前端·javascript·webgl·three.js·着色器
peachSoda71 小时前
随手记:鼠标触顶方法
前端·javascript·vue.js
疯狂的沙粒1 小时前
Vue项目开发 formatData 函数有哪些常用的场景?
前端·javascript·vue.js
逆旅行天涯1 小时前
【功能实现】bilibili顶部鼠标跟随效果怎么实现?
前端·javascript·vue
毛毛三由1 小时前
【10分钟学习Vue自定义指令开发】鼠标放置提示指令
前端·javascript·vue.js
一秒美工助手1 小时前
鼠标经过遮罩效果 详情页阿里巴巴国际站外贸跨境电商装修运营 详情页装修无线端装修手机装修设计代码证书滚动特效效果代码,自定义内容代码模板模块设计设置装修
前端·javascript·html·计算机外设
桑榆肖物2 小时前
将 .NET Aspire 添加到现有应用:前端 JavaScript 项目处理
前端·javascript·.net
Wh1teR0se4 小时前
[极客大挑战 2019]Secret File--详细解析
前端·web安全·网络安全
ZhaiMou5 小时前
HTML5拖拽API学习 托拽排序和可托拽课程表
前端·javascript·学习·html5
code_shenbing8 小时前
跨平台WPF框架Avalonia教程 三
前端·microsoft·ui·c#·wpf·跨平台·界面设计