🚀 个人简介:某大型测绘遥感企业资深Webgis开发工程师,软件设计师(中级)、CSDN优质创作者
💟 作 者:柳晓黑胡椒❣️
📝 专 栏:cesium实践(原生)
🌈 若有帮助,还请关注 ➕ 点赞➕收藏,不行的话我再努努力💪💪💪
需求背景
1.实现一个动态的三维无人机航拍过程实景效果
2.应粉丝要求,需要添加实时轨迹
3.应粉丝要求,需要加载路径点,其通过后端长连接,10秒返回一个点
解决思路
1.采用cesium 的 SampledPositionProperty
方法 来存储随时间变化的位置数据
2.采用 entity 的 path
实体来绘制绘制路径
3.采用每个路径点获取时,用 SampledPositionProperty.addSamples
覆盖之前的路径点数组,少于二个人不启动动画;
解决效果
index.vue
/**
* @author: liuk
* @date: 2024-11-28
* @describe:无人机轨道飞行(clock + 后端长连接实时更新)
*/
<template>
<div class="polylineFly-wrap">
<el-button @click="start">开始</el-button>
<el-button @click="pause">暂停</el-button>
<el-button @click="remove">清除</el-button>
<Tdt_img_d/>
</div>
</template>
<script lang="ts" setup>
import {usemapStore} from "@/store/modules/cesiumMap";
// Component
import Tdt_img_d from "@/views/cesium/component/controlPanel/layerManagement/basicMap/tdt_img_d.vue"
import {onMounted, onUnmounted, reactive} from "vue";
const mapStore = usemapStore()
const model = reactive({
curRuningArr_i: 0,
curRuningArr: [],
})
onMounted(() => {
viewer.dataSources.add(lineDatasource);
viewer.dataSources.add(wrjModelDatasource);
addLineEntiy()
addModelEntity()
})
onUnmounted(() => {
lineDatasource.entities.removeAll()
viewer.dataSources.remove(lineDatasource);
wrjModelDatasource.entities.removeAll()
viewer.dataSources.remove(wrjModelDatasource);
})
const getlist = () => { // 模拟实时接口
let apiIndex = 3
const timer = setInterval(() => {
if (apiIndex > 7) {
clearInterval(timer)
return
}
const times = flyPoints.slice(0, apiIndex).map((_, index) => Cesium.JulianDate.addSeconds(viewer.clock.startTime, 2 * index, new Cesium.JulianDate()))
const positions = flyPoints.slice(0, apiIndex).map(pos => new Cesium.Cartesian3.fromDegrees(pos[0], pos[1], pos[2]))
positionSampledPositionProperty.addSamples(times, positions)
apiIndex++
}, 2000)
}
const start = () => {
viewer.clock.shouldAnimate = true;
viewer.clock.currentTime = tempTime ? tempTime.clone() : viewer.clock.startTime.clone();
}
const pause = () => {
tempTime = viewer.clock.currentTime
viewer.clock.shouldAnimate = false;
}
const remove = () => {
viewer.clock.shouldAnimate = false;
viewer.clock.currentTime = viewer.clock.startTime.clone();
tempTime = null
}
// 地图逻辑
const viewer = mapStore.getCesiumViewer()
const lineDatasource = new Cesium.CustomDataSource("line")
const wrjModelDatasource = new Cesium.CustomDataSource("wrj")
// 飞行区域边界线坐标
const lineCoordinates = [[116.069898, 31.303655], [116.098708, 31.322126], [116.108063, 31.311256], [116.079317, 31.292959], [116.069898, 31.303655]]
// 飞行路线
const flyPoints = [[116.069898, 31.303655, 200], [116.098708, 31.322126, 200], [116.108063, 31.311256, 200],
[116.079317, 31.292959, 200]]
let wrjEntity, tempTime
const positionSampledPositionProperty = new Cesium.SampledPositionProperty();
positionSampledPositionProperty.setInterpolationOptions({
interpolationDegree: 4, //插值程度
});
viewer.clock.startTime = Cesium.JulianDate.fromDate(new Date(1727971200000));
viewer.clock.clockRange = Cesium.ClockRange.CLAMPED // UNBOUNDED CLAMPED LOOP_STOP
const addLineEntiy = () => {
const pos = Cesium.Cartesian3.fromDegreesArray(lineCoordinates.flat())
const entity = lineDatasource.entities.add({
polyline: {
positions: pos,
width: 1.5,
material: Cesium.Color.fromCssColorString("#C0C0C0").withAlpha(0.5),
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
}
})
viewer.flyTo(entity)
}
const addModelEntity = () => {
viewer.clock.shouldAnimate = false;
viewer.clock.stopTime = Cesium.JulianDate.addSeconds(viewer.clock.startTime, 2 * 3, new Cesium.JulianDate())
viewer.clock.currentTime = viewer.clock.startTime.clone();
const times = flyPoints.map((_, index) => Cesium.JulianDate.addSeconds(viewer.clock.startTime, 2 * index, new Cesium.JulianDate()))
const positions = flyPoints.map(pos => new Cesium.Cartesian3.fromDegrees(pos[0], pos[1], pos[2]))
positionSampledPositionProperty.addSamples(times, positions)
wrjEntity = viewer.entities.add({
position: positionSampledPositionProperty,
orientation: new Cesium.VelocityOrientationProperty(positionSampledPositionProperty),
path: {
leadTime: 0,
trailTime: 0.3, //路径持续时间
width: 1, //路径宽度
resolution: 10, //路径分辨率
material: Cesium.Color.fromCssColorString("red")
},
model: {
uri: import.meta.env.VITE_APP_MODELDATA + '/wrj.glb',
minimumPixelSize: 128, //模型最小像素
maximumScale: 200, //模型最大放大倍数,
},
});
}
</script>
<style lang="scss" scoped>
.polylineFly-wrap {
position: fixed;
top: 100px;
left: 280px;
pointer-events: auto;
}
</style>
致谢
期间收到了粉丝(骑猪兜风)奶茶❣️,这真是太贴心了,非常感谢支持和鼓励!感谢你们的每一次点击、每一条留言,甚至每一份小小的礼物,都是我不断前行的动力!🍀