Cesium中实现模型贴地飞行进行三维游览

该博客介绍了如何在Cesium中实现模型的贴地飞行游览功能,通过解析 CZML 数据并计算路径点之间的距离,设置时间间隔,结合地形数据更新模型位置,创建平滑的飞行轨迹。同时,博主分享了一段未成功的尝试,希望通过每帧获取地形高度实现游览,期待读者提供解决方案。
摘要由CSDN通过智能技术生成

Cesium中实现模型贴地飞行进行三维游览

代码如下

我这里使用的是vue,需要将拾取到的点传入其中,调用这个函数就可以实现模型的匀速贴地飞行。
里面代码有些冗余,自己可以修改一下。

czmlNew(){
        let positions = this.$czmlActiveLocation;

        let distance = []
        for (let i = 0;i<positions.length-1;i++){  
          let dis = Cesium.Cartesian3.distance(positions[i],positions[i+1])
          distance.push(dis)
        }

        // new Cartesian3(1216348.1632364073, -4736348.958775471, 4081284.5528982095) 所需的数据格式
        let stPos = positions[0];
        let endPos = positions[positions.length-1];

        let times =[Cesium.JulianDate.fromDate(new Date())]
        times.push(Cesium.JulianDate.addSeconds(times[0], 360, new Cesium.JulianDate()))
        for(let i = 1;i<positions.length-1;i++){
          let s = Cesium.JulianDate.addSeconds(times[i], 360 * (distance[i]/distance[0]), new Cesium.JulianDate())
          times.push(s)
        }

        let stTime = times[0];
        let endTime = times[times.length-1];
        var start = stTime.clone();
        var stop = endTime.clone();
        this._viewer.clock.startTime = start.clone();
        this._viewer.clock.stopTime = stop.clone();
        this._viewer.clock.currentTime = start.clone();
        this._viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP; //Loop at the end
        this._viewer.clock.multiplier = 10;

        let timeOfResolution = 6;

        let oriSamples = new Cesium.SampledProperty(Cesium.Cartesian3);
        oriSamples.addSamples(times, positions);
        
        let geodesic = new Cesium.EllipsoidGeodesic( 。
                stPos,
                endPos
        );
        let lenInMeters = Math.ceil(geodesic.surfaceDistance); 
        let samplesNum = Math.floor( 
                Cesium.JulianDate.secondsDifference(endTime, stTime) / timeOfResolution  
        );

        let sampledPositions = [];
        let sampledTimes = [];

        for (let i = 0; i < samplesNum + 1; i++) {
          let sampleTime = Cesium.JulianDate.addSeconds(
                  stTime,
                  i * timeOfResolution,
                  new Cesium.JulianDate()
          );
          let tmpPos = oriSamples.getValue(sampleTime);
          sampledPositions.push(Cesium.Cartographic.fromCartesian(tmpPos));
          sampledTimes.push(sampleTime);
        }
        var that = this

        let promise = Cesium.sampleTerrainMostDetailed(  
                that._viewer.terrainProvider,
                sampledPositions
        ).then(() => {
          let carPositionProperty = new Cesium.SampledPositionProperty();

          for (let i = 0;i<sampledPositions.length;i++){
            sampledPositions[i].height = sampledPositions[i].height + 20  
          }

          for (let i = 0; i < samplesNum + 1; i++) {
            carPositionProperty.addSample(
                    sampledTimes[i],
                    Cesium.Ellipsoid.WGS84.cartographicToCartesian(sampledPositions[i])
            );
          }

          let isConstant = false;
          let curSegmentNo = 0;
          let lastSegementNo = -1;
          let p2 = Cesium.Ellipsoid.WGS84.cartographicToCartesian(sampledPositions[sampledPositions.length-1]);
          let curPolyline = [stPos]; 

          this._viewer.entities.add({
            polyline: {
              positions: new Cesium.CallbackProperty(function (time, result) {

                curSegmentNo = Math.floor(
                        Cesium.JulianDate.secondsDifference(time, stTime) / timeOfResolution
                );
                if (curSegmentNo !== lastSegementNo) {
                  let tmpP = Cesium.Ellipsoid.WGS84.cartographicToCartesian(
                          sampledPositions[curSegmentNo]
                  );
                  curPolyline.push(tmpP);
                  lastSegementNo = curSegmentNo;
                }
                if (curSegmentNo === samplesNum - 1) {
                  curSegmentNo = 0;
                  curPolyline = [];
                  console.log("cleared!");
                }

                return curPolyline;
              }, isConstant),
              clampToGround: true,
              width: 5,
              show: false,
              material: Cesium.Color.RED,
              availability: new Cesium.TimeIntervalCollection([
                new Cesium.TimeInterval({
                  start: stTime,
                  stop: endTime,
                }),
              ]),
            },
          });

          var position = carPositionProperty;
          this.flyEntity = this._viewer.entities.add({
            availability: new Cesium.TimeIntervalCollection([
              new Cesium.TimeInterval({
                start: start,
                stop: stop,
              }),
            ]),
            position: position,

            orientation: new Cesium.VelocityOrientationProperty(position),

            model: {
              uri: this.czml.czmlModelUrl,
              minimumPixelSize: 64,
              maximumSize: 128,
              show:true,
              runAnimations: true 
            },
            path: {
              show:false,
              resolution: 1,
              material: new Cesium.PolylineGlowMaterialProperty({
                glowPower: 0.1,
                color: Cesium.Color.YELLOW,
              }),
              width: 1,
            },
          });
        });
      },

另外

之前原本想用下面这种方法,通过每一帧获取地形高度来实现模型游览的,可是没有实现,如果某位大佬有解决方法的话请不吝赐教。

this._viewer.scene.postRender.addEventListener()
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值