首页 > 其他分享 >Cesium实时轨迹、点击运动、插值坐标、轨迹回放

Cesium实时轨迹、点击运动、插值坐标、轨迹回放

时间:2022-12-13 22:46:34浏览次数:55  
标签:轨迹 const Cartesian3 插值 value let Cesium path

在这里插入图片描述

老规矩,效果图放前面,满足需求接着往下看。

加载模型

模型加载方式为primitive,利用矩阵设置世界坐标,modelMatrix,包含位置方向,在此基础上可以做到物体位移。

let Primitive: Cesium.Primitive
let entityPath: Cesium.Entity
let path: number[][] = [104.063914, 30.640356, 500] //存在路线数组
let linePath: Cesium.Cartesian3[] = [] //轨迹线数组
const initModel = () => { //初始化模型
  const { Viewer } = window
  let pos = Cesium.Cartesian3.fromDegrees(path[0][0], path[0][1], path[0][2])
  linePath = [pos]
  entityPath = Viewer.entities.add({ //轨迹线
      polyline: {
          positions: new Cesium.CallbackProperty(() => {
              return linePath;
          }, false),
          show: true,
          material: Cesium.Color.RED,
          width: 1.5,
          clampToGround: true //是否贴地
      }
  });
  Primitive = Viewer.scene.primitives.add( //加载模型
      Cesium.Model.fromGltf({
          url: "/models/GroundVehicle.glb",
          modelMatrix: Cesium.Transforms.headingPitchRollToFixedFrame(
              pos,
              hpRoll,
              Cesium.Ellipsoid.WGS84,
              fixedFrameTransform,
          ),
          scale: 1,
          maximumScale: 10
      })
  );
  Primitive.readyPromise.then((model) => {
      // Play and loop all animations at half-speed
      (<any>model).activeAnimations.addAll({
          multiplier: 0.5,
          loop: Cesium.ModelAnimationLoop.REPEAT,
      });
  });
}

新增加的点

利用 Cesium.Cartesian3.lerp做插值运算

Cesium.Cartesian3.lerp (start, end, t, result)
使用提供的笛卡尔计算在 t 处的线性插值或外插。
start 笛卡尔3 在 0.0 时对应于 t 的值。
end 笛卡尔3 在 1.0 时对应于 t 的值。
t 数字 沿 t 进行插值的点。
result 笛卡尔3 存储结果的对象。

let maxIndex = 0// 最大插值经纬度数组索引
let m_lng = ref<number>(104.063914)
let m_lat = ref<number>(30.640356)
let m_alt = ref<number>(496)
const add = () => { //添加位置点进入数组
    if (m_lng.value === 0 || m_lat.value === 0) {
        message.warning('经纬度不能为0')
        return
    }
    let len = path.length - 1
    if (path[len] && m_lng.value === path[len][0] && m_lat.value === path[len][1]) return
    path.push([m_lng.value, m_lat.value, m_alt.value])
    m_lng.value = 0
    m_lat.value = 0
    interpolation() //将轨迹添加进数组中
    if (path.length === 1) {
        initModel()
    }
}
const interpolation = () => { //插值坐标
    if (path.length < 2) return
    const po1 = Cesium.Cartesian3.fromDegrees(path[pathIndex][0], path[pathIndex][1], path[pathIndex][2])
    const po2 = Cesium.Cartesian3.fromDegrees(path[pathIndex + 1][0], path[pathIndex + 1][1], path[pathIndex + 1][2])
    getPosition(po1, po2, m_interval.value).then((res: Cesium.Cartesian3[]) => {
        showPath = showPath.concat(res)
        pathIndex++
        maxIndex = showPath.length
    })
}
const getPosition = (startP: Cesium.Cartesian3, endP: Cesium.Cartesian3, duration: number) => {
    return new Promise((resolve: (value: Cesium.Cartesian3[]) => void) => {
        let arr: Cesium.Cartesian3[] = []
        duration = duration * 1000
        for (let i = 0; i <= duration; i = i + forNum) {
            let pos = Cesium.Cartesian3.lerp(startP, endP, i / duration, new Cesium.Cartesian3());
            arr.push(pos)
        }
        if (duration % forNum !== 0) {
            arr.push(endP)
        }
        resolve(arr);
    })
}

监听坐标变化

利用 viewer.scene.preUpdate.addEventListener(render)做实时回调
获取将在更新或渲染场景之前引发的事件。事件的订阅者接收场景实例作为第一个参数,当前时间作为第二个参数。
有新的点位就进行更新,preUpdate的回调时间不稳定,大概范围在16ms~100ms之间,所以实时轨迹会有些许延迟。比如两个点位之间时间间隔是3S,但是实际动画运行出来可能是4S、5S。

const start = () => { //轨迹开始
    const { Viewer } = window
    const controller = Viewer.scene.screenSpaceCameraController;
    const r =
        2.0 *
        Math.max((<any>Primitive).boundingSphere.radius, Viewer.camera.frustum.near);
    controller.minimumZoomDistance = r * 0.5;
    Viewer.scene.preUpdate.addEventListener(render) //监听下一帧
}
let index = 0 //插值经纬度索引
let autoDirection = true; //自动调整方向
const fixedFrameTransform = Cesium.Transforms.localFrameToFixedFrameGenerator("north", "west");
const render = (scene: Cesium.Scene, time: number) => {
    if (index >= maxIndex) return
    if (autoDirection && index > 0 && !showPath[index - 1].equals(showPath[index])) {
        const heading = Helper.getHeading(
            showPath[index - 1],
            showPath[index],
        );
        if (heading) hpRoll.heading = heading
    }
    linePath.push(showPath[index])
    Cesium.Transforms.headingPitchRollToFixedFrame(
        showPath[index],
        hpRoll,
        Cesium.Ellipsoid.WGS84,
        fixedFrameTransform,
        Primitive.modelMatrix
    );
    index += 1
}

清理监听

onUnmounted(() => {
    const { Viewer } = window;
    (Viewer as Cesium.Viewer).scene.preUpdate.removeEventListener(render)
})

资源地址

资源地址

有问题请留言。欢迎交流

本文转自 https://blog.csdn.net/qq_41400354/article/details/126093933?spm=1001.2014.3001.5502,如有侵权,请联系删除。

标签:轨迹,const,Cartesian3,插值,value,let,Cesium,path
From: https://www.cnblogs.com/hustshu/p/16980879.html

相关文章