企业管理系统定制开发Cesium实时轨迹、点击运动、插值坐标、轨迹回放。

老规矩,企业管理系统定制开发效果图放前面,企业管理系统定制开发满足需求接着往下看。

加载模型

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

let Primitive: Cesium.Primitivelet entityPath: Cesium.Entitylet 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,      });  });}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40

新增加的点

利用 .Cartesian3.lerp做插值运算

Cesium.Cartesian3. (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);    })}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43

监听坐标变化

利用 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}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

清理监听

onUnmounted(() => {    const { Viewer } = window;    (Viewer as Cesium.Viewer).scene.preUpdate.removeEventListener(render)})
  • 1
  • 2
  • 3
  • 4

资源地址

有问题请留言。欢迎交流

网站建设定制开发 软件系统开发定制 定制软件开发 软件开发定制 定制app开发 app开发定制 app开发定制公司 电商商城定制开发 定制小程序开发 定制开发小程序 客户管理系统开发定制 定制网站 定制开发 crm开发定制 开发公司 小程序开发定制 定制软件 收款定制开发 企业网站定制开发 定制化开发 android系统定制开发 定制小程序开发费用 定制设计 专注app软件定制开发 软件开发定制定制 知名网站建设定制 软件定制开发供应商 应用系统定制开发 软件系统定制开发 企业管理系统定制开发 系统定制开发