cesium 实现三维无人机航拍过程实景效果

需求背景

需要实现一个动态的三维无人机航拍过程实景效果
代码开发中,迭代功能待续...

解决效果

index.vue

<template>
  <div>
    <el-button class="btn" @click="start">开始</el-button>
  </div>
</template>

<script>
let lineEntity,
    lineDatasource = new Cesium.CustomDataSource("line-polygun"),
    wrjModelDatasource = new Cesium.CustomDataSource("wrj"),
    wrjEntity,
    wrjLineEntity,
    curPosition,
    lineArr =[]

export default {
  data() {
    return {
      // 飞行区域边界线坐标
      coordinates: [[116.069898, 31.303655], [116.098708, 31.322126], [116.108063, 31.311256], [116.079317, 31.292959], [116.069898, 31.303655]],
      // 飞行路线
      points: [[116.069898, 31.303655, 200], [116.098708, 31.322126, 200], [116.108063, 31.311256, 200], [116.079317, 31.292959, 200]],
      // 当前飞行位置
      curRuningArr_i: 0,
      curRuningArr: [],
    }
  },
  mounted() {
    const viewer = window.dasViewer;
    viewer.scene.terrainProvider = new Cesium.EllipsoidTerrainProvider()
    viewer.dataSources.add(lineDatasource);
    viewer.dataSources.add(wrjModelDatasource);
    this.initwork()
  },
  destory() {
    lineDatasource.entities.removeAll()
    viewer.dataSources.remove(lineDatasource);
    wrjModelDatasource.entities.removeAll()
    viewer.dataSources.remove(wrjModelDatasource);
  },
  methods: {
    initwork() {
      const viewer = window.dasViewer;
      const pos = Cesium.Cartesian3.fromDegreesArray(this.coordinates.flat())
      const entity = lineDatasource.entities.add({
        polyline: {
          positions: pos,
          width: 1.5,
          material: Cesium.Color.fromCssColorString("#C0C0C0").withAlpha(0.5),
          // disableDepthTestDistance: Number.POSITIVE_INFINITY, //解决遮挡问题
          heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
        }
      })
      viewer.flyTo(entity)
      this.addModel()
    },
    addModel() {
      const viewer = window.dasViewer;
      const positions = Cesium.Cartesian3.fromDegreesArrayHeights(this.points.flat())
      wrjEntity = wrjModelDatasource.entities.add({
        position: Cesium.Cartesian3.fromDegrees(116.069898, 31.303655, 200),
        model: {
          uri: process.env.VUE_APP_MODEL_API + '/wrj.glb',
          scale: 100,
          horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
          verticalOrigin: Cesium.VerticalOrigin.CENTER,
        },
      })
      wrjLineEntity = wrjModelDatasource.entities.add({

        polyline: {
          positions: positions,
          width: 1.5,
          material: Cesium.Color.fromCssColorString("red").withAlpha(1),
          heightReference: Cesium.HeightReference.NONE,
        }
      })
      // viewer.scene.postRender.addEventListener(()=>{
      //   wrjLineEntity.polyline.positions = lineArr
      // });
    },
    start() {
      let runQueue = this.points.map((_, i) => ([this.points[i], this.points[i + 1]]))
      runQueue.pop()
      runQueue = runQueue.map(pos => ({
        pos,
        startCartesian3: Cesium.Cartesian3.fromDegrees(pos[0][0], pos[0][1], pos[0][2]), // 该路径起始点
        cartesian3Pos: pos.map(item => Cesium.Cartesian3.fromDegrees(item[0], item[1], item[2])) // 该路径起始点和目标点
      }))
      this.runRecursion(0, runQueue)
    },
    runRecursion(i, runArr, callback) {
      const self = this
      const speed = 700 // todo 默认速度为500m/s
      const cartesian3Pos = runArr[i].cartesian3Pos
      lineArr = runArr.slice(0, Math.max(1, i + 1)).map(item => item.startCartesian3).flat()
      self.curRuningArr_i = i
      self.curRuningArr = runArr
      self.runFn(cartesian3Pos, lineArr, speed, () => {
        if (++i < runArr.length) self.runRecursion(i, runArr, callback)
      })
    },
    runFn([startPosition, targetPosition], lineArr, speed, callback) { // [startPosition 初始点位 targetPosition 目标点位] lineArr 路径线点位 speed 速度
      const subtract = Cesium.Cartesian3.subtract(startPosition, targetPosition, new Cesium.Cartesian3());
      const meter = Cesium.Cartesian3.magnitude(subtract) // 得出距离多少米
      const step = meter / speed
      const startTime = Cesium.JulianDate.now()
      curPosition = new Cesium.Cartesian3()
      wrjEntity.position = new Cesium.CallbackProperty(() => {
        const elapsedTime = Cesium.JulianDate.secondsDifference(Cesium.JulianDate.now(), startTime);
        const ratio = elapsedTime / step;
        if (ratio >= 1.0) {
          callback()
          return targetPosition.clone()
        } else {
          return Cesium.Cartesian3.lerp(startPosition, targetPosition, ratio, curPosition)
        }
      }, false);
    },
  }
}
</script>

<style lang="less" scoped>
.btn {
  position: fixed;
  top: 20px;
  left: 20px;
}
</style>
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
实现Cesium三维漫游飞行效果可以通过以下步骤实现: 1. 创建一个Cesium Viewer对象: ``` var viewer = new Cesium.Viewer('cesiumContainer'); ``` 2. 通过Camera控制视角和位置: ``` viewer.camera.setView({ destination: Cesium.Cartesian3.fromDegrees(longitude, latitude, height), orientation: { heading: Cesium.Math.toRadians(heading), pitch: Cesium.Math.toRadians(pitch), roll: Cesium.Math.toRadians(roll) } }); ``` 3. 为视角添加动画效果: ``` var duration = 5.0; // 动画时间,单位为秒 Cesium.CameraFlightPath.createAnimationCartographic(viewer.scene, { destination: Cesium.Cartographic.fromDegrees(longitude, latitude, height), orientation: { heading: Cesium.Math.toRadians(heading), pitch: Cesium.Math.toRadians(pitch), roll: Cesium.Math.toRadians(roll) }, duration: duration }); ``` 4. 添加键盘和鼠标事件: ``` // 飞行到指定位置 function flyTo(longitude, latitude, height, heading, pitch, roll) { viewer.camera.flyTo({ destination: Cesium.Cartesian3.fromDegrees(longitude, latitude, height), orientation: { heading: Cesium.Math.toRadians(heading), pitch: Cesium.Math.toRadians(pitch), roll: Cesium.Math.toRadians(roll) } }); } // 监听键盘和鼠标事件 document.addEventListener('keydown', function(event) { switch (event.keyCode) { case 87: // W viewer.camera.moveForward(1000.0); break; case 83: // S viewer.camera.moveBackward(1000.0); break; case 65: // A viewer.camera.moveLeft(1000.0); break; case 68: // D viewer.camera.moveRight(1000.0); break; case 38: // Up arrow viewer.camera.lookUp(0.1); break; case 40: // Down arrow viewer.camera.lookDown(0.1); break; case 37: // Left arrow viewer.camera.lookLeft(0.1); break; case 39: // Right arrow viewer.camera.lookRight(0.1); break; default: return; } event.preventDefault(); }, false); ``` 通过以上步骤,即可实现Cesium三维漫游飞行效果
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

柳晓黑胡椒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值