cesium-无人机航线问题

1.cesium 创建三维航线 

写的磕磕绊绊 期间遇到很多问题

1.无人机的姿态实时更新

 查阅cesium文档 发现了Cesium.Transforms.headingPitchRollQuaternion(position, hpr)

2.无人机视锥跟随无人机转向

这个问题困了好久 一开始尝试自己画了锥形 后面控制锥形旋转 平移 一直没成功  只能做到一直向下探测跟随  后面做了个模型  一开始也没成功 直达发现模型修改原点起点位置  将模型用blender把起点设置成锥顶 

3.无人机飞行会有后退动作

在画航线的时候 一开始设置

// interpolationAlgorithm: Cesium.HermitePolynomialApproximation,
// interpolationDegree: 2

发现在碰到重复点的时候会有一个向前起飞又回退的动作 考虑过速度和惯性问题  一直尝试也没成功 后来改成

interpolationDegree: 1,
interpolationAlgorithm: Cesium.LinearApproximation

 4.目前还存在的问题 

点击航线将无人机定位到航线点击位置  存在误差  在俯视的情况下 正确性颇高 但是其他角度就会有问题

     init () {
            const Cesium = this.Cesium
            // console.log(this.path3DList)
            this.showSpin = true
            let _this = this
            let startTime = ""
            let endTime = ""
            if (this.flightPathList.length) {
                startTime = this.flightPathList[0].recordTime ? moment(this.flightPathList[0].recordTime).format("YYYY-MM-DDTHH:mm:ss") + "Z" : ''
                endTime = this.flightPathList[this.flightPathList.length - 1].recordTime ? moment(this.flightPathList[this.flightPathList.length - 1].recordTime).format("YYYY-MM-DDTHH:mm:ss") + "Z" : ''
            }
            var viewer = new Cesium.Viewer("cesiumContainer", {
                infoBox: false,
                terrainProvider: Cesium.createWorldTerrain(),
                shouldAnimate: false,
                geocoder: false,//右上角第一个位置的查找工具
                homeButton: false,//右上角第二个位置的home图标
                sceneModePicker: false,//右上角第三个选择视角模式
                baseLayerPicker: false,//右上角第四个位置的图层选择器
                navigationHelpButton: false,//右上角第五个导航帮助按钮
                timeline: true,
                animation: false,//控制左下角的动画器件
                fullscreenButton: false,
                scene3DOnly: true,
                selectionIndicator: true,
            })
            //设置地形
            // viewer.terrainProvider = Cesium.createWorldTerrain({
            //     requestWaterMask: true,//水渲染需求
            //     requestVertexNormals: true//顶点法线渲染需求
            // })
            // viewer.scene.globe.depthTestAgainstTerrain = true//深度显示(用于湖泊河流 水深对周围景观的影响)
            // viewer.scene.globe.enableLighting = true//全局日照(受太阳,月亮的位置而影响光照信息)
            // console.log(this.flightPathList)
            let point = this.flightPathList[this.currentCount]
            // console.log(point.yaw, point.pitch, point.roll, Number(point.height), 'height')
            var initialPosition = new Cesium.Cartesian3.fromDegrees(point.longitude, point.latitude, Number(point.height))//摄像机位置 ,经度,纬度,高度
            // var initialOrientation = new Cesium.HeadingPitchRoll.fromDegrees(point.yaw, point.pitch, point.roll)//飞行 专用的  表示旋转角度之类的东西:
            var homeCameraView = {
                destination: initialPosition,
                // orientation: {
                //     heading: Number(initialOrientation.heading) + 5, //偏航角
                //     pitch: Number(initialOrientation.pitch) + 5,     //俯仰角
                //     roll: initialOrientation.roll//滚转角
                // },
                complete: () => {
                    setTimeout(() => {
                        viewer.camera.zoomOut(2000)
                        this.showSpin = false
                    }, 2000)

                }
            }

            //飞行时,相机的动画属性设置
            homeCameraView.dutaion = 1.0
            homeCameraView.maximumHeight = 2000
            homeCameraView.pitchAdjustHeight = 2000
            homeCameraView.endTransform = Cesium.Matrix4.IDENTITY
            //
            // var CesiumViewerSceneController = viewer.scene.screenSpaceCameraController
            // CesiumViewerSceneController.inertiaSpin = 1
            // CesiumViewerSceneController.inertiaTranslate = 1
            // CesiumViewerSceneController.inertiaZoom = 1

            var czml = [
                {
                    id: "document",
                    name: "CZML Path",
                    version: "1.0",
                    clock: {
                        interval: `${startTime}/${endTime}`,
                        currentTime: `${startTime}`,
                        // currentTime: `${'2021-11-16T17:03:44Z'}`,
                        multiplier: 1,
                        clockStep: Cesium.ClockStep.TICK_DEPENDENT,
                        // clockStep: 1
                    },
                },
                {
                    id: "path_2",
                    name: "path2",
                    availability: `${startTime}/${endTime}`,
                    path: {
                        show: [
                            {
                                interval: `${startTime}/${endTime}`,
                                boolean: false
                            }
                        ],
                        width: 0,
                    },
                    position: {
                        epoch: `${startTime}`,
                        cartographicDegrees: this.path3DList,
                    },
                },
                {
                    id: "path",
                    name: "path1",
                    availability: `${startTime}/${endTime}`,
                    path: {
                        show: [
                            {
                                interval: `${startTime}/${endTime}`,
                                boolean: true
                            }
                        ],
                        width: 6,
                        material: {
                            solidColor: {
                                color: { rgba: [255, 161, 65, 255], }
                            }
                        }
                    },
                    billboard: {
                        color: {
                            rgba: [0, 255, 255, 255]
                        },
                        eyeOffset: { "cartesian": [0, 0, 0] },
                        pixelOffset: { "cartesian2": [0, 0] },
                        horizontalOrigin: "CENTER",
                        verticalOrigin: "CENTER",
                        image: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAjSURBVChTYyAa/EcDUGEIgIphAKg0XRSAAFQMDqDChAADAwDC13+BJ+0oDwAAAABJRU5ErkJgggAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
                        scale: 1,
                        show: true
                    },
                    position: {
                        epoch: `${startTime}`,
                        cartographicDegrees: this.path3DList,
                    },
                }
            ]

            var dronePromise = Cesium.CzmlDataSource.load(czml)
            var drone
            var drone_2
            dronePromise.then(dataSource => {
                viewer.dataSources.add(dataSource)
                drone = dataSource.entities.getById('path')
                drone_2 = dataSource.entities.getById('path_2')
                // 无人机模型
                drone.model = {
                    id: 'wrj',
                    name: 'wrj',
                    uri: '/WRJ02.glb',
                    minimumPixelSize: 48,
                    scale: 0.2,
                    maximumScale: 10
                }
                // uri: 'https://gist.githubusercontent.com/rahwang/9843cb77fc1c6d07c287566ed4e08ee3/raw/dc3a9ff6fc73b784519ac9371c0e2cbd3ab3dc47/CesiumDrone.gltf',
                // 添加无人机位置
                //VelocityOrientationProperty(速度方向属性):基于所给的位置属性的速度来得出一个四元旋转属性
                // drone.orientation = new Cesium.VelocityOrientationProperty(drone.position)
                drone.position.setInterpolationOptions({
                    // interpolationAlgorithm: Cesium.HermitePolynomialApproximation,
                    // interpolationDegree: 2
                    interpolationDegree: 1,
                    interpolationAlgorithm: Cesium.LinearApproximation
                })
                drone_2.position.setInterpolationOptions({
                    interpolationDegree: 1,
                    interpolationAlgorithm: Cesium.LinearApproximation
                })
                drone_2.model = {
                    id: 'wrj_zhuiti',
                    name: 'wrj_zhuiti',
                    uri: '/WRJ_zhuiti.glb',
                    minimumPixelSize: 48,
                    scale: 1,
                    maximumScale: 10
                }
                //跟踪无人机
                // viewer.trackedEntity = drone
                //取消跟踪无人机
                // viewer.trackedEntity = undefined
                viewer.camera.flyTo(homeCameraView)
            })
            //白模
            // var shpTileset = new Cesium.Cesium3DTileset({
            //     url: 'http://10.2.13.73:9000/model/ad9d5be0767e11ebab9c9b084bddd6a4/tileset.json',
            // })
            // shpTileset.style = new Cesium.Cesium3DTileStyle({
            //     color: {
            //         conditions: [
            //             ["${height} >= 300", "rgba(45, 0, 75, 0.5)"],
            //             ["${height} >= 200", "rgb(102, 71, 151)"],
            //             ["${height} >= 100", "rgb(170, 162, 204)"],
            //             ["${height} >= 50", "rgb(224, 226, 238)"],
            //             ["${height} >= 25", "rgb(252, 230, 200)"],
            //             ["${height} >= 10", "rgb(248, 176, 87)"],
            //             ["${height} >= 5", "rgb(198, 106, 11)"],
            //             ["true", "rgb(127, 59, 8)"],
            //         ],
            //     },
            // })
            // viewer.scene.primitives.add(shpTileset)

            viewer.timeline.makeLabel = (datetime) => {
                return this.timeFmt(datetime, "HH:mm:ss")
            }
            viewer.timeline.zoomTo(viewer.clock.startTime, viewer.clock.stopTime)//设置时间轴可见趋近
            viewer.clock.canAnimate = false
            viewer.clock.onTick.addEventListener((tick) => {
                // this.scanEntity.orientation = null
                // viewer.entities.remove(this.scanBox)
                let time = this.timeFmt(tick.currentTime, "YYYY-MM-DD HH:mm:ss")
                this.preTime = this.nowTime
                this.nowTime = time
                if (this.preTime == this.nowTime) {
                    return
                }
                this.currentTime = getTime(this.flightPathList[0].recordTime, time)
                let allTime = (new Date(this.flightPathList[this.flightPathList.length - 1].recordTime).getTime() - new Date(this.flightPathList[0].recordTime).getTime()) / 1000
                let nowTime = (new Date(time).getTime() - new Date(this.flightPathList[0].recordTime).getTime()) / 1000
                this.currentWidth = (nowTime * 1000) / (allTime * 1000) * 100 + '%'
                this.isPlay = viewer.clock.shouldAnimate
                this.$emit('start3D', { isPlay: viewer.clock.shouldAnimate, time, tick: viewer.clock.shouldAnimate })
                function getTime (start, now) {
                    let time = (new Date(now).getTime() - new Date(start).getTime()) / 1000
                    // console.log(time, 'time')
                    _this.$emit('getCurrentCount', time)
                    let s = showNum(time % 60)
                    let m = showNum(parseInt(time / 60))
                    return `${m}:${s}`
                }
                function showNum (num) {
                    if (num < 10) {
                        return '0' + num
                    }
                    return num
                }

                //设置偏转俯仰翻滚
                if (this.timePathList[time]) {

                    let { pitch, roll, yaw, longitude, latitude, height } = this.timePathList[time]
                    var position = Cesium.Cartesian3.fromDegrees(longitude, latitude, height)
                    var position_2 = Cesium.Cartesian3.fromDegrees(longitude, latitude, height)
                    //no 视锥
                    var hpr = new Cesium.HeadingPitchRoll(Cesium.Math.toRadians(Number(yaw) + 90), Cesium.Math.toRadians(Number(pitch)), Cesium.Math.toRadians(Number(roll)))
                    //has 视锥
                    // var hpr = new Cesium.HeadingPitchRoll(Cesium.Math.toRadians(Number(yaw) + 180), Cesium.Math.toRadians(Number(pitch)), Cesium.Math.toRadians(Number(roll)))

                    var orientation = Cesium.Transforms.headingPitchRollQuaternion(position, hpr)
                    drone.orientation = orientation

                    viewer.entities.remove(this.scanBox)
                    var headingC = Cesium.Math.toRadians(180 + Number(yaw))
                    var pitchC = Cesium.Math.toRadians(90.0 + 0)
                    var rollC = Cesium.Math.toRadians(0)
                    var hprC = new Cesium.HeadingPitchRoll(headingC, pitchC, rollC)
                    drone_2.orientation = Cesium.Transforms.headingPitchRollQuaternion(position_2, hprC)

                }

            })
            viewer.clock.onStop.addEventListener((tick) => {
                viewer.clock.shouldAnimate = false
                this.$emit('clearMap3D')
            })
            //航点
            this.drawPoint(viewer)
            //
            // currentCount
            var time_count = new Date(_this.flightPathList[_this.currentCount].recordTime)
            var utc_time = Cesium.JulianDate.fromDate(time_count)//UTC
            viewer.clock.currentTime = Cesium.JulianDate.addHours(utc_time, 8, new Cesium.JulianDate())
            //航点点击
            viewer.screenSpaceEventHandler.setInputAction(function leftClick (movement) {
                var pickedFeature = viewer.scene.pick(movement.position)
                console.log(pickedFeature)
                if (pickedFeature && pickedFeature.id && pickedFeature.id._name == "point") {
                    let time_bj = new Date(_this.flightPathList[pickedFeature.id._id].recordTime)
                    let utc = Cesium.JulianDate.fromDate(time_bj)//UTC
                    viewer.clock.currentTime = Cesium.JulianDate.addHours(utc, 8, new Cesium.JulianDate())
                    return
                }
                if (pickedFeature && pickedFeature.id && (pickedFeature.id._name == "wrj_zhuiti" || pickedFeature.id._name == 'wrj' || pickedFeature.id._name == 'path2')) {
                    return
                }
                if (pickedFeature && pickedFeature.id && (pickedFeature.id._name != "wrj_zhuiti" || pickedFeature.id._name != 'path2')) {
                    let pointSelectArray = []
                    var earthPosition = viewer.camera.pickEllipsoid(movement.position, viewer.scene.globe.ellipsoid)
                    var cartographic = Cesium.Cartographic.fromCartesian(earthPosition, viewer.scene.globe.ellipsoid, new Cesium.Cartographic())
                    var lng = Cesium.Math.toDegrees(cartographic.longitude)
                    var lat = Cesium.Math.toDegrees(cartographic.latitude)
                    // var height = cartographic.height

                    // function getDistance (lng1, lat1, lng2, lat2) {
                    //     let startPosition = new Cesium.Cartesian3.fromDegrees(lng1, lat1)
                    //     let endPosition = new Cesium.Cartesian3.fromDegrees(lng2, lat2)
                    //     let distance = Cesium.Cartesian3.distance(startPosition, endPosition)//求两点直线距离,单位为米
                    //     return distance
                    // }
                    // console.log("[Lng=>" + lng + ",Lat=>" + lat + ",H=>" + height + "]")

                    // 经纬度转换成三角函数中度分表形式
                    function rad (d) {
                        return d * Math.PI / 180.0
                    }
                    // 根据经纬度计算距离
                    function getDistance (lng1, lat1, lng2, lat2,) {
                        var radLat1 = rad(lat1)
                        var radLat2 = rad(lat2)
                        var a = radLat1 - radLat2
                        var b = rad(lng1) - rad(lng2)
                        var s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) +
                            Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)))
                        s = s * 6378.137 // EARTH_RADIUS;
                        s = Math.round(s * 10000) //输出为公里
                        return s
                    }
                    _this.flightPathList.forEach(el => {
                        pointSelectArray.push(getDistance(el.longitude, el.latitude, lng, lat))
                    })
                    // console.log(lat, lng, height, pointSelectArray)
                    //获取最小值的下标
                    function getMinIndex (arr) {
                        var min = arr[0]
                        //声明了个变量 保存下标值
                        var index = 0
                        for (var i = 0; i < arr.length; i++) {
                            if (min > arr[i]) {
                                min = arr[i]
                                index = i
                            }
                        }
                        return index
                    }
                    let index = getMinIndex(pointSelectArray)
                    let time_bj = new Date(_this.flightPathList[index].recordTime)
                    let utc = Cesium.JulianDate.fromDate(time_bj)//UTC
                    viewer.clock.currentTime = Cesium.JulianDate.addHours(utc, 8, new Cesium.JulianDate())
                }
            }, Cesium.ScreenSpaceEventType.LEFT_UP)//LEFT_CLICK
            //鼠标移动
            var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas)
            handler.setInputAction((movement) => {
                var haveEn = viewer.scene.pick(movement.endPosition)
                // console.log(haveEn, 'haveEn1', haveEn.id._id)
                if (haveEn) {
                    viewer._container.style.cursor = "pointer"
                } else {
                    viewer._container.style.cursor = "default"
                }
            }, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
            viewer._cesiumWidget._creditContainer.style.display = "none"
            this.viewer = viewer
            console.log(viewer)
        },

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值