cesium 实现轨迹回放

一、项目介绍

在地图上画出2条路径,无人机在轨迹上移动的效果。只需要准备路径的坐标集合和3d模型。

二、创建地图

js 复制代码
import * as Cesium from "cesium"; 
Cesium.Ion.defaultAccessToken = key; 
const viewer = new Cesium.Viewer(id);

三、添加轨迹

使用viewer.entities.add方法添加线条polyline,设置线条的颜色、宽度、样式。

js 复制代码
let positions = []; //路径集合
//路径坐标转笛卡尔坐标
points.forEach((item) => { 
    let point = Cesium.Cartesian3.fromDegrees(item[0], item[1], height);
    positions.push(point);
  });

//添加轨迹
  pathEntry = viewer.entities.add({
    polyline: {
      positions: positions,
      width: 5,
      material: new Cesium.PolylineDashMaterialProperty({
        color:  Cesium.Color.RED,
        dashLength: 16.0, // 控制虚线段的长度
      }),
      clampToGround:false, // 设置为true可使路线贴地
    },
    name: "path",
  });

四、添加模型、轨迹与时间结合

js 复制代码
// 2. 设置移动速度并计算总时间
  const totalSeconds = 300;

  const positionProperty = new Cesium.SampledPositionProperty();

  tracks = viewer.entities.add({
    name: "移动",
    position: positionProperty, //位置
    orientation: new Cesium.VelocityOrientationProperty(positionProperty), //模型的方向
    model: {
      uri: 'xx.glft', //3d模型链接
      scale: 0.2,   //缩放比例
      runAnimations: true, //播放3d模型的动画
    },
    monitoItems: {
      ...curItem,
    },
  });

//开始时间
  const start = Cesium.JulianDate.fromDate(new Date());
 //结束时间
  const stop = Cesium.JulianDate.addSeconds(
    start,
    totalSeconds,
    new Cesium.JulianDate()
  );

  // 添加路径点和时间点
  positions.forEach((position, index) => {
    const time = Cesium.JulianDate.addSeconds(
      start,
      index*10,
      new Cesium.JulianDate()
    );
    positionProperty.addSample(time, position);
  });

  // 设置时间范围
  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; //时间加速倍数
  
  // 相机跟踪实体
  viewer.trackedEntity = tracks; 
  
   // 自定义相机行为
  viewer.clock.onTick.addEventListener(function(clock) {
        const currentDate = clock.currentTime.toDate(); // 转成标准 Date 对象
        console.log("当前时间:", currentDate);
   });
   
    // 后续移除
    viewer.clock.onTick.removeEventListener(listener);

五、知识点

1、Cesium.SampledPositionProperty 随时间变化的位置属性。

  • 通常与 Cesium.Clock 配合实现时间控制
  • Entity.position 属性使用
  • 可与 Cesium.PathGraphics 一起显示运动轨迹
js 复制代码
//添加时间-位置样本点:
const time = Cesium.JulianDate.fromIso8601('2023-01-01T00:00:00Z');
const position = Cesium.Cartesian3.fromDegrees(116.3, 39.9, 100);
positionProperty.addSample(time, position);

//获取指定时间点的位置:
const currentPosition = positionProperty.getValue(viewer.clock.currentTime);

//设置插值选项:
positionProperty.setInterpolationOptions({
    interpolationDegree: 5,
    interpolationAlgorithm: Cesium.LagrangePolynomialApproximation
});

2、Cesium.JulianDate 用于计算时间

js 复制代码
// 从ISO 8601字符串创建
const date1 = Cesium.JulianDate.fromIso8601("2023-01-01T12:00:00Z");

// 从JavaScript Date对象创建
const date2 = Cesium.JulianDate.fromDate(new Date());

// 从年、月、日等组件创建
const date3 = Cesium.JulianDate.fromGregorianDate({
    year: 2023, 
    month: 1, 
    day: 1,
    hour: 12,
    minute: 0,
    second: 0
});

// 创建当前时间
const now = Cesium.JulianDate.now();

// 时间加减
const newDate = Cesium.JulianDate.addSeconds(date1, 3600, new Cesium.JulianDate());
const diff = Cesium.JulianDate.secondsDifference(date2, date1);

// 比较时间
const isAfter = Cesium.JulianDate.compare(date1, date2) > 0;

