1.非实时动画
- 前提:轨迹全程数据具备。(非实时)
- 利用自带动画组件与插值方法
//启用动画
viewer.clock.shouldAnimate = true;
// 定义路径的起始和结束时间
var start = Cesium.JulianDate.fromDate(new Date());
var stop = Cesium.JulianDate.addSeconds(start, 360, new Cesium.JulianDate());
// 配置时钟以控制动画
viewer.clock.startTime = start.clone();
viewer.clock.stopTime = stop.clone();
viewer.clock.currentTime = start.clone();
viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP;
viewer.clock.multiplier = 10;
// 创建一个 SampledPositionProperty 来存储随时间变化的位置数据
var position = new Cesium.SampledPositionProperty();
//SampledPositionProperty 是 Cesium 中的一个类,它用于存储随时间变化的位置数据。它可以用来定义路径实体的形状,或者用来控制模型、点等其他实体随时间移动的轨迹。
//开发者可以使用 addSample 方法向 SampledPositionProperty 中添加位置数据。每个位置数据都包含一个时间值和一个位置值
for (var i = 0; i <= 360; i += 45) {
// 计算每个时间点的位置
var radians = Cesium.Math.toRadians(i);
var time = Cesium.JulianDate.addSeconds(start, i, new Cesium.JulianDate());
var height = 10000 + 500 * Math.sin(radians); // 计算飞机的高度
var positionValue = new Cesium.Cartesian3.fromDegrees(
114.3 + 0.1 * Math.cos(radians),
39.9 + 0.1 * Math.sin(radians),
height
);
// 将位置数据添加到 SampledPositionProperty 中
position.addSample(time, positionValue);
}
//设置插值算法,平滑路径
position.setInterpolationOptions({
interpolationDegree: 4, //插值程度
interpolationAlgorithm: Cesium.HermitePolynomialApproximation, //插值算法
});
// 创建一个路径实体,并为其提供位置数据和样式
var path = viewer.entities.add({
name: "路径",
position: position,
orientation: new Cesium.VelocityOrientationProperty(position),
path: {
leadTime: 0,
trailTime: 60, //路径持续时间
width: 20, //路径宽度
resolution: 10, //路径分辨率
material: new Cesium.PolylineGlowMaterialProperty({
glowPower: 1, //发光强度或者粗细程度
color: Cesium.Color.BLUEVIOLET, //发光颜色
}),
},
model: {
uri: "/src/assets/Cesium_Air.glb",
minimumPixelSize: 128, //模型最小像素
maximumScale: 200, //模型最大放大倍数,
},
});
//视角飞行至路径
viewer.zoomTo(path);
2.实时动画
- 飞机每2秒移动一次,使用自带轨迹插值实现动画。
- 因为动画时钟为全局属性,无法单独为某一模型设置时钟,因此实时轨迹中部分不移动的飞机在当前时间消失。(无法解决,换方案可解决)
socket.onopen = () => {
viewer.clock.shouldAnimate = true;
viewer.clock.clockRange = Cesium.ClockRange.CLAMPED;
this.start(); //心跳检测开始
setTimeout(() => {
this.changesocketOpen(true);
}, 2000);
};
/**
* 创建飞机
* @param aircraftInfo
*/
OurMap.prototype.createOneMarker = async function(aircraftInfo) {
var ourMap = this;
let heading = Cesium.Math.toRadians(Number(Number(aircraftInfo.airVelocityInfo.avBiasMagneticNorth) - 180));
let pitch = 0;
let roll = 0;
const hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);
var position = Cesium.Cartesian3.fromDegrees(
Number(aircraftInfo.alLongitude),
Number(aircraftInfo.alLatitude),
Math.floor(
Number(aircraftInfo.airLocationInfo.alAltitude) / 3.2808399
)
);
// let modelMatrix = Cesium.Transforms.headingPitchRollToFixedFrame(
// position,
// hpr
// );
const orientation = Cesium.Transforms.headingPitchRollQuaternion(
position,
hpr
);
var startTime = Cesium.JulianDate.fromDate(new Date());
var julianDate = Cesium.JulianDate.addSeconds(startTime, 2.0, new Cesium.JulianDate());
var property = new Cesium.SampledPositionProperty();
property.setInterpolationOptions({
interpolationDegree: 5,
interpolationAlgorithm: Cesium.LagrangePolynomialApproximation,
});
property.addSample(julianDate, position)
var AirModel = viewer.entities.add({
name: aircraftInfo.sn,
position: property,
orientation: new Cesium.VelocityOrientationProperty(property),
// orientation: orientation,
model: {
uri: "/static/glft/Cesium_Air.glb",
minimumPixelSize: 50,
},
});
AirModel.sn = aircraftInfo.sn;
AirModel.icao = aircraftInfo.icao;
AirModel.aircraftInfo = {...aircraftInfo };
AirModel.property = property;
AirModel.attr = { position: position }
ourMap.markers.push(AirModel);
//筛选机制
//初始化设置高度
// ourMap.setHeightMarker(marker, aircraftInfo);
//初始化设置类型
// ourMap.setTypeMarker(marker, aircraftInfo, aircraftInfo.watchAir);
var icon = ourMap.initMarkerIcon(aircraftInfo);
AirModel.model.uri = icon;
AirModel.model.minimumPixelSize = 50;
}
/**
* 改变飞机位置
*/
AircraftInfo.prototype.changeLocation = function() {
var aircraftInfo = this;
var marker = CwsiumourMap.getOneMarkerByIcao(aircraftInfo.icao);
let Angle = aircraftInfo.aircraftcategory === 'FREE_BALLOON' ? 0 : Number(aircraftInfo.airVelocityInfo.avBiasMagneticNorth);
if (marker) {
let heading = Cesium.Math.toRadians(Number(aircraftInfo.airVelocityInfo.avBiasMagneticNorth) - 180);
let pitch = 0;
let roll = 0;
let alAltitudeNum = Math.floor(
Number(aircraftInfo.airLocationInfo.alAltitude) / 3.2808399
) - Math.floor(
Number(aircraftInfo.airLocationInfo.alAltitude) / 3.2808399
)
if (alAltitudeNum > 0) {
roll = 0.1
} else if (alAltitudeNum == 0) {
roll = 0
} else if (alAltitudeNum < 0) {
roll = -0.1
}
const hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);
var position = Cesium.Cartesian3.fromDegrees(
Number(aircraftInfo.alLongitude),
Number(aircraftInfo.alLatitude),
Math.floor(
Number(aircraftInfo.airLocationInfo.alAltitude) / 3.2808399
)
);
const orientation = Cesium.Transforms.headingPitchRollQuaternion(
position,
hpr
);
var startTime = Cesium.JulianDate.fromDate(new Date());
var julianDate = Cesium.JulianDate.addSeconds(startTime, 2.0, new Cesium.JulianDate());
// let modelMatrix = Cesium.Transforms.headingPitchRollToFixedFrame(
// position,
// hpr
// );
// marker.orientation = orientation;
marker.property.addSample(julianDate, position);
marker.attr.position = position
}
}