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

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,});// 隐藏logoviewer.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() 取决于你的具体需求,是需要立即改变视图还是需要一个平滑的过渡效果。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • springboot013基于SpringBoot的旅游网站的设计与实现
  • 做谷歌seo,b端跟c端有什么区别吗?
  • 【笔记】CarrierConfig 解析加载的debug和日志分析
  • 高亚科技与广东海悟携手,打造全流程电子竞标管理平台!
  • 利用高德+ArcGIS优雅获取任何感兴趣的矢量边界
  • 云服务器拉取docker镜像
  • Redis学习笔记(六)——Redis的持久化
  • flink中disableChaining() 的详解
  • mfc140u.dll错误是什么情况?如何将mfc140u.dll丢失的解决方法详细分析
  • Arduino IDE离线配置第三方库文件-ESP32开发板
  • C++提高--模板(类模板/函数模板)
  • 数据库第一章:库的操作
  • linux-IO-进程-线程(相关函数)
  • Apache POI用法
  • 云原生应用——软件的未来
  • 【5+】跨webview多页面 触发事件(二)
  • 【许晓笛】 EOS 智能合约案例解析(3)
  • CSS中外联样式表代表的含义
  • linux安装openssl、swoole等扩展的具体步骤
  • Netty 框架总结「ChannelHandler 及 EventLoop」
  • October CMS - 快速入门 9 Images And Galleries
  • Python十分钟制作属于你自己的个性logo
  • Shadow DOM 内部构造及如何构建独立组件
  • Vue官网教程学习过程中值得记录的一些事情
  • 安卓应用性能调试和优化经验分享
  • 表单中readonly的input等标签,禁止光标进入(focus)的几种方式
  • 翻译 | 老司机带你秒懂内存管理 - 第一部(共三部)
  • 反思总结然后整装待发
  • 基于webpack 的 vue 多页架构
  • 解决iview多表头动态更改列元素发生的错误
  • 让你成为前端,后端或全栈开发程序员的进阶指南,一门学到老的技术
  • 如何抓住下一波零售风口?看RPA玩转零售自动化
  • 好程序员web前端教程分享CSS不同元素margin的计算 ...
  • 智能情侣枕Pillow Talk,倾听彼此的心跳
  • ​Java基础复习笔记 第16章:网络编程
  • $ git push -u origin master 推送到远程库出错
  • (7)STL算法之交换赋值
  • (Oracle)SQL优化基础(三):看懂执行计划顺序
  • (搬运以学习)flask 上下文的实现
  • (分布式缓存)Redis分片集群
  • (附源码)springboot掌上博客系统 毕业设计063131
  • (附源码)ssm本科教学合格评估管理系统 毕业设计 180916
  • (附源码)计算机毕业设计SSM保险客户管理系统
  • (三分钟了解debug)SLAM研究方向-Debug总结
  • (一)VirtualBox安装增强功能
  • (转)关于多人操作数据的处理策略
  • .NET 4.0中的泛型协变和反变
  • .NET CF命令行调试器MDbg入门(三) 进程控制
  • .net framework4与其client profile版本的区别
  • .NET 中 GetHashCode 的哈希值有多大概率会相同(哈希碰撞)
  • .net(C#)中String.Format如何使用
  • .NET/ASP.NETMVC 大型站点架构设计—迁移Model元数据设置项(自定义元数据提供程序)...
  • .net获取当前url各种属性(文件名、参数、域名 等)的方法
  • @require_PUTNameError: name ‘require_PUT‘ is not defined 解决方法
  • [ C++ ] 继承