Bootstrap

Cesium路径回放

写项目时,有路径回放功能。但是网上资料有些不适用或者不全。写完之后想着放上来,共大家参考。
代码参考:
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();

最后效果(删了点帧):
drawLine.gif

;