为了方便用户能够直观的浏览三维模型上的所有位置点位,具体的实现思路是:
1、首先将所有的位置点按照一定的路线顺序排列好;
2、接着以第一人称视角开始漫游所设定的路线图;
3、设置飞行、继续、暂停及退出漫游飞行的状态。
具体参考可见:【Cesium开发实战】飞行漫游功能的实现,可设置漫游路径,漫游高度,暂停,继续,删除路径...-优快云博客
实现代码如下:
var airplaneEntity = null
var timeStepInSeconds = 7
const positionProperty = new Cesium.SampledPositionProperty();
//开始飞行
startFly () {
//飞行的时候,飞行按钮、继续按钮置灰不可点击
this.start = true
this.pause = false
this.keepup = true
this.stop = false
this.showSelect = true
// 当下个飞行前清除上次的飞行对象和路径
if (airplaneEntity != null) {
viewer.entities.remove(airplaneEntity)
}
// 获取飞行的路径线路
const positions = []
for (let i = 0; i < this.options.length; i++) {
const position = {
longitude: this.options[i].longitude,
latitude: this.options[i].ydbWeiDu,
height: 1000
}
positions.push(position)
}
const flightData = positions;
//timeStepInSeconds表示在每个位置点的停留时间
const totalSeconds = (flightData.length) * timeStepInSeconds
// 设置起点时间
const time = new Date('2020-03-09T23:10:00Z')
const start = Cesium.JulianDate.fromDate(time)
// 设置终点时间
const stop = Cesium.JulianDate.addSeconds(start, totalSeconds, new Cesium.JulianDate())
viewer.clock.startTime = start.clone()
viewer.clock.stopTime = stop.clone()
viewer.clock.currentTime = start.clone()
for (let i = 0; i < flightData.length; i++) {
const dataPoint = flightData[i]
// 采样时间
const time = Cesium.JulianDate.addSeconds(start, i * timeStepInSeconds, new Cesium.JulianDate())
// 计算当前的3D坐标
const position = Cesium.Cartesian3.fromDegrees(dataPoint.longitude, dataPoint.latitude, dataPoint.height)
// 添加轨迹采样点
positionProperty.addSample(time, position)
}
// 创建飞机模型
airplaneEntity = viewer.entities.add({
availability: new Cesium.TimeIntervalCollection([
new Cesium.TimeInterval({
start: start,
stop: stop
})
]),
position: positionProperty,
model: {
uri: '/model/glb/Cesium_Air.glb',
scale: 0.0 //由于我们以第一人称视角,此时可设置其飞机模型的大小为0,但是必须存在这个分级机模型
},
// 自动计算前进方向
orientation: new Cesium.VelocityOrientationProperty(positionProperty)
})
// 设置相机追踪运动物体
viewer.trackedEntity = airplaneEntity
// 设置时间速率
viewer.clock.multiplier = 1
// 设置自动播放
viewer.clock.shouldAnimate = true
const that = this
viewer.clock.onTick.addEventListener(function (clock) {
// var endTime = Cesium.JulianDate.addSeconds(startTime, duration, new Cesium.JulianDate());
if (Cesium.JulianDate.greaterThan(clock.currentTime, stop)) {
// 退出界面操作
// 例如:关闭Cesium Viewer
that.finishFly()
}
})
},
// 暂停飞行,设置暂停、飞行按钮置灰;继续和结束按钮可点击
stopFly () {
this.pause = true
this.start = true
this.keepup = false
this.stop = false
viewer.clock.shouldAnimate = false //是否尝试延长时间
},
// 继续飞行;设置继续、飞行按钮置灰;暂停和结束按钮可点击
continueFly () {
this.keepup = true
this.start = true
this.pause = false
this.stop = false
viewer.clock.shouldAnimate = true //尝试延长时间
},
注意:为了以第一人称视角漫游,需要将飞机模型隐藏掉,但是不能去掉。
整体代码如下
<template>
<div class="visualization">
<div id="cesiumContainer"></div>
<div class="infoDiv">
<el-select v-model="pointInfo" placeholder="请选择" size="mini" popper-class="type-popper"
:disabled="showSelect">
<el-option v-for="item in options" :key="item.id" :label="item.name" :value="item.id">
</el-option>
</el-select>
<div
style="margin-top: 10px;display: flex;flex-direction: column;justify-content: flex-start;align-items: flex-start;">
<el-button icon="el-icon-video-play" type="text" @click.native-type="startFly" :disabled="start">飞行</el-button>
<el-button icon="el-icon-video-pause" type="text" @click.native-type="stopFly" style="margin-left: 0px;"
:disabled="pause">暂停</el-button>
<el-button icon="el-icon-video-play" type="text" @click.native-type="continueFly" style="margin-left: 0px;"
:disabled="keepup">继续</el-button>
<el-button icon="el-icon-video-play" type="text" @click.native-type="finishFly" style="margin-left: 0px;"
:disabled="stop">退出</el-button>
</div>
</div>
</template>
<script>
var viewer = null
var tileset = null
var terrainProvider = null
var airplaneEntity = null
var timeStepInSeconds = 7
const positionProperty = new Cesium.SampledPositionProperty()
var entities = []
export default {
components: {
},
data () {
return {
pointInfo: '',
options: [
{
id:1,
name:'公园',
longitude:110.4565,
latitude:36.89797
},
...
],
start: false, //飞行按钮可否点击
pause: true, //暂停按钮可否点击
keepup: true, //继续按钮可否点击
stop: true, //退出飞行按钮可否点击
showSelect: false //下拉框可否选择
}
},
mounted () {
},
methods: {
initCesium () {
Cesium.Ion.defaultAccessToken = '申请自己的access token'
viewer = new Cesium.Viewer('cesiumContainer', {
animation: false, // 是否显示动画控件
shouldAnimate: false,//是否自动播放
homeButton: false, // 是否显示Home按钮
fullscreenButton: false, // 是否显示全屏按钮
baseLayerPicker: false, // 是否显示图层选择控件
geocoder: false, // 是否显示地名查找控件
timeline: false, // 是否显示时间线控件
sceneModePicker: false, // 是否显示投影方式控件
navigationHelpButton: false, // 是否显示帮助信息控件
navigationInstructionsInitiallyVisible: false, // 是否显示导航提示,默认为true,
infoBox: true, // 是否显示点击要素之后显示的信息
requestRenderMode: true, // 启用请求渲染模式
// scene3DOnly: false, //每个几何实例将只能以3D渲染以节省GPU内存
sceneMode: 3, // 初始场景模式 1 2D模式 2 2D循环模式 3 3D模式 Cesium.SceneMode
creditContainer: document.createElement('div'), // 创建一个空的div来包裹版权信息,类似隐藏掉默认的版权信息
// baseLayerPicker: false,//如果设置为false,则不会创建BaseLayerPicker小部件
// 指定Cesium的底图图层实例,默认为ImageryProvider
imageryProvider: new Cesium.WebMapTileServiceImageryProvider({
url: 'http://t0.tianditu.gov.cn/img_w/wmts?tk=申请自己的key',
layer: 'vec',
style: 'default',
tileMatrixSetID: 'w',
format: 'tiles',
maximumLevel: 18
})
});
//加载具有地形高度的数字模型或图像,即抬高三维模型所在区域的地形高度
terrainProvider = new Cesium.CesiumTerrainProvider({
url: 'http://127.0.0.1:10004' + this.detailInfo.terrainPath,
requestVertexNormals: true,
requestWaterMask: true,
tilingScheme: new Cesium.GeographicTilingScheme(),
requestVertexNormals: true
})
viewer.terrainProvider = terrainProvider
var creditElement = document.createElement('div')
creditElement.style.position = 'absolute'
creditElement.style.bottom = '10px'
creditElement.style.right = '10px'
creditElement.style.color = 'white'
creditElement.style.fontSize = '20px'
creditElement.innerHTML = '2024.6'
// 将DOM元素添加到Viewer的容器中
viewer.container.appendChild(creditElement)
tileset = new Cesium.Cesium3DTileset({
url: 'http://127.0.0.1:10004' + this.detailInfo.filePath,
maximumMemoryUsage: 5120//控制 3D Tiles 的最大内存使用量,从而在保证数据流畅的前提下尽可能减小内存占用。
})
viewer.scene.primitives.add(tileset)
viewer.zoomTo(tileset)
// this.addYdbPoints()//绘制自定义位置点广告牌,见Cesium实现位置点的自定义弹框显示内容
},
startFly () {
this.start = true
this.pause = false
this.keepup = true
this.stop = false
this.showSelect = true
// 当下个飞行前清除上次的飞行对象和路径
if (airplaneEntity != null) {
viewer.entities.remove(airplaneEntity)
}
// 获取条目经纬度数据集合
const positions = []
for (let i = 0; i < this.options.length; i++) {
const position = {
longitude: this.options[i].longitude,
latitude: this.options[i].latitude,
height: 1000
}
positions.push(position)
}
const flightData = positions
const totalSeconds = (flightData.length) * timeStepInSeconds
// 设置起点时间
const time = new Date('2020-03-09T23:10:00Z')
const start = Cesium.JulianDate.fromDate(time)
// 设置终点时间
const stop = Cesium.JulianDate.addSeconds(start, totalSeconds, new Cesium.JulianDate())
viewer.clock.startTime = start.clone()
viewer.clock.stopTime = stop.clone()
viewer.clock.currentTime = start.clone()
for (let i = 0; i < flightData.length; i++) {
const dataPoint = flightData[i]
// 采样时间
const time = Cesium.JulianDate.addSeconds(start, i * timeStepInSeconds, new Cesium.JulianDate())
// 计算当前的3D坐标
const position = Cesium.Cartesian3.fromDegrees(dataPoint.longitude, dataPoint.latitude, dataPoint.height)
// 添加轨迹采样点
positionProperty.addSample(time, position)
}
// 创建飞机模型
airplaneEntity = viewer.entities.add({
// id: item.id,
availability: new Cesium.TimeIntervalCollection([
new Cesium.TimeInterval({
start: start,
stop: stop
})
]),
position: positionProperty,
model: {
uri: '/model/glb/Cesium_Air.glb',
scale: 0.0
},
// 自动计算前进方向
orientation: new Cesium.VelocityOrientationProperty(positionProperty)
})
// 设置相机追踪运动物体
viewer.trackedEntity = airplaneEntity
// 设置时间速率
viewer.clock.multiplier = 1
// 设置自动播放
viewer.clock.shouldAnimate = true
const that = this
viewer.clock.onTick.addEventListener(function (clock) {
// var endTime = Cesium.JulianDate.addSeconds(startTime, duration, new Cesium.JulianDate());
if (Cesium.JulianDate.greaterThan(clock.currentTime, stop)) {
// 退出界面操作
// 例如:关闭Cesium Viewer
that.finishFly()
}
})
},
// 暂停飞行
stopFly () {
this.pause = true
this.start = true
this.keepup = false
this.stop = false
viewer.clock.shouldAnimate = false
},
// 继续飞行
continueFly () {
this.keepup = true
this.start = true
this.pause = false
this.stop = false
viewer.clock.shouldAnimate = true
},
finishFly () {
this.stopFly()
this.stop = true
this.start = false
this.keepup = true
this.pause = true
this.showSelect = false
viewer.entities.remove(airplaneEntity)
}
},
beforeDestroy () {
if (viewer) {
// 组件销毁时,确保Cesium资源被释放
viewer.destroy()
}
}
}
</script>
<style scoped>
.visualization {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 99999;
}
.infoDiv {
padding: 10px;
position: absolute;
left: 10px;
top: 70px;
width: 10%;
height: 180px;
z-index: 999999;
}
#cesiumContainer {
position: relative;
top: 5px;
left: 0;
width: 100%;
height: 100%;
z-index: 99999
}
</style>