写项目时,有路径回放功能。但是网上资料有些不适用或者不全。写完之后想着放上来,共大家参考。
代码参考:
cesium实现飞行漫游
cesium轨迹回放,按路径飞行
核心代码:
- 绘制轨迹线
const handler = new this.Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
const self = this;
handler.setInputAction(function(event) {
var earthPosition = self.viewer.scene.pickPosition(event.position);
if (Cesium.defined(earthPosition)) {
if (self.activeShapePoints.length === 0) {
self.floatingPoint = self.createPoint(earthPosition);
self.activeShapePoints.push(earthPosition);
var dynamicPositions = new Cesium.CallbackProperty(function() {
return self.activeShapePoints;
}, false);
self.activeShape = self.drawShape(dynamicPositions); //绘制动态图
}
self.activeShapePoints.push(earthPosition);
self.createPoint(earthPosition);
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
//鼠标移动
handler.setInputAction(function(event) {
if (Cesium.defined(self.floatingPoint)) {
var newPosition = self.viewer.scene.pickPosition(event.endPosition);
if (Cesium.defined(newPosition)) {
self.floatingPoint.position.setValue(newPosition);
self.activeShapePoints.pop();
self.activeShapePoints.push(newPosition);
}
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
handler.setInputAction(function() {
self.terminateShape();
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
//绘制点
createPoint(worldPosition) {
var point = this.viewer.entities.add({
position: worldPosition,
point: {
color: Cesium.Color.WHITE,
pixelSize: 1
}
});
return point;
}
//画线
drawShape(positionData) {
var shape;
if (this.drawingMode === 'line') {
shape = this.viewer.entities.add({
polyline: {
positions: positionData,
clampToGround: true,
width: 3
}
});
this.drawinLink.push(shape)
}
return shape;
}
terminateShape() {
this.activeShapePoints.pop(); //去除最后一个动态点
if (this.activeShapePoints.length) {
this.marks = [];
for (const position of this.activeShapePoints) {
const latitude = this.toDegrees(Cesium.Cartographic.fromCartesian(position).latitude)
const longitude = this.toDegrees(Cesium.Cartographic.fromCartesian(position).longitude)
this.marks.push({
lat: latitude,
lng: longitude,
flytime: this.flytime,
height: 0
})
}
this.drawShape(this.activeShapePoints); //绘制最终图
this.startFly();
}
this.viewer.entities.remove(this.floatingPoint); //去除动态点图形(当前鼠标点)
this.viewer.entities.remove(this.activeShape); //去除动态图形
this.floatingPoint = undefined;
this.activeShape = undefined;
this.activeShapePoints = [];
}
drawShape(positionData) {
var shape;
if (this.drawingMode === 'line') {
shape = this.viewer.entities.add({
polyline: {
positions: positionData,
clampToGround: true,
width: 3
}
});
}
return shape;
}
- 模型按轨迹运动
let planeModel = this.viewer.entities.add({
// 和时间轴关联
availability: new Cesium.TimeIntervalCollection([new Cesium.TimeInterval({
start: start,
stop: stop
})]),
position: property,
// 根据所提供的速度计算模型的朝向
orientation: new Cesium.VelocityOrientationProperty(property),
// 模型数据
model: {
uri: '../../static/CesiumAir/Cesium_Air.glb',
minimumPixelSize: 128
}
});
- 重点:脱离时间轴
找了很多代码基本都是依靠Cesium的时间轴进行移动,但是写的时候遇到了问题,如果是多条线路,可能存在时间轴播放结束但是模型未移动到终点的情况。于是将路线对应的时间轴终点修改,不再统一使用一条时间轴,而是多条时间轴(页面不显示时间轴)。以解决每条路径长度不同移动时间不同的问题。
computeFlight(source, start) {
let property = new Cesium.SampledPositionProperty();
let end = ""
for (let i = 0; i < source.length; i++) {
let time = Cesium.JulianDate.addSeconds(start, source[i].flytime*i*10, new Cesium.JulianDate);
let position = Cesium.Cartesian3.fromDegrees(source[i].lng, source[i].lat, source[i]
.height);
// 添加位置,和时间对应
property.addSample(time, position);
if(i == source.length -1){
//获取最后节点时间
end = Cesium.JulianDate.addSeconds(start, source[i].flytime*i*10, new Cesium.JulianDate)
}
}
return {
property,end
};
}
// 设置始终停止时间
this.viewer.clock.stopTime = stop.clone();
最后效果(删了点帧):