这篇文章给大家分享一个 ​​Cesium​​ 实现的飞机漫游飞行的效果

前置准备

案例中采用 ​​Vue3​​​ 来搭建,还不会搭建 ​​Vue3​​​ ​​脚手架​​的同学可以看下我之前的文章:

Vite2 + Vue3 + TypeScript + Pinia 搭建一套企业级的开发脚手架【值得收藏】

本文的主题是讲解 ​​实现一个飞机飞行效果​​ , 搭建过程这里不做过多的介绍.

安装 Cesium

安装方式有​​两种​​:

第一种是使用 ​​npm​​ 方式来安装

npm i cesium --save

在项目根目录新增配置文件 ​​vue.config.js​​ ,如下

const CopyWebpackPlugin = require('copy-webpack-plugin')
const webpack = require('webpack')
const path = require('path')

const debug = process.env.NODE_ENV !== 'production'
let cesiumSource = './node_modules/cesium/Source'
let cesiumWorkers = '../Build/Cesium/Workers'
module.exports = {
baseUrl: '',
devServer: {
port: 8090 //修改服务端口号
},
outputDir: 'docs', //设置 build 输出目录
configureWebpack: {
output: {
sourcePrefix: ' '
},
amd: {
toUrlUndefined: true
},
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js',
'@': path.resolve('src'),
'cesium': path.resolve(__dirname, cesiumSource)
}
},
plugins: [
new CopyWebpackPlugin([ { from: path.join(cesiumSource, cesiumWorkers), to: 'Workers'}]),
new CopyWebpackPlugin([ { from: path.join(cesiumSource, 'Assets'), to: 'Assets'}]),
new CopyWebpackPlugin([ { from: path.join(cesiumSource, 'Widgets'), to: 'Widgets'}]),
new CopyWebpackPlugin([ { from: path.join(cesiumSource, 'ThirdParty/Workers'), to: 'ThirdParty/Workers'}]),
new webpack.DefinePlugin({
CESIUM_BASE_URL: JSON.stringify('./')
})
],
module: {
unknownContextCritical: /^.\/.*$/,
unknownContextCritical: false

}
}
}

​main.js​​ 中新增引用

import Cesium from 'cesium/Cesium' //from 中 cesium 指向的是vue.config.js中 alias对象中的别名
// noinspection ES6UnusedImports
import widget from 'cesium/Widgets/widgets.css'

第二种直接下载官方的包引入

下载地址:​​https://cesium.com/platform/cesiumjs/​

本文讲解的案例使用的第二种方式,直接下载后放到项目的 ​​public​​ 文件夹下


Cesium 实现一个 飞机漫游 飞行效果_css

在 ​​index.html​​ 中直接引入即可

<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= htmlWebpackPlugin.options.title %></title>
<!-- 引入 cesium -->
<script src="./cesium/Build/Cesium/Cesium.js"></script>
<link rel="stylesheet" href="./cesium/Build/Cesium/Widgets/widgets.css">

</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>


Cesium 初始化

新建一个 ​​vue​​​ 组件,用于初始化 ​​Cesium​

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

<script setup>
import { onMounted } from "vue";

const token ="token自己注册账号申请即可";

