当前位置: 首页 > article >正文

cesium.js 入门到精通(7)

我们说一下相机的概念:

生活中的相机是一个用来拍照的设备,而这里的相机应该理解成一个人机交互的媒介。地图的缩放、平移、旋转,以及相关的鼠标操作都是由相机作为媒介来实现的。相机的位置和姿态参数决定了我们能看到的地图的样子。

可以把使用 Cesium 浏览地图的过程想象成这样一个场景:

一个带有相机的能实时传回拍摄画面的无人机在地球上空飞翔。当我们在 Cesium 程序上操作鼠标的时候,无人机就会执行相关的飞行动作,并实时拍摄照片回传到程序,于是我们看到了预期的地图。在这个过程中,无人机的姿态、位置决定了相机的位置,从而决定了我们能看到什么样的地图。

二、理解相机常用参数

相机由位置(position)、姿态(orientation)和视锥体(frustum)定义。[1]

相机的三个关键参数中 position、orientation 最常用,其中 orientation 不太好理解。

orientation 由 headingpitchroll 三个参数构成,他们的单位都是弧度。在 Camera API 中没有 orientation 属性,只有 headingpitchroll 三个相关的属性。这三个属性怎么理解呢?看一张图就明白了。

假设把人绑在相机上,差不多就是这个效果。

三个姿态参数的含义以及取值范围如下:

heading: 相机的偏航角。取值范围 [-π/2π/2]。

取值及其效果:

  • -π/2 :向左旋转 90 度;
  • -π/4 :向左旋转45度;
  • 0 :不旋转;
  • π/2 :向右旋转 90 度;
  • π/4 :向右旋转45度;

pitch: 相机的俯仰角。取值范围 [-π/20]。

取值及其效果:

  • -π/2 :俯视地面;
  • -π/4 :斜向下45度俯视地面;
  • 0 :平视前方,将看不到地图;

roll: 相机的翻滚角。取值范围 [0π]。

取值一般都是 0 。

三、调用相机功能的方式

1. 直接调用

可以从 Viewer 和 Scene 的实例上获取到相机实例,然后实现相关功能。

  • 从 Viewer 实例上获取:viewer.camera
  • 从 Scene 实例上获取:scene.camera

测试发现从 Viewer 和 Scene 的实例中获取到的相机对象是一样的。

Cesium 中有相机类,但是使用时一般不会去执行 new Camera()

2. 间接调用

有些时候,不用获取相机实例也可调用相机的功能。例如viewer.flyToviewer.zoomTo 等。

<template>
  <div id="cesiumContainer" ref="cesiumContainer"></div>
</template>

<script setup>
// yarn add cesium
// 将cesium目录下的Build/Cesium4个目录拷贝到public,然后将widgets目录拷贝一份到src下
import * as Cesium from "cesium";
import "./Widgets/widgets.css";
import { onMounted } from "vue";

// 设置cesium token
Cesium.Ion.defaultAccessToken =
  "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJhMzNkNTE5Zi1mMjY4LTRiN2QtOTRlZC1lOTUyM2NhNDYzNWYiLCJpZCI6NTU0OTYsImlhdCI6MTYyNTAyNjMyOX0.a2PEM4hQGpeuMfeB9-rPp6_Gkm6O-02Dm4apNbv_Dlk";

// 设置cesium静态资源路径
window.CESIUM_BASE_URL = "/";

// 设置cesium默认视角
Cesium.Camera.DEFAULT_VIEW_RECTANGLE = Cesium.Rectangle.fromDegrees(
  // 西边的经度
  89.5,
  // 南边维度
  20.4,
  // 东边经度
  110.4,
  // 北边维度
  61.2
);

onMounted(() => {
  var viewer = new Cesium.Viewer("cesiumContainer", {
    // 是否显示信息窗口
    infoBox: false,
  });

  // 隐藏logo
  viewer.cesiumWidget.creditContainer.style.display = "none";

  // setview瞬间到达指定位置,视角
  // 生成position是天安门的位置
  var position = Cesium.Cartesian3.fromDegrees(116.393428, 39.90923, 100);
  // viewer.camera.setView({
  //   // 指定相机位置
  //   destination: position,
  //   // 指定相机视角
  //   orientation: {
  //     // 指定相机的朝向,偏航角
  //     heading: Cesium.Math.toRadians(0),
  //     // 指定相机的俯仰角,0度是竖直向上,-90度是向下
  //     pitch: Cesium.Math.toRadians(-20),
  //     // 指定相机的滚转角,翻滚角
  //     roll: 0,
  //   },
  // });

  // flyto,让相机飞往某个地方
  viewer.camera.flyTo({
    destination: position,
    orientation: {
      heading: Cesium.Math.toRadians(0),
      pitch: Cesium.Math.toRadians(-20),
      roll: 0,
    },
  });
});
</script>

