Cesium 实现(空中、地面)漫游功能

252 阅读1分钟

简单、容易实现,只需要传入一个数组,包含经纬度、高度以及相机的其他参数直接能实现漫游

下面是示例数组:

 waypointsDm: [
                { longitude: 110.84702901337153, latitude: 21.72178740738186, height: 911.5463374263119, heading: 0.19594529336319066, pitch: -0.7990472454086719, roll: 2.6645352591003757e-14 },
                { longitude: 110.86942328584473, latitude: 21.709049738726268, height: 991.8520778683095, heading: 0.15564193765157341, pitch: -0.6858565157753844, roll: 2.6645352591003757e-14 },
                { longitude: 110.89241829126586, latitude: 21.69568867439878, height: 991.8520778797083, heading: 0.15579040181238568, pitch: -0.6858565157753844, roll: 2.930988785010413e-14 },
                { longitude: 110.92929593458405, latitude: 21.685945517480302, height: 924.2145103391056, heading: 0.0003038198060272279, pitch: -0.7668438290919148, roll: 2.398081733190338e-14 },
                { longitude: 110.9471029442024, latitude: 21.67595736542084, height: 894.243866888826, heading: 0.1561431603537331, pitch: -0.6860010062568578, roll: 2.930988785010413e-14 },
                { longitude: 110.89213061028616, latitude: 21.645872680198057, height: 7019.862437779638, heading: 0.0036562095227417046, pitch: -0.7677969280350254, roll: 2.3092638912203256e-14 },
            ]

实现代码:

只需要将waypointsDm当参数传入roam函数即可

 roam(list) {
            let that = this;
            this.$message({
                message: '开始漫游',
                type: 'success'
            })
            let mylist = list
            // 创建SampledPositionProperty和SampledProperty
            var flightPath = new Cesium.SampledPositionProperty(); // 创建飞行路径
            var headingProperty = new Cesium.SampledProperty(Number); // 创建航向属性
            var pitchProperty = new Cesium.SampledProperty(Number); // 创建俯仰属性
            var rollProperty = new Cesium.SampledProperty(Number); // 创建滚转属性
            var startTime = Cesium.JulianDate.now(); // 获取当前时间作为起始时间
            var timeStepInSeconds = 30; // 每个路径点之间的时间间隔为30秒

            // 遍历所有路径点
            for (var i = 0; i < mylist.length; i++) {
                var time = Cesium.JulianDate.addSeconds(startTime, i * timeStepInSeconds, new Cesium.JulianDate()); // 计算每个路径点的时间
                var position = Cesium.Cartesian3.fromDegrees(
                    mylist[i].longitude,
                    mylist[i].latitude,
                    mylist[i].height
                ); // 将经纬度和高度转换为笛卡尔坐标
                flightPath.addSample(time, position); // 将位置样本添加到飞行路径
                headingProperty.addSample(time, mylist[i].heading); // 将航向样本添加到航向属性
                pitchProperty.addSample(time, mylist[i].pitch); // 将俯仰样本添加到俯仰属性
                rollProperty.addSample(time, mylist[i].roll); // 将滚转样本添加到滚转属性
            }

            // 设置飞行路径的可用时间
            var totalSeconds = timeStepInSeconds * (mylist.length - 1); // 计算总时间
            viewer.clock.startTime = startTime.clone(); // 设置起始时间
            viewer.clock.stopTime = Cesium.JulianDate.addSeconds(startTime, totalSeconds, new Cesium.JulianDate()); // 设置停止时间
            viewer.clock.currentTime = startTime.clone(); // 设置当前时间
            viewer.clock.clockRange = Cesium.ClockRange.CLAMPED; // 设置时钟范围为CLAMPED,飞行路径播放一次后停止 LOOP_STOP循环执行
            viewer.clock.multiplier = 5; // 设置时钟速度

            // 动态更新视角参数和相机位置
            var onTickHandler = function (clock) {
                var currentTime = clock.currentTime; // 获取当前时间
                var currentPosition = flightPath.getValue(currentTime); // 获取当前时间的飞行路径位置
                var currentHeading = headingProperty.getValue(currentTime); // 获取当前时间的航向
                var currentPitch = pitchProperty.getValue(currentTime); // 获取当前时间的俯仰
                var currentRoll = rollProperty.getValue(currentTime); // 获取当前时间的滚转

                if (currentPosition && currentHeading !== undefined && currentPitch !== undefined && currentRoll !== undefined) {
                    viewer.scene.camera.setView({
                        destination: currentPosition, // 设置相机位置为当前飞行路径位置
                        orientation: {
                            heading: Cesium.Math.toRadians(currentHeading), // 设置相机的航向
                            pitch: currentPitch, // 设置相机的俯仰
                            roll: currentRoll // 设置相机的滚转
                        }
                    });
                }
                // 检查是否到达终点
                if (Cesium.JulianDate.compare(clock.currentTime, viewer.clock.stopTime) >= 0) {
                    viewer.clock.onTick.removeEventListener(onTickHandler); // 移除onTick事件监听器,停止动态更新视角
                    that.$message({
                        message: '漫游结束',
                        type: 'success'
                    })
                }
            };
            viewer.clock.onTick.addEventListener(onTickHandler); // 添加onTick事件监听器,动态更新视角参数和相机位置
        }