高德经纬度点位过滤算法

Vue.component('ambulance-layer', {
    template: html,
    props: ['map', 'infoWindow', 'amblanceMap'],
    data() {
        return {
            mainHeight: $defConf.height - 60,
            tableHeight: $defConf.height - 60 - 60 - 37,
            formSize: $defConf.formSize || 'mini',
            formBtnSize: $defConf.formBtnSize || 'mini',
            tableSize: $defConf.tableSize || 'mini',
            tableBtnSize: $defConf.tableBtnSize || 'mini',
            dialogBtnSize: $defConf.dialogBtnSize || 'mini',
            btns: $defConf.btns,
            pageSizes: $defConf.pageSizes,
            pageSize: 3,
            headerAlign: $defConf.tableHeaderAlign || 'left',
            pageNo: 1,
            totalCount: 0,
            totalCount2: 0,
            pageNo2: 1,
            pageSize2: 2,
            pageNo3: 0,
            pageSize3: 2,
            totalCount3: 0,
            pageNo4: 0,
            pageSize4: 2,
            totalCount4: 0,
            carsList: [],
            curIndex: -1,
            curHisIndex: '',
            detailFlag: false,

            eventDetails: {},

            icon: '',
            defaultIcon: './resources/com/bsoft/emss/sys/gismap/css/ambuance-red.svg',
            xcIcon: './resources/com/bsoft/emss/sys/gismap/css/hpi.svg', //现场
            yyIcon: './resources/com/bsoft/emss/sys/gismap/css/wb_hospital.svg', //医院
            trackIcon: './resources/com/bsoft/emss/sys/gismap/css/track_car.png',
            icon2: './resources/com/bsoft/emss/sys/gismap/css/fenzhan.svg',
            directIcon: './resources/com/bsoft/emss/sys/gismap/css/car_02.png', //测试用
            vehicleId: '',
            taskId: '',

            hisTaskId: '',
            hisVehicleId: '',
            hisTrackData: [],//历史车辆轨迹
            eventHisDetails: {},
            detailHistFlag: false,
            hisPatientData: [],


            patientData: [],
            mapMarkerList: [],
            vehicleHistoryData: [],
            lineArr: [],
            trackMark: null,
            trackMark2: null,
            xcAddressMark: null,  //现场地点
            sdxcAddressMark: null, //送达现场
            posIcon: null,
            posIcon2: null,

            senceLnglat: null, //现场经纬度
            hospiLnglat: [], //医院经纬度
            vehicleForm: {workState: [], devices: ''},
            workStateOptions: [],
            times: null,
            times2: null,
            drawPathTimer: null,
            showMonitorDialog: false,
            userId: '',
            vehicleCd: '',
            fullBtnLoading: false,
            fullHisLoading: false,
            devices: [{na: "监控", ty: "2"}, {na: "导航", ty: "3"}],//ma:"Ma"端 ,ty:"4"
            refreshFlag: false,
            driving: null,
            tempTaskState: '',
            tempStateText: '',
            tempTaskTime: '', //当前车辆状态改变时间
            filterPostion: [],  //存储的是相同记录中 时间最新的一条
            maxSpeed: 180,
            taskStates: [], //当前车辆和任务的所有状态
            preFiltersTracks: [], //过滤之前的数据,用于地图上判断显示不同的状态标签
            stateMarker: null
        }
    },
    methods: {
        //打开当前任务-now
        drawPath(index, item) {
            let self = this
            self.tempTaskState = item.state
            self.clearAmbulanceTimes() //清除定时任务
            self.clearAmbulanceTimes2()
            if (this.isCicked) {
                return;
            }
            this.isCicked = true;
            this.drawPathTimer = setTimeout(() => {
                self.vehicleId = item.vehicle_id
                self.taskId = item.taskId
                self.curIndex = index
                self.eventDetails = item;
                self.isCicked = false;

                self.tempTaskTime = item.update_time
                self.tempStateText = item.state_text
                self.clickShowVehicleSign()
                self.getVehicleExpectTime({distance: '', time: ''})
                self.queryCurTrack(item);
            }, 500);

        },
        //查看当前车辆轨迹路径-now
        queryCurTrack(item) {
            this.map.clearMap()
            if (this.driving) {
                this.driving.clear()
                this.driving = null
            }
            let info = {
                lnglat: item.lnglat,
                taskId: this.taskId,
                vehicleId: item.vehicle_id,
                flag: ''
            }
            this.generateCurText()
            this.findVehicleTrackList(info)

        },


        //打开历史任务-history
        drawHisPath(index, item) {
            let self = this
            self.hisVehicleId = item.vehicle_id
            self.hisTaskId = item.taskId
            self.curHisIndex = index
            self.eventHisDetails = item;
            self.queryHisTrack(item);

        }
        ,
        //查看车辆历史轨迹路径-history
        queryHisTrack(item) {
            this.map.clearMap()
            if (this.driving) {
                this.driving.clear()
                this.driving = null
            }
            let info = {
                taskId: item.taskId,
                vehicleId: item.vehicle_id,
                flag: ''
            }
            this.generateHisText()
            this.findVehicleHisTrackList(info)

        }
        ,

        //生成现场地点和医院标识-now
        generateCurText() {
            let xcLnglat = [] //当前现场地点
            let sdLnglat = [] //当前送达地点
            if (this.eventDetails.xclat && this.eventDetails.xclng) {
                xcLnglat = [this.eventDetails.xclng, this.eventDetails.xclat]
                this.getSceneMarker(xcLnglat, this.eventDetails.xcaddress, "xc")
            }
            if (this.eventDetails.sdlat && this.eventDetails.sdlng) {
                sdLnglat = [this.eventDetails.sdlng, this.eventDetails.sdlat]
                this.getSceneMarker(sdLnglat, this.eventDetails.to_location, "sd")
            }
        }
        ,

        //生成现场地点和医院标识-history
        generateHisText() {
            let xcLnglat = [] //历史现场地点
            let sdLnglat = [] //历史送达地点
            if (this.eventHisDetails.xclat && this.eventHisDetails.xclng) {
                xcLnglat = [this.eventHisDetails.xclng, this.eventHisDetails.xclat]
                this.getSceneMarker(xcLnglat, this.eventHisDetails.xcaddress, "xc")
            }
            if (this.eventHisDetails.sdlat && this.eventHisDetails.sdlng) {
                sdLnglat = [this.eventHisDetails.sdlng, this.eventHisDetails.sdlat]
                this.getSceneMarker(sdLnglat, this.eventHisDetails.to_location, "sd")
            }
        }
        ,

        //显示gis图层右下角任务信息展示牌
        clickShowVehicleSign() {
            this.$emit("clickShowVehicleSign", {
                taskState: this.eventDetails.state,
                vehicleCd: this.eventDetails.cd,
                lng: this.eventDetails.lng,
                lat: this.eventDetails.lat,
                updateTime: this.eventDetails.update_time,
                vehicleId: this.eventDetails.vehicle_id,
                NEUpdateTime: this.eventDetails.NEUpdateTime,
                speed: this.eventDetails.speed ? (this.eventDetails.speed * 3.6).toFixed(1) : '-',
                installNav: this.eventDetails.installNav == '0' ? "否" : "是" //是否安装导航
            })

        }
        ,

        //查询车辆历史事项
        findVehicleHistoryById(lnglat, flag) {
            let condition = {
                pageNo: this.pageNo3 || 1,
                pageSize: this.pageSize3 || 2
            }
            this.fullHisLoading = true
            $ajax({
                url: 'api/emss.gis/findVehicleHistoryById',
                jsonData: [this.vehicleId, condition],
                async: true
            }).then(res => {
                this.fullHisLoading = false
                this.vehicleHistoryData = res.body.data.items
                this.totalCount3 = res.body.data.total

            }).catch(e => {
                this.fullHisLoading = false
            })

        }
        ,


        //查询当前任务所有患者人信息
        findAcceptancePiByTaskId() {
            let condition = {
                pageNo: this.pageNo2 || 1,
                pageSize: this.pageSize2 || 2
            }
            $ajax({
                url: 'api/emss.gis/findAcceptancePiByTaskId',
                jsonData: [this.taskId, condition]
            }).then(res => {
                this.patientData = res.body.data.items
                this.totalCount2 = res.body.data.total
            })
        }
        ,

        //查询历史中某个任务所有患者人信息
        findAcceptancePiByHisTaskId() {
            let condition = {
                pageNo: this.pageNo4 || 1,
                pageSize: this.pageSize4 || 2
            }
            $ajax({
                url: 'api/emss.gis/findAcceptancePiByTaskId',
                jsonData: [this.hisTaskId, condition]
            }).then(res => {
                this.hisPatientData = res.body.data.items
                this.totalCount4 = res.body.data.total
            })
        }
        ,


        //打开历史项
        expandHis(index, item) {
            this.curHisIndex = index
            this.hisTaskId = item.taskId
            this.eventHisDetails = item
            this.detailHistFlag = true
            this.findAcceptancePiByHisTaskId()
        }
        ,

        //双击列表中车辆
        expand(index, item) {
            clearTimeout(this.drawPathTimer);
            this.isCicked = false;
            this.vehicleId = item.vehicle_id
            this.taskId = item.taskId
            this.curIndex = index
            this.detailFlag = true
            this.eventDetails = item

            // if ("2" === item.work_state) { //任务中
            //查询当前车辆历史任务
            this.findVehicleHistoryById()
            // }
            //查询当前车辆任务受理人
            this.findAcceptancePiByTaskId()
        }
        ,

        //查询当前任务车轨迹-now
        findVehicleTrackList(info) {
            //对经纬度进行转换为高德
            let lnglat = transform(info.lnglat[0], info.lnglat[1])
            //当前车辆点标记生成
            let trackMarker = this.getCurMarker(lnglat)
            this.map.setFitView(trackMarker)

            $ajax({
                url: 'api/emss.gis/findVehicleTrackList',
                jsonData: [info.vehicleId, info.taskId],
                async: true
            }).then(res => {
                this.lineArr = []
                this.preFiltersTracks = [] //该对象用于处理获取当前任务所有操作状态,且在地图上标记出来每个操作的功能使用。选择性复制。
                this.filterPostion = []
                if (null != res.body.data && res.body.data.length > 0) {
                    this.$message({message: '正在绘制车辆轨迹...', type: 'success', center: true})
                    this.clearAmbulanceTimes2()

                    //点位去重(方便过滤操作 不需要考虑持续时间点相同问题)
                    let filters = this.filterRepeatPos(res.body.data)
                    //obs非高德经纬度转为高德
                    let transToGdGps = this.transformPos(filters)

                    this.preFiltersTracks = transToGdGps //过滤前,保存临时数据

                    //点位过滤(过滤轨迹中不符合要求点位)
                    this.lineArr = this.filterTracks(transToGdGps)


                    let trackPolyline = null;
                    // 2:非任务中
                    // taskAmbulance:任务受理车辆列表双击车牌号 。work_state车辆工作状态:1:待命;2:任务中;3:暂停;4:未上班;'
                    if (info.flag !== "taskAmbulance" && "2" !== this.eventDetails.work_state) {
                        trackPolyline = this.generateLastTaskTrack(this.lineArr)
                    } else {
                        trackPolyline = this.generateTrack(this.lineArr)
                    }
                    this.map.setFitView([trackPolyline]);
                    this.detailFlag = false
                    this.refreshTrackMark(trackMarker, trackPolyline, info);

                    //查询任务状态集合
                    this.getTaskStates(info)
                } else {
                    this.$message({message: '未查询到轨迹信息,车载设备未上传轨迹数据!', type: 'warning', center: true})
                    this.refreshByVehicleId(trackMarker, info)
                }

            })

        }
        ,

        //对非高德经纬度进行转换
        transformPos(arrs) {
            let data = []
            for (let i = 0; i < arrs.length; i++) {
                if (arrs[i]?.ty == '2') { //车载gps
                    let lnglat = transform(arrs[i].longitude, arrs[i].latitude)
                    arrs[i].longitude = lnglat[0]
                    arrs[i].latitude = lnglat[1]
                    data.push(arrs[i])

                } else {
                    data.push(arrs[i])
                }
            }
            return data;
        },

        /**
         *  解决车辆停止时GPS严重漂移问题(一次考虑前中后三个点:a 、b、c,可以理解为三角形)
         * @param 一次考虑前中后三个点
         * author:  duKang
         * time :2023/03/22
         *
         * 过滤前data:[a,a1,a2, b,b1,b2, c, c1,d] 解释:相同字母点位(经纬度)表示相同a=a1=a2 但 != b
         */

        filterTracks(data) {

            if (data.length <= 0) {
                console.log("数组长度为0 ");
                return
            }
            let resultArray = new Array();

            //三段距离判断点是否要过滤
            let thirdPos = ''  //对应c点
            //先放第一个点到数组。
            resultArray.push([data[0].longitude, data[0].latitude])
            this.filterPostion.push(data[0])
            for (let i = 0; i < data.length; i++) {

                if (i < data.length - 1) {
                    let prePos = data[i]
                    let lastPos = data[i + 1] //时间较晚的点
                    //当两点一样,则跳过上个点 同时取下个点
                    let dist4 = calcDistance([lastPos.longitude, lastPos.latitude], [prePos.longitude, prePos.latitude])
                    if (dist4 == 0) {
                        continue
                    }

                    //速度大于180km/h
                    let flag = this.getDist(lastPos, prePos)
                    if (flag) { //点位异常:  进行下面处理
                        // c点
                        if (data[i + 2]) {
                            thirdPos = data[i + 2]
                            //b->c距离
                            let dist2 = calcDistance([thirdPos.longitude, thirdPos.latitude], [lastPos.longitude, lastPos.latitude])
                            if (dist2 == 0) { //说明是b1 、b2两点 就要取后面一点
                                if (data[i + 3]) {
                                    let fourPos = data[i + 3]
                                    //b->c距离
                                    dist2 = calcDistance([fourPos.longitude, fourPos.latitude], [lastPos.longitude, lastPos.latitude])
                                    //b->c距离
                                    let dist3 = calcDistance([fourPos.longitude, fourPos.latitude], [prePos.longitude, prePos.latitude])
                                    if (dist2 < dist3) {
                                        //说明lastPos是正常点 正常保存
                                    } else if (dist2 > dist3) {
                                        console.log("去除的点1" + [lastPos.longitude, lastPos.latitude])
                                        //将lastPos点过滤掉
                                        i = i + 2 //跳过相同的两个点
                                        resultArray.push([prePos.longitude, prePos.latitude])
                                        this.filterPostion.push(prePos)
                                        continue
                                    }
                                }
                            } else {
                                //a->c距离
                                let dist3 = calcDistance([thirdPos.longitude, thirdPos.latitude], [prePos.longitude, prePos.latitude])
                                if (dist2 < dist3) {
                                    //说明lastPos是正常点 正常保存
                                } else if (dist2 > dist3) {
                                    //将lastPos点过滤掉
                                    i = i + 1
                                    resultArray.push([prePos.longitude, prePos.latitude])
                                    this.filterPostion.push(prePos)
                                    console.log("去除的点2" + [lastPos.longitude, lastPos.latitude])
                                    continue
                                }
                            }

                        }
                    }
                    resultArray.push([prePos.longitude, prePos.latitude])
                    this.filterPostion.push(prePos)
                }
            }
            //判断轨迹最后的点位是否合规 距离过远 则去除(最后点位出现问题频率较高)
            if (resultArray.length > 0) {
                resultArray = this.checkLastPos(resultArray, data)
            }
            // 过滤后[a,a2,b,b2,c,c1,d]  只保留首尾
            return resultArray;
        },

        /**
         * dukang
         * time :20230323
         * 判断轨迹最后的点位是否合规 距离过远 则去除(最后点位出现问题频率较高)
         */

        checkLastPos(resultArray, data) {
            let pre = this.filterPostion[this.filterPostion.length - 1]
            if (data[data.length - 2]) {
                let da1 = data[data.length - 1]
                let da2 = data[data.length - 2] //时间较da1早的一个点
                //判断数组最后两个值是不是同一个经纬度(数据经过去重的,连着同个经纬度只会有首部和尾部两个点在data中)
                if (da2.latitude == da1.latitude && da2.longitude == da1.longitude) {
                    let flag = this.getDist(da2, pre)
                    if (!flag) {
                        resultArray.push([da2.longitude, da2.latitude])
                        //但是要把da1存到数组中,因为任务中车辆实时轨迹判断点  要用时间最新的一个点
                        this.filterPostion.push(da1)
                    }
                } else {
                    //说明最后一条经纬度没连着相同的点
                    let flag = this.getDist(da1, pre)
                    if (!flag) {
                        resultArray.push([da1.longitude, da1.latitude])
                        this.filterPostion.push(da1)
                    }
                }
            } else if (data[data.length - 1]) {
                let da1 = data[data.length - 1]
                let flag = this.getDist(da1, pre)
                if (!flag) {
                    resultArray.push([da1.longitude, da1.latitude])
                    this.filterPostion.push(da1)
                }
            }
            return resultArray;

        },
        //过滤重复点位 ,如果一样的数据,则保留每条时间最新、最晚两条的点位数据
        filterRepeatPos(data) {
            let arr = []
            let tempPos = null //用于存储一样的数据
            let tempBest = null
            let flag = true
            //过滤国外的经纬度
            let dataArr = []
            for (let i = 0; i < data.length; i++) {
                let outOfFlag = outOfChina(data[i].latitude, data[i].longitude)
                if (outOfFlag) {
                    continue
                }
                dataArr.push(data[i])
            }

            for (let i = 0; i < dataArr.length; i++) {
                if (i < dataArr.length - 1) {
                    let prePos = null
                    if (tempPos) {
                        prePos = tempPos
                    } else {
                        prePos = dataArr[i]
                    }
                    let lastPos = dataArr[i + 1] //时间较晚的点

                    let dist = calcDistance([lastPos.longitude, lastPos.latitude], [prePos.longitude, prePos.latitude]);
                    if (dist == 0) { //说明前后两点经纬度一样
                        if (flag) {
                            arr.push(prePos) //当前相同位置首条点位
                            flag = false
                        }
                        tempPos = lastPos
                        continue
                    } else {
                        //每次拿到的是
                        tempBest = prePos
                        tempPos = null
                        flag = true
                    }
                    arr.push(prePos)
                }
            }
            //arr说明数组长度为空
            if (arr.length == 0) {
                arr.push(dataArr[dataArr.length - 1])
            }
            //判断最后两个点是否相同
            if (arr.length > 0) {
                let last = dataArr[dataArr.length - 1] // 数组最后一个点位
                let pre = arr[arr.length - 1]
                if (last.insertTime != pre.insertTime) {
                    arr.push(last)
                }
            }

            return arr
        },

        //判断行驶中距离是否符合常规
        getDist(lastPos, prePos) {
            let flag = false

            let dist = calcDistance([lastPos.longitude, lastPos.latitude], [prePos.longitude, prePos.latitude]);

            let preTime = new Date(parseFloat(prePos.time)).valueOf();
            let lastTime = new Date(parseFloat(lastPos.time)).valueOf();

            let hour = (parseFloat(lastTime) - parseFloat(preTime)) / (60 * 60);
            let speed = dist / hour;
            if (speed - this.maxSpeed >= 0.000001) { //最大速度 180km/h
                flag = true
            }
            return flag;
        },


        //刷新车辆最新位置
        refreshTrackMark(trackMarker, trackPolyline, info) {
            if (trackMarker) {
                let oldPos = trackMarker.getPosition();

                //获取当前车辆图层当前所有maarker点
                let allMarker = this.map.getAllOverlays("marker");
                /* if (allMarker.indexOf(trackMarker) > 0) {
                     return;
                 }*/
                let param = {
                    taskId: info.taskId,
                    vehicleId: info.vehicleId
                }
                $ajax({
                    url: 'api/emss.gis/queryTrackPositionByInfo',
                    jsonData: [param],
                    async: true
                }).then(resp => {
                    let pos = resp.body.data;
                    if (pos?.longitude && pos?.latitude) {
                        //对非高德经纬度转换
                        if(pos?.ty =='2'){ //车载gps
                             let transPos = transform(pos.longitude, pos.latitude)
                             pos.longitude = transPos[0]
                             pos.latitude = transPos[1];
                        }

                        let lnglat = new AMap.LngLat(pos.longitude, pos.latitude);
                        if (!oldPos.equals(lnglat)) {
                            //判断当前点是否有问题
                            let flag = this.filterSinglePoint(pos)
                            if (!flag) {
                                this.filterPostion.push(pos) //将没问题的点存到临时变量
                                this.produceTrack(trackMarker, oldPos, lnglat, trackPolyline)
                            }

                        } else {
                            if (!this.driving) { //当点击第一次当前车辆时候
                                let flag = this.filterSinglePoint(pos)
                                if (!flag) {
                                    this.checkState(lnglat)
                                }
                            }

                        }

                        this.getVehicleBestpostion(pos)
                    }
                    let self = this;
                    if (null !== self.times) {
                        clearTimeout(self.times)
                    }
                    self.times = setTimeout(() => {
                        self.refreshTrackMark(trackMarker, trackPolyline, info);
                    }, 2 * 5000);
                })
            }
        },


        //刷新车辆点位置 --无任务情况下
        refreshByVehicleId(trackMarker, info) {
            if (trackMarker) {
                let oldPos = trackMarker.getPosition();

                //marker>1个 不刷新
                /* let allMarker = this.map.getAllOverlays("marker");
                 if (allMarker.indexOf(trackMarker) > 0) {
                     return;
                 }*/
                let param = {
                    vehicleId: info.vehicleId
                }
                $ajax({
                    url: 'api/emss.gis/queryTrackPositionByInfo',
                    jsonData: [param],
                    async: true
                }).then(resp => {
                    let pos = resp.body.data;
                    if (pos?.longitude && pos?.latitude) {
                        //转为高德经纬度
                        if(pos?.ty =='2'){     //车载gps
                            let transPos = transform(pos.longitude, pos.latitude)
                            pos.longitude = transPos[0]
                            pos.latitude = transPos[1];
                        }


                        let lnglat = new AMap.LngLat(pos.longitude, pos.latitude);
                        if (!oldPos.equals(lnglat)) {
                            //设置图片角度
                            let nDegree = this.calAngle(oldPos, lnglat)
                            if (nDegree > 0) {
                                trackMarker.setAngle(nDegree);
                                //只让车辆图片旋转,不影响lable中内容。
                                $(".car-track-marker>.amap-icon").css({
                                    'transform': 'rotate(' + nDegree + 'deg)'
                                })
                            }
                            //trackMarker.moveTo(lnglat, 10); //使用此种方式,setangle不生效
                            trackMarker.setPosition(lnglat)

                            this.map.setCenter(lnglat);
                        }
                        this.getVehicleBestpostion(pos)

                    }
                    let self = this;
                    if (null !== self.times2) {
                        clearTimeout(self.times2)
                    }
                    self.times2 = setTimeout(() => {
                        self.refreshByVehicleId(trackMarker, info);
                    }, 2 * 5000);
                })

            }

        },


        produceTrack(trackMarker, oldPos, lnglat, trackPolyline) {
            //计算车辆角度
            let nDegree = this.calAngle(oldPos, lnglat)
            if (nDegree > 0) {
                trackMarker.setAngle(nDegree);
                //只让车辆图片旋转,不影响lable中内容。
                $(".car-track-marker>.amap-icon").css({
                    'transform': 'rotate(' + nDegree + 'deg)'
                })
            }


            //trackMarker.moveTo(lnglat, 10); //使用此种方式,setangle不生效
            trackMarker.setPosition(lnglat)
            this.map.setCenter(lnglat);
            let state = this.tempTaskState
            //暂停、站内待命、途中待命后 轨迹停止更新
            if (state != '20' && state != '21' && state != '22') {
                if (trackPolyline != null) {
                    let path = trackPolyline.getPath();
                    path.push(lnglat);
                    trackPolyline.setPath(path);

                    //每次更新最后点位 就重新规划一次未行走路线
                    this.checkState(lnglat)
                }
            }
        }
        ,

        //计算角度angle
        calAngle(oldPos, lnglat) {
            if (oldPos.lng && oldPos.lat && lnglat.lng && lnglat.lat) {
                let nDegree = calcRotateAngle(oldPos.lng, oldPos.lat, lnglat.lng, lnglat.lat);
                if (nDegree < 0) {
                    nDegree = 360 + nDegree;
                }
                nDegree = parseInt(nDegree.toFixed(0));

                return nDegree;
            }


            return 0;
        },
        // 过滤不规则的经纬度 返回true/false
        filterSinglePoint(pos) {

            //是否出国界
            let flagOut = outOfChina(pos.latitude, pos.longitude)
            if (flagOut) {
                return true   //超出 不添加点到轨迹
            }
            if (this.filterPostion.length > 0) {
                let ptLast = this.filterPostion[this.filterPostion.length - 1];//前一个点
                let dist = calcDistance([pos.longitude, pos.latitude], [ptLast.longitude, ptLast.latitude]);

                if (dist <= 0.001) { //当距离小于0.01km 不移动车位置
                    return true;
                } else {
                    let flag = this.getDist(pos, ptLast)//判断当前点是否超出行驶距离  是:true   最快速度45米/秒
                    if (!flag) { //点位正常 ,正常将该点添加到轨迹中
                        return false
                    }
                }
            }
            return true
        },
        //查询当前任务车轨迹-history
        findVehicleHisTrackList(info) {
            $ajax({
                url: 'api/emss.gis/findVehicleTrackList',
                jsonData: [info.vehicleId, info.taskId],
                async: true
            }).then(res => {
                if (null != res.body.data && res.body.data.length > 0) {
                    this.$message({message: '正在绘制车辆历史轨迹...', type: 'success', center: true})
                    this.filterPostion = []
                    this.preFiltersTracks = []
                    //过滤重复的点位数据
                    let filterArr = this.filterRepeatPos(res.body.data)
                    //obs设备非高德经经纬度转换
                    let transToGdGps = this.transformPos(filterArr)

                    this.preFiltersTracks = transToGdGps
                    //过滤不符合点位
                     let hisLineArr = this.filterTracks(transToGdGps)

                    let trackPolyline = this.generateLastTaskTrack(hisLineArr)
                    let trackMarker = this.getCurMarker(hisLineArr[hisLineArr.length - 1])
                    this.map.setFitView([trackPolyline]);

                    this.getTaskStates(info)
                } else {
                    this.$message({message: '未查询到历史轨迹信息', type: 'warning', center: true})
                }

            })

        }
        ,

        getVehicleBestpostion(pos) {
            let speed = pos?.speed
            let data = {
                lng: pos?.longitude,
                lat: pos?.latitude,
                NEUpdateTime: pos?.updateTime,
                speed: speed ? (speed * 3.6).toFixed(1) : "-"
            }
            this.$emit("getVehicleBestpostion", data)
        }
        ,

        checkState(startLngLat) {
            let state = this.tempTaskState
            //根据状态判断当前车辆位置
            // 1	任务派遣中2	收到指令3	驶向现场 4	到达现场5	送往医院 6	到达医院  异常状态: 20-暂停  21-站内待命 22-途中待命',
            if (state) {
                if (this.driving != null) {
                    this.driving.clear()
                }
                //取现场地点为导航结束点
                if (state == '01' || state == '02' || state == '03') {
                    if (this.eventDetails.xclat && this.eventDetails.xclng) {
                        let xcLnglat = [this.eventDetails.xclng, this.eventDetails.xclat]
                        this.routePlan(startLngLat, xcLnglat)
                    }
                } else if (state == '04' || state == '05') { //取送往地址为结束点
                    if (this.eventDetails.sdlat && this.eventDetails.sdlng) {
                        let sdLnglat = [this.eventDetails.sdlng, this.eventDetails.sdlat]
                        this.routePlan(startLngLat, sdLnglat)
                    }
                }
            }
        }
        ,
        //路线规划
        routePlan(startLngLat, endLngLat) {
            let self = this
            if (this.driving != null) {
                this.driving.clear()
            }
            this.driving = new AMap.Driving({
                policy: AMap.DrivingPolicy.LEAST_TIME,
                map: this.map,
                hideMarkers: true, //隐藏起始点图标
            })
            this.driving.search(startLngLat, endLngLat, function (status, result) {
                if (status === 'complete') {
                    self.getVehicleExpectTime(result.routes[0])
                }
            });
        }
        ,

        //预计送达时间和距离
        getVehicleExpectTime(routes) {
            let self = this
            self.$emit("getVehicleExpectTime", {
                distance: routes.distance ? (routes.distance / 1000).toFixed(1) : '',
                minute: routes.time ? Math.floor(routes.time / 60) : ''
            })
        }
        ,
        //清除定时  MapComp.js中也在调用
        clearAmbulanceTimes() {
            let self = this;
            if (null !== self.times) {
                clearTimeout(self.times)
            }
        }
        ,

        clearAmbulanceTimes2() {
            let self = this
            if (null !== self.times2) {
                clearTimeout(self.times2)
            }
        },
        //生成车辆当前位置点标记
        getCurMarker(curlnglat) {
            if (null != this.trackMark) {
                this.map.remove(this.trackMark)
            }
            if (undefined == curlnglat || curlnglat == null) {
                return
            }
            //let icon = this.icon == '' ? this.defaultIcon : this.icon;
            let icon = this.directIcon
            this.getNewMarker(icon, '')
            this.trackMark.setPosition(curlnglat) //当前位置点
            this.trackMark.setLabel({
                content: "" + this.eventDetails.cd + "", //设置文本标注内容
            });

            this.trackMark.on('click', () => {
                this.infoWindow.setContent(this.getContent(this.eventDetails).join("
")); this.infoWindow.open(this.map, this.trackMark.getPosition()); }) this.trackMark.dom.classList.add('car-track-marker'); return this.trackMark; } , //现场地点点标记 //生成车辆当前位置点标记 getSceneMarker(position, address, type) { if (undefined == position || position == null) { return } let style = {} if (type === 'xc') { style = { 'padding': '.35rem 0.80rem', 'margin-bottom': '0.5rem', 'border-radius': '.25rem', 'background-color': 'white', 'width': '12rem', 'border-width': 0, 'box-shadow': '0 2px 6px 0 rgba(114, 124, 245, .5)', 'text-align': 'center', 'font-size': '9px', 'color': 'blue' } } else if (type === 'sd') { style = { 'padding': '.35rem 0.80rem', 'margin-bottom': '0.5rem', 'border-radius': '.25rem', 'background-color': 'white', 'width': '12rem', 'border-width': 0, 'box-shadow': '0 2px 6px 0 rgba(114, 124, 245, .5)', 'text-align': 'center', 'font-size': '9px', 'color': 'red' } } // 创建纯文本标记 let text = new AMap.Text({ text: address, anchor: 'center', // 设置文本标记锚点 map: this.map, angle: 0, style: style, position: position }); } , //------------生成车辆轨迹------------------ generateTrack(lineArr) { let trackPolyline = new AMap.Polyline({ map: this.map, path: lineArr, showDir: true, strokeColor: '#28F', strokeOpacity: 1, //线透明度 strokeWeight: 6, //线宽 strokeStyle: "solid", //线样式 lineJoin: 'round', lineCap: 'round', }) return trackPolyline; } , //虚线-灰色车辆轨迹 generateLastTaskTrack(lineArr) { let trackPolyline = new AMap.Polyline({ map: this.map, path: lineArr, showDir: true, strokeColor: 'grey', //线颜色 strokeOpacity: 1, //线透明度 strokeWeight: 6, //线宽 strokeStyle: "dashed", //线样式 strokeDasharray: [15, 10], //虚线间隔 lineJoin: 'round', outlineColor: '#ffeeff', borderWeight: 3, lineCap: 'round', isOutline: true, lineJoin: 'round', lineCap: 'round', }) return trackPolyline; // this.map.setFitView([trackPolyline]) } , //创建新对象 getNewMarker(icon, icon2, curlnglat) { /* let posIcon = new AMap.Icon({ size: new AMap.Size(30, 30), imageOffset: new AMap.Pixel(0, 0), imageSize: new AMap.Size(30, 30), anchor: 'center', //设置锚点, image: icon, });*/ this.trackMark = new AMap.Marker({ // offset: new AMap.Pixel(-10, -5), offset: new AMap.Pixel(-13, -26), map: this.map, icon: icon, autoRotation: false, //true不生效 angle: 0 }); } , doQueryVehicle() { this.pageNo = 1 this.pageSize = 3 this.findVehiclLayerList(); } , //双击调度台进来的时候车辆 openCar(info) { if (info.vehicleId) { this.findSingVehiclLayerList(info.vehicleId) } } , enter() { this.findVehiclLayerList() } , //查询车辆列表信息 findVehiclLayerList() { let condition = { pager: { pageNo: this.pageNo || 1, pageSize: this.pageSize || 3 }, workState: this.vehicleForm.workState, devices: this.vehicleForm.devices, cd: this.vehicleForm.cd } this.fullBtnLoading = true; $ajax({ url: 'api/emss.gis/findVehiclLayerList', jsonData: [condition], }).then(res => { this.fullBtnLoading = false; if (undefined != res.body.data.items && res.body.data.items.length > 0) { for (let item of res.body.data.items) { if ('' == item.lng || undefined == item.lng || undefined == item.lat || '' == item.lat) { continue } item.lnglat = [item.lng, item.lat] //车辆当前位置坐标 } } this.carsList = res.body.data.items this.totalCount = res.body.data.total // this.initMap() }).catch(e => { this.fullBtnLoading = false }) } , //查询车辆列表信息 findSingVehiclLayerList(temp) { let condition = { pager: { pageNo: 1, pageSize: 3 }, ty: "tc", vehicleId: temp, } $ajax({ url: 'api/emss.gis/findVehiclLayerList', jsonData: [condition], }).then(res => { if (undefined != res.body.data.items && res.body.data.items.length > 0) { for (let item of res.body.data.items) { if ('' == item.lng || undefined == item.lng || undefined == item.lat || '' == item.lat) { continue } item.lnglat = [item.lng, item.lat] //车辆当前位置坐标 } this.drawPath(-1, res.body.data.items[0]) } else { this.$message({message: '未查询到该车信息!', type: 'warning'}) } }).catch(e => { }) } , // ---------页面获取当前车辆位置---- initMap() { this.mapMarkerList = [] let pos_icon = []; let pos_marker = []; for (let i = 0; i < this.carsList.length; i++) { // 创建 AMap.Icon 实例: pos_icon[i] = new AMap.Icon({ size: new AMap.Size(30, 30), // 图标尺寸 image: this.directIcon, // Icon的图像 imageOffset: new AMap.Pixel(0, 0), // 图像相对展示区域的偏移量,适于雪碧图等 imageSize: new AMap.Size(30, 30), // 根据所设置的大小拉伸或压缩图片 anchor: 'center', //设置锚点 }); pos_marker[i] = new AMap.Marker({ position: this.carsList[i].lnglat, offset: new AMap.Pixel(-10, -5), icon: pos_icon[i], // 添加 Icon 图标 URL title: this.carsList[i].vehicle, }); pos_marker[i].setLabel({ content: "" + this.carsList[i].cd + "", //设置文本标注内容 }); pos_marker[i].on('click', () => { this.infoWindow.setContent(this.getContent(this.carsList[i]).join("
")); this.infoWindow.open(this.map, pos_marker[i].getPosition()); }) /*if (this.carsList[i].lat && this.carsList[i].lng) { this.mapMarkerList.push(pos_marker[i]) }*/ } //this.map.add(this.mapMarkerList) //this.map.setZoom(10) //自适应地图 // this.map.setFitView(this.mapMarkerList) } , /* 获取救护车图标*/ getIcon() { $ajax({ url: 'api/emss.gis/getIconByElType', jsonData: ['4'] }).then(res => { if (res.body.data.length > 0) { this.icon = res.body.data[0].pathsrc } }) } , getContent(car) { let cd = car.cd == undefined ? '-' : car.cd let state_text = car.state_text == undefined ? '-' : car.state_text let to_location = car.to_location == undefined ? '-' : car.to_location let driver = (car.driver == undefined || car.driver == 'undefined') ? '-' : car.driver let doctor = (car.doctor == undefined || car.doctor == 'undefined') ? '-' : car.doctor let nurse = (car.nurse == undefined || car.nurse == 'undefined') ? '-' : car.nurse var s = []; s.push('
' + ' ' + cd + '
' + '' + state_text + '
' + '
' + '
' + '
目的地:' + to_location + '
' + '
' + '
医生: ' + doctor + '
' + '
护士: ' + nurse + '
' + '
司机: ' + driver + '
' + '
'); return s; } , lookMonitor(vehicleCd) { let self = this if (null != self.monitor) { clearTimeout(self.monitor) } if (vehicleCd) { self.vehicleCd = vehicleCd.substring(1, vehicleCd.length) } console.log(self.vehicleCd) self.showMonitorDialog = true self.$message({type: "success", message: "正在开启监控..."}) // self.monitor = setTimeout(() => { /*self.$refs.monitorDemo.createPlayer(self.vehicleCd) self.$refs.monitorDemo.createPlayer2(self.vehicleCd)*/ var domain = window.location.origin + window.location.pathname;// 这里替换成自己的域名 let base = new Base64();//base64加密 var strWindowFeatures = "width=1400,height=800,menubar=yes,location=yes,resizable=yes,scrollbars=true,status=true,left=200,top=100"; window.open(domain + "?clz=com.bsoft.emss.greenChannel.MonitorDemo&vehicleCd=" + self.vehicleCd + "&msg=" + self.vehicleId, 'ambuanceLayer', strWindowFeatures); // }, 1000) //删除dialog右上角关闭按钮 // $(".monitor-dialog-close").find('.el-dialog__header').find(".el-dialog__headerbtn").children('i').remove() } , loadWorkState() { loadWorkState().then(res => { this.workStateOptions = [] if (null != res.body.items && undefined != res.body.items) { for (let item of res.body.items) { if (item.key == '1' || item.key == '2' || item.key == '4' || item.key == '3') { this.workStateOptions.push(item) } } } }) } , cancelRadio(ty) { ty === this.vehicleForm.devices ? this.vehicleForm.devices = '' : this.vehicleForm.devices = ty } , /*websocket任务车辆状态改变,刷新车辆列表信息*/ getTaskChangeInfo(data) { if (data.vehicleId == this.eventDetails.vehicle_id) { // this.tempTaskTime = '' // this.tempStateText = '' // this.tempTaskState = '' this.tempTaskState = data.taskState this.tempTaskTime = data.updateTime let stateText = this.getStateText(data) this.tempStateText = stateText this.getVehicleLastPos(data, stateText) } this.findVehiclLayerList() } , //获取车辆最新位置 getVehicleLastPos(info, stateText) { $ajax({ url: 'api/emss.gis/queryTrackPositionByVehicleId', jsonData: [info.vehicleId], }).then(res => { let data = res.body.data if (data) { if (data.longitude && data.latitude) { let item = { stateTime: info.updateTime, stateText: stateText, latitude: data.latitude, longitude: data.longitude, taskState: data.taskState } //将当前更改任务状态更新到地图上 this.gernateText(item) } } }) }, //查询当前车辆和任务所有状态 getTaskStates(info) { this.taskStates = [] $ajax({ url: 'api/emss.taskService/queryTaskStatesByTaskIdAndVehicleId', jsonData: [info.taskId, info.vehicleId], async: true }).then(res => { //循环当前所有轨迹点 ,判断某个状态时间在哪两个个轨迹中间 if (res.body.data.length > 0) { for (let item of res.body.data) { //状态 //有值则取值数据 if (item?.latitude && item?.longitude) { if (this.taskStates.indexOf(item.stateText) < 0) { this.gernateText(item) this.taskStates.push(item) } continue } else if (undefined != item.stateTime) { for (let i = 0; i < this.preFiltersTracks.length; i++) { let stateTime = new Date(item.stateTime) let trackTime = new Date(this.preFiltersTracks[i].insertTime) if (trackTime >= stateTime) { if (i == 0) { //小于第一条轨迹 则取第一个点 item.latitude = this.preFiltersTracks[i].latitude item.longitude = this.preFiltersTracks[i].longitude } else { item.latitude = this.preFiltersTracks[i - 1].latitude item.longitude = this.preFiltersTracks[i - 1].longitude } if (this.taskStates.indexOf(item.stateText) < 0) { this.gernateText(item) this.taskStates.push(item) } break } } } } } else { console.log("状态集合为空") } console.log(this.taskStates); }) }, //dukang //生成标记 gernateText(item) { let time = '..' if (item.stateTime) { time += item.stateTime.substring(5); } let dingweiIcon = new AMap.Icon({ size: new AMap.Size(30, 30), // 图标尺寸 image: this.icon2, // Icon的图像 imageSize: new AMap.Size(30, 30), // 根据所设置的大小拉伸或压缩图片 }); var marker = new AMap.Marker({ //添加自定义点标记 map: this.map, // anchor: 'bottom-center', icon: dingweiIcon, position: [item.longitude, item.latitude], //基点位置 // content: '' //自定义点标记覆盖物内容 }); marker.setLabel({ direction: 'right', offset: new AMap.Pixel(10, 0), //设置文本标注偏移量 content: '
' + item.stateText + '
' + time + '
', //设置文本标注内容 }); }, invokeMethod() { this.getIcon() this.getFrequency() if (!this.refreshFlag) { this.refreshFlag = true this.loadWorkState() this.findVehiclLayerList() } } , /** * 关闭监控视频弹框 * @param pageNo */ closeMonitor() { let self = this this.showMonitorDialog = false self.$refs.monitorDemo.close() } , handleCurrentChange(pageNo) { this.curIndex = -1 this.pageNo = pageNo this.findVehiclLayerList() } , handleSizeChange(pageSize) { this.pageSize = pageSize this.findVehiclLayerList() } , handleCurrentChange2(pageNo) { this.pageNo2 = pageNo this.findAcceptancePiByTaskId() } , handleSizeChange2(pageSize) { this.pageSize2 = pageSize this.findAcceptancePiByTaskId() } , handleCurrentChange3(pageNo) { this.curHisIndex = -1 this.pageNo3 = pageNo this.findVehicleHistoryById() } , handleSizeChange3(pageSize) { this.pageSize3 = pageSize this.findVehicleHistoryById() } , handleCurrentChange4(pageNo) { this.pageNo4 = pageNo this.findAcceptancePiByHisTaskId() } , handleSizeChange4(pageSize) { this.pageSize4 = pageSize this.findAcceptancePiByHisTaskId() } , //获取默认上传时间 getFrequency() { $ajax({ url: 'api/emss.gis/findSysParsmValues', jsonData: [] }).then(res => { if (res.body.data.maxSpeed) { this.maxSpeed = parseInt(res.body.data.maxSpeed) } else { this.maxSpeed = 180 //默认值 km/h } }) }, getStateText(data) { let stateText = '' switch (data.taskState) { case "01": stateText = '任务派遣中' break; case "02": stateText = '收到指令' break; case "03": stateText = '驶向现场' break; case "04": stateText = '到达现场' break; case "05": stateText = '病人上车' break; case "06": stateText = '到达医院' break; case "20": stateText = '暂停' break; case "21": stateText = '站内待命' break; case "22": stateText = '途中待命' break; default: break; } return stateText }, } , created() { let self = this window.lookMonitor = self.lookMonitor /*let base = new Base64();//base64加密 if(window.location.href.indexOf("userId")>-1 && window.location.href.split("userId=")[1]){ self.userId=base.decode(window.location.href.match(/&userId=(\S*)/)[1]) }*/ } , watch: { mainHeight: function (value) { this.tableHeight = value - 60 - 60 - 37; } , } , mounted() { let self = this window.onresize = () => { return (() => { let height = document.body.clientHeight; this.mainHeight = height; })() }; } , })

})

你可能感兴趣的:(算法)