Skip to content
Cesium轨迹回放

需求

需要实现如下图所示

思路

  1. 先获取得到的轨迹线,把起点和终点绘制出来,以透明度 30%的形式绘制
  2. 获取该轨迹线人物的头像
  3. 再通过 Cesium 中 entity 自带的# PathGraphics就可以实现轨迹线的模块

![[Pasted image 20241014142034.png]]

代码实现

entityPath实现

这种方法是最简单的方法,但是存在问题如下

问题

  1. 先绘制的entity轨迹线有depthMaterial,可以无视地形,但是path绘制的轨迹线无法无视地形(Cesium官方还没提供接口)
  2. 如果数据量大可能会存在卡顿的问题

解决方法

通过primitive来再做一个轨迹回放,这样深度控制的权力可以掌握在自己手上,而且性能问题也能有比较好的解决

优点

  1. 写法简单快捷,代码量相对少

坑点

因为轨迹是根据时间来的,轨迹终点的时间都是确定的,如果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实现动态绘制轨迹线]]

https://blog.csdn.net/XFIRR/article/details/129385516

Updated at: