需求
需要实现如下图所示
思路
- 先获取得到的轨迹线,把起点和终点绘制出来,以透明度 30%的形式绘制
- 获取该轨迹线人物的头像
- 再通过 Cesium 中 entity 自带的# PathGraphics就可以实现轨迹线的模块
![[Pasted image 20241014142034.png]]
代码实现
entityPath实现
这种方法是最简单的方法,但是存在问题如下
问题
- 先绘制的entity轨迹线有depthMaterial,可以无视地形,但是path绘制的轨迹线无法无视地形(Cesium官方还没提供接口)
- 如果数据量大可能会存在卡顿的问题
解决方法
通过primitive来再做一个轨迹回放,这样深度控制的权力可以掌握在自己手上,而且性能问题也能有比较好的解决
优点
- 写法简单快捷,代码量相对少
坑点
因为轨迹是根据时间来的,轨迹终点的时间都是确定的,如果Cesium. ClockRange用默认的UNBOUNDED,就会导致时钟始终往前,就会导致轨迹线path消失。需要把ClockRange设置成CLAMPED,当clock的stoptime到达后不再推进时间,才能解决这个问题
javascript
// 创建 Cesium Viewer
const viewer = new Cesium.Viewer('cesiumContainer', {
imageryProvider: new Cesium.IonImageryProvider({ assetId: 3 }),
});
const dataOption = {
userId: '123',
userName: '测试',
startTime: '2024-10-12T15:18:39+08:00',
endTime: '2024-10-14 15:18:39',
billboardUrl: 'https://sandcastle.cesium.com/images/Cesium_Logo_overlay.png',
speed: '1',
color: '#007CFF',
needPlayback: false,
maxCount: 8000,
isZoomTo: false,
isShow: true,
uploadSourceType: 1,
};
// 轨迹数据
const lineData = [
[94.9952697710716, 43.68696250150549],
[94.99493266015436, 43.68663049749048],
[94.99459555296879, 43.68629849248484],
[94.99425844951485, 43.68596648648851],
];
// 创建轨迹线
const polyline = viewer.entities.add({
polyline: {
positions: Cesium.Cartesian3.fromDegreesArray(
lineData.flat() // 将二维数组转换为一维数组
),
width: 5,
material: Cesium.Color.fromAlpha(Cesium.Color.fromCssColorString('#007CFF'), 0.3),
clampToGround: true,
},
});
// 模型沿着轨迹移动
const moveData = lineData.map((coord, index) => ({
time: Cesium.JulianDate.addSeconds(
Cesium.JulianDate.fromDate(new Date('2024-10-12T15:18:39+08:00')),
index * 10, // 每隔10秒一个点
new Cesium.JulianDate()
),
x: coord[0],
y: coord[1],
z: 0,
}));
console.log('moveData', moveData);
// 定义SampledPositionProperty来储存时间和位置
const property = new Cesium.SampledPositionProperty();
moveData.forEach((item) => {
const position = Cesium.Cartesian3.fromDegrees(item.x, item.y, item.z);
property.addSample(item.time, position);
});
// 设置插值方法
property.setInterpolationOptions({
interpolationDegree: 2,
interpolationAlgorithm: Cesium.LagrangePolynomialApproximation,
});
// 添加移动的实体
const entityTest = viewer.entities.add({
availability: new Cesium.TimeIntervalCollection([
new Cesium.TimeInterval({
start: moveData[0].time,
stop: moveData[moveData.length - 1].time,
}),
]),
position: property,
billboard: {
image: 'https://sandcastle.cesium.com/images/Cesium_Logo_overlay.png', // 使用你的billboardUrl
scale: 0.5,
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
},
path: {
leadTime: 0,
resolution: 1,
trailTime: 99999999, // 设置为Infinity以保持路径不消失
material: Cesium.Color.fromCssColorString('#007CFF'),
width: 5,
},
});
// 设置时间轴
viewer.clock.startTime = moveData[0].time.clone();
viewer.clock.stopTime = moveData[moveData.length - 1].time.clone();
viewer.clock.currentTime = moveData[0].time.clone();
viewer.clock.shouldAnimate = true;
viewer.clock.multiplier = 3; // 这里可以调整为你想要的倍速
// 缩放到轨迹线
viewer.zoomTo(viewer.entities);
console.log('entityTest', entityTest);
Primitive轨迹回放实现(todo)
参考文章
[[【转载】Cesium实现动态绘制轨迹线]]