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);
}
相关推荐
Cao_Ron7 分钟前
用 SVG image symbol 画 ECharts graph 圆形节点
前端
hxy060111 分钟前
React-Call让你的React组件像异步函数一样调用
前端·react.js
Hilaku12 分钟前
为什么 AI 写前端时,总是优先选择 React,而不是 Vue?
前端·javascript·程序员
京东云开发者14 分钟前
GPT-5.6、ChatGPT Work 与 Codex 更新食用指南
前端
Cao_Ron25 分钟前
用 ECharts graph 画出卡片式矩形节点
前端
skiyee34 分钟前
换个底座的 Wot Starter 居然让 AI 更懂项目!
前端·ai编程
anyup40 分钟前
这一套绝了!AI 大模型写故事,星云 SDK 驱动 3D 数字人实时演绎
前端·人工智能·aigc
耀耀切克闹灬1 小时前
短链跳转
前端
孟陬1 小时前
高质量全方位的 AI 工具 sse-stuntman — Mock SSE 接口
前端·node.js·openai
Cao_Ron1 小时前
给 ECharts 6 graph 节点叠加角标:从原理到性能优化
前端