// 转为JavaScript Date
const jsDate = Cesium.JulianDate.toDate(date1);

// 转为ISO 8601字符串
const isoString = Cesium.JulianDate.toIso8601(date1);

// 获取时间组件
const gregorian = Cesium.JulianDate.toGregorianDate(date1);
console.log(gregorian.year, gregorian.month, gregorian.day);

3、viewer.clock

viewer.clock是Cesium中控制时间系统的核心对象,用于管理场景中的时间流动、动画和动态数据的时间同步。

js 复制代码
//创建时钟对象
viewer.clock = new Cesium.Clock({
    // 必须参数
    startTime: Cesium.JulianDate.fromIso8601("2023-01-01T00:00:00Z"),
    stopTime: Cesium.JulianDate.fromIso8601("2023-01-02T00:00:00Z"),
    currentTime: Cesium.JulianDate.fromIso8601("2023-01-01T06:00:00Z"),
    
    // 可选参数
    multiplier: 10,                  // 时间流逝速度倍数
    clockStep: Cesium.ClockStep.SYSTEM_CLOCK_MULTIPLIER, // 时间步进模式
    clockRange: Cesium.ClockRange.LOOP_STOP, // 时间范围行为
    canAnimate: true,                // 是否允许动画
    shouldAnimate: false             // 初始是否自动播放
});

ClockStep (时间步进模式)

js 复制代码
Cesium.ClockStep.SYSTEM_CLOCK          // 跟随系统时钟
Cesium.ClockStep.SYSTEM_CLOCK_MULTIPLIER // 系统时钟×multiplier
Cesium.ClockStep.TICK_DEPENDENT        // 依赖渲染帧率

ClockRange (时间范围行为)

js 复制代码
Cesium.ClockRange.UNBOUNDED  // 到达终点后继续前进
Cesium.ClockRange.LOOP_STOP  // 到达终点后回到起点
Cesium.ClockRange.CLAMPED    // 到达终点后停止

时间控制方法

js 复制代码
// 播放/暂停控制
viewer.clock.shouldAnimate = true; // 开始播放
viewer.clock.shouldAnimate = false; // 暂停

// 跳转到特定时间
viewer.clock.currentTime = Cesium.JulianDate.fromIso8601("2023-01-01T12:00:00Z");

// 调整播放速度
viewer.clock.multiplier = 60; // 60倍速播放

// 重置时间范围
viewer.clock.startTime = newStartTime;
viewer.clock.stopTime = newStopTime;

// 初始化时间轴范围
viewer.timeline.zoomTo(viewer.clock.startTime, viewer.clock.stopTime);

// 更新时间轴显示
viewer.timeline.updateFromClock();

时间变化监听

js 复制代码
// 每帧时间变化事件
viewer.clock.onTick.addEventListener(function(clock) {
    console.log("当前时间:", Cesium.JulianDate.toIso8601(clock.currentTime));
});

// 时间范围变化事件
viewer.clock.onStop.addEventListener(function() {
    console.log("到达时间轴终点");
});

// 后续移除
 viewer.clock.onTick.removeEventListener(listener);
相关推荐
胡gh4 小时前
页面卡成PPT?重排重绘惹的祸!依旧性能优化
前端·javascript·面试
言兴4 小时前
# 深度解析 ECharts:从零到一构建企业级数据可视化看板
前端·javascript·面试
山有木兮木有枝_5 小时前
TailWind CSS
前端·css·postcss
烛阴5 小时前
TypeScript 的“读心术”:让类型在代码中“流动”起来
前端·javascript·typescript
杨荧5 小时前
基于Python的农作物病虫害防治网站 Python+Django+Vue.js
大数据·前端·vue.js·爬虫·python
Moment6 小时前
毕业一年了,分享一下我的四个开源项目!😊😊😊
前端·后端·开源
程序视点7 小时前
Escrcpy 3.0投屏控制软件使用教程:无线/有线连接+虚拟显示功能详解
前端·后端
silent_missile7 小时前
element-plus穿梭框transfer的调整
前端·javascript·vue.js
专注VB编程开发20年7 小时前
OpenXml、NPOI、EPPlus、Spire.Office组件对EXCEL ole对象附件的支持
前端·.net·excel·spire.office·npoi·openxml·spire.excel
古蓬莱掌管玉米的神7 小时前
coze娱乐ai换脸
前端