<style>
* {
  margin: 0;
  padding: 0;
}
#cesiumContainer {
  width: 100vw;
  height: 100vh;
}
</style>

我直接让这个 相机 飞到 天安门广场了

在 CesiumJS 中,viewer.camera.setView() 和 viewer.camera.flyTo() 是两个用于控制相机位置和视角的函数,但它们的行为有所不同。

  1. viewer.camera.setView():这个函数会立即将相机的位置和视角设置到指定的位置。它不会创建平滑的过渡效果,而是直接跳转到新的位置和视角。这对于需要立即改变视图而不希望用户看到过渡过程的场景很有用。

     

    javascript复制代码

    viewer.camera.setView({
    destination: position, // 指定相机位置
    orientation: {
    heading: Cesium.Math.toRadians(0), // 相机朝向的偏航角(东向为0度)
    pitch: Cesium.Math.toRadians(-20), // 相机视角的俯仰角(竖直向上为0度,-90度为向下)
    roll: 0, // 相机视角的滚转角(翻滚角)
    }
    });
  2. viewer.camera.flyTo():这个函数会使相机平滑地飞往指定的位置和视角。它会创建一个过渡效果,使得相机从当前位置和视角逐渐变化到新的位置和视角。这对于提高用户体验,让用户看到从一个地点到另一个地点的移动过程非常有用。

     

    javascript复制代码

    viewer.camera.flyTo({
    destination: position, // 指定相机飞往的目的地位置
    orientation: {
    heading: Cesium.Math.toRadians(0), // 相机朝向的偏航角
    pitch: Cesium.Math.toRadians(-20), // 相机视角的俯仰角
    roll: 0, // 相机视角的滚转角
    },
    // 还可以添加其他参数,如持续时间(duration)来控制飞行时间
    });

注意

  • Cesium.Math.toRadians() 函数用于将角度从度转换为弧度,因为 CesiumJS 内部使用弧度作为角度的度量单位。
  • 在使用 flyTo() 方法时,可以通过添加额外的参数(如 duration)来控制飞行过渡的持续时间,以毫秒为单位。如果不指定,Cesium 会使用默认的飞行时间。
  • position 变量应该是一个 Cesium.Cartesian3 类型的对象,表示相机要飞往的地球表面或空间中的位置。你可以通过经纬度(使用 Cesium.Cartesian3.fromDegrees())或其他方式计算这个位置。

选择使用 setView() 还是 flyTo() 取决于你的具体需求,是需要立即改变视图还是需要一个平滑的过渡效果。


http://www.kler.cn/news/303474.html

相关文章:

  • 修改centos7系统语言en_US.UTF-8为中文zh_CN.UTF-8
  • 高防服务器的优势与劣势分析
  • 【LLM:Fan】
  • 踩坑记:Poco库,MySql,解析大文本的bug
  • 递归、排序、二分查找(C语言实现)
  • mybatis与concat实现模糊查询、mybatis中模糊查询concat传入参数为空时的解决方法
  • nacos安装使用调优及面试题分享
  • Apple发布会都有哪些亮点?如何在苹果手机和电脑上录制屏幕?
  • MATLAB默认工作路径修改
  • 串口通信数据包介绍和包结构定义实例
  • 【Echarts】vue3打开echarts的正确方式
  • real, dimension(3) :: rho1 和 real :: rho1(3) 的区别
  • C++学习笔记----7、使用类与对象获得高性能(一)---- 书写类(1)
  • element表格合并列数据相同合并单元格
  • 【Flutter 面试题】 无需上下文进行路由跳转原理是怎么样的
  • Python用MarkovRNN马尔可夫递归神经网络建模序列数据t-SNE可视化研究
  • 医疗报销|基于springboot的医疗报销系统设计与实现(附项目源码+论文+数据库)
  • RocketMQ 集群搭建详细指南
  • F12抓包10:UI自动化 - Elements(元素)定位页面元素
  • 【devops】devops-git之git分支与标签使用
  • Kubernetes 容器与镜像管理
  • 五、Django 路由配置
  • 如何编写ChatGPT提示词
  • LabVIEW中EPICS客户端/服务端的测试
  • 数据库系统概论(3,4)
  • 【网络安全】漏洞挖掘之会话管理缺陷
  • Layout 布局组件快速搭建
  • 如何建设数据中台(五)——数据汇集—打破企业数据孤岛
  • Android 12.0 Launcher修改density禁止布局改变功能实现
  • 【C++题解】1398. 奇偶统计