onMounted(() => {
Cesium.Ion.defaultAccessToken = token;

var viewer = new Cesium.Viewer("cesiumContainer", {
animation: true, //是否创建动画小器件,左下角仪表
shouldAnimate: true,
baseLayerPicker: true, //是否显示图层选择器
fullscreenButton: true, //是否显示全屏按钮
geocoder: true, //是否显示geocoder小器件,右上角查询按钮
homeButton: true, //是否显示Home按钮
infoBox: true, //是否显示信息框
sceneModePicker: true, //是否显示3D/2D选择器
selectionIndicator: true, //是否显示选取指示器组件
timeline: true, //是否显示时间轴
navigationHelpButton: true, //是否显示右上角的帮助按钮
scene3DOnly: true, //如果设置为true,则所有几何图形以3D模式绘制以节约GPU资源
clock: new Cesium.Clock(), //用于控制当前时间的时钟对象
selectedImageryProviderViewModel: undefined, //当前图像图层的显示模型,仅baseLayerPicker设为true有意义
imageryProviderViewModels: Cesium.createDefaultImageryProviderViewModels(), //可供BaseLayerPicker选择的图像图层ProviderViewModel数组
selectedTerrainProviderViewModel: undefined, //当前地形图层的显示模型,仅baseLayerPicker设为true有意义
terrainProviderViewModels: Cesium.createDefaultTerrainProviderViewModels(), //可供BaseLayerPicker选择的地形图层ProviderViewModel数组
terrainProvider: new Cesium.EllipsoidTerrainProvider(), //地形图层提供者,仅baseLayerPicker设为false有意义
fullscreenElement: document.body, //全屏时渲染的HTML元素,
useDefaultRenderLoop: true, //如果需要控制渲染循环,则设为true
targetFrameRate: undefined, //使用默认render loop时的帧率
showRenderLoopErrors: false, //如果设为true,将在一个HTML面板中显示错误信息
automaticallyTrackDataSourceClocks: true, //自动追踪最近添加的数据源的时钟设置
contextOptions: undefined, //传递给Scene对象的上下文参数(scene.options)
sceneMode: Cesium.SceneMode.SCENE3D, //初始场景模式
mapProjection: new Cesium.WebMercatorProjection(), //地图投影体系
dataSources: new Cesium.DataSourceCollection(),
//需要进行可视化的数据源的集合
});
});
</script>

效果如下:

Cesium 实现一个 飞机漫游 飞行效果_css_02

加载 CZML 数据

什么是 CZML 数据呢

  • CZML 是 cesium 中很重要的一个概念,也是一个亮点,​​CZML​​ 使得 ​​cesium​​ 很酷很炫地展示​​动态数据​​成为可能。
  • CZML 是一种​​JSON​​ 格式的字符串,用于描述与​​时间​​有关的​​动画​​场景,CZML 包含​​点​​、​​线​​、​​地标​​、​​模型​​、和其他的一些​​图形元素​​,并指明了这些元素如何​​随时间​​而变化。某种程度上说, Cesium 和 CZML 的关系就像 Google Earth 和 KML。
  • CZML 的一个典型结构如下。片段描述了两个包(​​packet​​,这里每个包描述了一个点),每个包的 ​​id​​,​​position​​ 和 ​​color​​。
  • CZML 比较特殊的是​​跟时间序列​​相关的属性
[
{
id: "document",
version: "1.0",
clock: {
interval: "2018-07-19T15:18:00Z/2018-07-19T15:18:30Z", // 开始时间-结束时间
currentTime: "2018-07-19T15:18:00Z", // 当前时间
multiplier: 5, // 轨迹运行的速度
range: "LOOP_STOP",
step: "SYSTEM_CLOCK_MULTIPLIER",
},
},
{
id: "CesiumMilkTruck",
model: {
gltf: "/Cesium_Air.glb",
},
// 位置信息
position: {
interpolationAlgorithm: "LINEAR", //插值算法
forwardExtrapolationType: "HOLD", //插值算法
cartesian: [
"2018-07-19T15:18:00Z",
1216348.1632364073,
-4736348.958775471,
4081284.5528982095,
"2018-07-19T15:18:30Z",
1216369.1229444197,
-4736377.467107148,
4081240.888485707,
],
},
// 模型方向信息
orientation: {
velocityReference: "#position",
// unitQuaternion: [
// 0.3084011337938999, 0.3210181022701266, -0.45850421987074924,
// 0.7686388857813198,
// ],
},
},
{
id: "Polyline",
polyline: {
positions: {
cartesian: [
1216348.1632364073, -4736348.958775471, 4081284.5528982095,
1216369.1229444197, -4736377.467107148, 4081240.888485707,
],
},
material: {
polylineOutline: {
color: {
rgba: [255, 255, 0, 255],
},
outlineColor: {
rgba: [0, 0, 0, 255],
},
outlineWidth: 2,
},
},
width: 10,
clampToGround: true, // 线条紧贴地面
},
},
];

如何加载

贴心的 ​​Cesium​​ 已经给我们提供好了加载的方法,不需要我们做任何特殊的处理

// 加载 CZML
const dataSourcePromise = viewer.dataSources.add(
Cesium.CzmlDataSource.load(czml)
);
// 加载完成后移动相机跟踪目标
dataSourcePromise.then(function (dataSource) {
viewer.trackedEntity = dataSource.entities.getById("CesiumMilkTruck");
});

点赞就是最大的支持❤️