高德经纬度点位过滤算法

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: "<span style='color:red;font-weight: bold;font-size: 16px' class='idDay'>" + this.eventDetails.cd + "</span>", //设置文本标注内容
            });

            this.trackMark.on('click', () => {
                this.infoWindow.setContent(this.getContent(this.eventDetails).join("<br>"));
                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: "<span style='color:red;font-weight: bold;font-size: 16px' class='idDay'>" + this.carsList[i].cd + "</span>", //设置文本标注内容
                });

                pos_marker[i].on('click', () => {
                    this.infoWindow.setContent(this.getContent(this.carsList[i]).join("<br>"));
                    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('<div><div class="el-row" style="padding-top:10px;width:350px"><div class="el-col el-col-12" style="font-size: 18px; font-weight: bold;">' +
                '  <span>' + cd + '</span></div> <div class="el-col el-col-6">' +
                '<span class="el-tag el-tag--success el-tag--light">' + state_text + '</span></div>' +
                '<div class="el-col el-col-6"><button type="button" onclick=lookMonitor("' + car.cd + '") class="el-button el-button--primary el-button--mini"><span >车内监控</span></button></div>' +
                '</div> <div class="el-row"></div> ' +
                '<div class="el-row"><div class="el-col el-col-24">目的地:' + to_location + '</div></div> ' +
                '<div class="el-row">' +
                '<div class="el-col el-col-8">医生:<span style="line-height: 22px; font-size: 14px; "> ' + doctor + '</span></div>' +
                '<div class="el-col el-col-8">护士:<span style="line-height: 22px; font-size: 14px; "> ' + nurse + '</span></div>' +
                '<div class="el-col el-col-8">司机:<span style="line-height: 22px; font-size: 14px; "> ' + driver + '</span></div>' +
                '</div>');
            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: '<div style="white-space:nowrap; font-size:13px;" title="' + item.stateText + item.stateTime + '">' + item.stateText + '</br> ' + time + '</div>', //设置文本标注内容
            });
        },
        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;
            })()
        };
    }
    ,
})

})

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值