VUE +高德地图实现 vue-高德地图-车辆轨迹 支持滑动快进退 /加速 /减速/暂停.

VUE +高德地图实现 vue-高德地图-车辆轨迹 支持滑动快进退 /加速 /减速/暂停.

项目演示

代码

先看效果

vue-高德地图-车辆轨迹 支持滑动快进退 加速 减速


<template>
     <div class="homeInfo">
        00.0.
        <div id="mapApp2" class="mapApp" style="width:100%;height:100%;">
        </div>
        <div class="homeInfoCar">
            <div >
                <div style="display:flex;align-items: center;">
                    <a-button size="Default" type="warning" @click="startAnimation">重新播放</a-button>
                    <!-- <a-slider v-model="sliderValue" 
                 
                    @change="ChangeAnimation" 
                     @input="inputAnimation"
                     :show-tooltip="true"
                     :format-tooltip="formatTooltip"
                      style="width:400px;margin:20px;"   /> -->
                      <div  style="width:500px;height:15px;margin:0 20px;" >
                        <a-slider v-model:value="sliderValue" :tooltip-visible="true"  @change="ChangeAnimation" @afterChange="afterChangeAnimation" style="width:500px;height:15px;margin:0 20px;"  />
                      </div>
                     
                    <!-- <a-slider v-model:value="sliderValue" @input="ChangeAnimation"  style="width:500px;height:15px;margin:0 20px;" /> -->

                    <div style="display:flex" >
                        <!-- <fast-backward-outlined  @click="linebackspeedMIN" title="暂停行驶" />
                        <fast-forward-outlined  @click="linebackspeedMAX" title="加速行驶" />
                        <play-circle-outlined @click="resumeAnimation"  title="继续行驶" />
                        <stop-outlined  @click="resumeAnimation"  title="暂停行驶" /> -->

                        <!-- <a-tag size="Default" @click="linebackspeedMIN">减速行驶</a-tag>
                        <a-tag size="Default" @click="pauseAnimation">暂停行驶</a-tag>
                        <a-tag size="Default" @click="resumeAnimation">继续行驶</a-tag>
                        <a-tag size="Default" @click="linebackspeedMAX">加速行驶</a-tag> -->
                            <FastBackwardOutlined style="color:#12a3f5;font-size:28px;" title="减速行驶"
                                @click="linebackspeedMIN" />
                            <PauseOutlined style="color:#12a3f5;font-size:28px;" title="暂停行驶" @click="pauseAnimation"  v-if="PauseOutlinedFlag" />
                            <CaretRightOutlined style="color:#12a3f5;font-size:28px;" title="继续行驶"
                                @click="resumeAnimation" v-else />
                            <FastForwardOutlined style="color:#12a3f5;font-size:28px;" title="加速行驶"
                                @click="linebackspeedMAX" />
                               
                        </div>
                    </div>
             
            </div>

            <a-table size="small" :columns="columns" :data-source="tableData[tableDataIndex]"  border style="width: 100%" 
             :rowClassName="setRowClass"  :scroll="{ x: 1500,}"  :pagination="false"
             id="Export">
        </a-table>
        <div class="flex space-between ">
            <div></div>
            <a-pagination v-model:current="tableDataIndex" :total="tableDataTotal" :page-size="5" />
        </div>
      
        </div>
    </div>
   
</template>

<script>
    import {
    
    
        computed,
        defineComponent,
        onMounted, //响应式
        ref,
        watch,
        nextTick
    } from 'vue';
    import {
    
     
        PauseOutlined,
        CaretRightOutlined,
        FastForwardOutlined,
        FastBackwardOutlined,
      
    } from '@ant-design/icons-vue';
    import {
    
    
        useStore
    } from "vuex";
    import {
    
    markerList} from "@/view/map/map.js"
    export default defineComponent({
    
    
        name: 'BusinessManagement',
        components:{
    
    
            PauseOutlined,
        CaretRightOutlined,
        FastForwardOutlined,
        FastBackwardOutlined,
        },
        setup() {
    
    
            const store = useStore()
            const modelRef = ref(null)
            store.dispatch("map/AmapInit").then((amap) => {
    
    
                amap.init("mapApp2", {
    
    
                    // mapStyle: 'amap://styles/darkblue', //设置地图的显示样式
                    rotateEnable: false,
                    pitchEnable: true,
                    resizeEnable: true,
                    zoom: 10,
                    // pitch: 45, //45度俯视
                    viewMode: '3D', //type ? '2D' : '3D', //开启3D视图,默认为关闭
                    zooms: [2, 20],
                    skyColor: "#002d56", //天空颜色 倾斜后才会产生
                    center: [120.294189,30.161941],
                })
            })
            const map=computed(()=>store.state.map.Amap)
            const sliderRef=ref(null)
            const tableData=ref([])
            const tableDataTotal=ref(0)
            const tableDataIndex=ref(1)
            const tableDataSize=ref(5)
            const moveAlongIndex = ref(1)  // 行驶下标
            const sliderValue = ref(0)         // 行驶下标
            const PauseOutlinedFlag  = ref(false)    // 暂停
            const barSearchFlag   = ref(false)    // 行驶下标
            const totalmileage   = ref(0)     // 行驶总公里数
            const linebackspeed = ref(1000) // 行驶速度
            const totalDateTime = ref(0) // 行驶耗时
            const columns=[
                {
    
    
                title: 'name',
                dataIndex: 'name',
                },
                {
    
    
                title: 'style',
                dataIndex: 'style',
                width:120,
                },
                {
    
    
                title: '经纬度',
                dataIndex: 'lnglat',
                width:200,
                },
                {
    
    
                title: '地址',
                dataIndex: 'address',
                },
            ]
            var marker = null // 车辆markser
            var PolylinesArr = [] // 轨迹列表
            var gjlineArr = [] // 储存轨迹线段list
            var gjspotArr = [] // 储存轨迹点list
            var delayedpolylinTime = null // 车辆行驶 计时器

            setTimeout(()=>{
    
    
                SpoUppolyline()
            },500)
            const formatAngle = (dv) => {
    
    
                while (dv < 0) dv += 360;
                while (dv >= 360) dv -= 360;
                if (dv == 0) return "正北";
                else if (dv == 90) return "正东";
                else if (dv == 180) return "正南";
                else if (dv == 270) return "正西";
                var dx = Math.floor(dv / 45);
                switch (dx) {
    
    
                    case 0:
                        return "北偏东" + dv + "°";
                    case 1:
                        return "东偏北" + (90 - dv) + "°";
                    case 2:
                        return "东偏南" + (dv - 90) + "°";
                    case 3:
                        return "南偏东" + (180 - dv) + "°";
                    case 4:
                        return "南偏西" + (dv - 180) + "°";
                    case 5:
                        return "西偏南" + (270 - dv) + "°";
                    case 6:
                        return "西偏北" + (dv - 270) + "°";
                    case 7:
                        return "北偏西" + (360 - dv) + "°";
                    default:
                        return dv;
                }
            }

            const handleTableChange = (info) => {
    
    
                current.value = info
            }
            const SetUpbarPromoteFlag = () => {
    
    
                barPromoteFlag.value = true
            }
            // 计算公里数
            const  getDistanceTwoPointn =(point1, point2)=> {
    
    
                
                return Math.sqrt(Math.pow(point2.mx - point1.mx, 2) + Math.pow(point2.my - point1.my, 2))
            }
            const  arraySlice=(array, sliceNum)=> {
    
    
                let newArray=[]
                let viod = 0;//数组初始量
                for (let i = 0; i <= array.length; i++) {
    
    
                if (i % sliceNum == 0 && i != 0) {
    
    
                    newArray.push(array.slice(viod, i));
                    viod = i;
                }
                if (i + 1 == array.length) {
    
    
                    newArray.push(array.slice(viod, i + 1));
                }
                }
                return newArray;
            }
      
            const SpoUppolyline = async() => {
    
    
                    closePolyline(false)
                    sliderValue.value = 0
                    if (marker) {
    
    
                        map.value.amap.remove(marker)
                        marker = null
                    }
                        PauseOutlinedFlag.value = true
                        
                        let info = markerList
                        console.log(info)
                        barSearchFlag.value = true
                        tableDataTotal.value=info.length
                          tableData.value = [
                            [], ...arraySlice(info, 5)
                        ]
                        PolylinesArr = info.map((x) => {
    
    
                            return {
    
    
                                value: x.lnglat,
                                color: x.color,
                                address:x.address
                            }
                        })

                        map.value.amap.setZoomAndCenter(14, PolylinesArr[0].value)
                 
                        SetUppolyline()
                    
                

            }


           





            const stringToTimeStamp = (date) => {
    
    
                date = date.substring(0, 19);
                date = date.replace(/-/g, '/');
                return new Date(date).getTime() / 1000;
            }

            

            //  开始车辆轨迹
            const SetUppolyline = () => {
    
    
                if (marker) {
    
    
                    map.value.amap.remove(marker)
                }
                marker = new AMap.Marker({
    
    
                    position: PolylinesArr[0].value,
                    icon: "https://webapi.amap.com/images/car.png",
                    offset: new AMap.Pixel(-13, -13),
                    autoRotation: true,
                    angle: -90,
                    zIndex: 200
                });
                map.value.amap.setZoomAndCenter(16, PolylinesArr[0].value)
         
                marker.on("moving", e => {
    
    
                    let movingLine = new AMap.Polyline({
    
    
                        map: map.value.amap,
                        strokeWeight: 5,
                        lineJoin: "round",
                        strokeColor: PolylinesArr[moveAlongIndex.value].color,
                        // strokeColor: "#f60",
                        zIndex: 110,
                        path:e.passedPath
                    })
                    gjspotArr.push({
    
    
                        keys: moveAlongIndex.value,
                        value: movingLine,
                    })
                })
                marker.on("moveend", e => {
    
    
                    moveAlongIndex.value++
                    delayedpolylin()
                 
                    
                })
                map.value.amap.add(marker)
                moveAlongIndex.value = 1
                delayedpolylin()
            }

          
            // 车辆行驶
            const delayedpolylin = () => {
    
    
              
                if (delayedpolylinTime) {
    
    
                    clearTimeout(delayedpolylinTime)
                }
                if(moveAlongIndex.value == PolylinesArr.length-1 )return
                if (!PauseOutlinedFlag.value) return;
                
                
                // return
                // if (JSON.stringify(PolylinesArr[moveAlongIndex.value - 1].value+"") == JSON.stringify(PolylinesArr[moveAlongIndex.value].value+"")) {
    
    
                if (PolylinesArr[moveAlongIndex.value - 1].value[0] == PolylinesArr[moveAlongIndex.value].value[0]) {
    
    
                    
                    delayedpolylinTime = setTimeout(() => {
    
    
                        let movingLine = new AMap.Polyline({
    
    
                            map: map.value.amap,
                            strokeWeight: 5,
                            lineJoin: "round",
                            strokeColor: PolylinesArr[moveAlongIndex.value].color,
                            zIndex: 110
                        })
                      
                        movingLine.setPath([PolylinesArr[moveAlongIndex.value - 1].value,
                            PolylinesArr[moveAlongIndex.value].value
                        ])
                        gjspotArr.push({
    
    
                            keys: moveAlongIndex.value,
                            value: movingLine,
                        })
                       
                        let tempPoint = new AMap.Marker({
    
    
                            map: map.value.amap,
                            position: PolylinesArr[moveAlongIndex.value].value,
                            offset: new AMap.Pixel(-5, -5),
                            icon: new AMap.Icon({
    
    
                                image: 'https://a.amap.com/jsapi_demos/static/images/mass2.png', // Icon的图像
                                size: new AMap.Size(10, 10),
                                imageSize: new AMap.Size(10, 10),
                            }),
                            zIndex: 113
                        })
                        gjlineArr.push({
    
    
                            keys: moveAlongIndex.value,
                            value: tempPoint,
                        })
                        moveAlongIndex.value++
                     
                        delayedpolylin()
                    }, 300)
                } else {
    
    
                    startmoveAlong(1)
                }
            }

            // 车辆行驶 添加轨迹和 轨迹点
            const startmoveAlong = () => {
    
    
                
                if (!PauseOutlinedFlag.value) return;
                let tempPoint = new AMap.Marker({
    
    
                    map: map.value.amap,
                    position: PolylinesArr[moveAlongIndex.value-1].value,
                    offset: new AMap.Pixel(-4, -4),
                    icon: new AMap.Icon({
    
    
                        image: 'https://a.amap.com/jsapi_demos/static/images/mass2.png', // Icon的图像
                        size: new AMap.Size(8, 8),
                        imageSize: new AMap.Size(8, 8),
                    }),
                    zIndex: 113
                })
                tempPoint.setTitle(PolylinesArr[moveAlongIndex.value].address)
               
                gjlineArr.push({
    
    
                    keys: moveAlongIndex.value,
                    value: tempPoint,
                })
                
                marker.moveTo(PolylinesArr[moveAlongIndex.value].value, linebackspeed.value, function (k) {
    
    
                    return k
                });
                
            }

            // 关闭车辆轨迹
            const closePolyline = (type) => {
    
    
                if (type) {
    
    
                    PauseOutlinedFlag.value = false
                    let car = map.value.getMarker('car')
                    map.value.amap.add(car.map((x) => {
    
    
                        return x.value
                    }))
            
                    emitter.emit("CheckcomponentName", 'monitor')
                }

                if (marker) {
    
    
                    map.value.amap.remove(marker)
                    marker = null
                }
                if (PolylinesArr) {
    
    
                    marker = []
                }

                if (gjlineArr.length) {
    
    
                    map.value.amap.remove(gjlineArr.map((x) => x.value))
                    gjlineArr = []
                }
                if (gjspotArr.length) {
    
    
                    map.value.amap.remove(gjspotArr.map((x) => x.value))
                    gjspotArr = []
                }

                moveAlongIndex.value = 1
                sliderValue.value = 0

            }

            var inputAnimationNumber=0
           
            const inputAnimation = (e) => {
    
    
                inputAnimationNumber=e
                pauseAnimation()
            }
            const formatTooltip = (e) => {
    
    
                if(PolylinesArr.length){
    
    
                    return PolylinesArr[moveAlongIndex.value-1].address+" (路程行驶 "+sliderValue.value+"%)"
                }else{
    
    
                    return "准备出发"
                }
               
            }

            const ChangeAnimation = (e) => {
    
    
                pauseAnimation()
            }
            
            const afterChangeAnimation = (e) => {
    
    
                 let Amap = map.value.amap
                let num=parseInt(PolylinesArr.length * (e/100))
                if(moveAlongIndex.value == num){
    
    
                }else if(moveAlongIndex.value > num){
    
    
                    let line= gjlineArr.filter((x)=>{
    
    return x.keys > num}).map(x=>x.value)
                    let spot= gjspotArr.filter((x)=>{
    
    return x.keys > num}).map(x=>x.value)
                    gjlineArr=gjlineArr.filter((x)=>{
    
    return x.keys > num})
                    gjspotArr=gjspotArr.filter((x)=>{
    
    return x.keys > num})
                    Amap.remove(line)
                    Amap.remove(spot)
                }else{
    
    
                    for(let i=moveAlongIndex.value;i<num;i++){
    
    
                        let movingLine = new AMap.Polyline({
    
    
                        path:[PolylinesArr[i-1].value,PolylinesArr[i].value],
                        map: Amap,
                        strokeWeight: 5,
                        lineJoin: "round",
                        strokeColor:  PolylinesArr[i].color,
                        zIndex: 110
                    })
                    // movingLine.setPath([PolylinesArr[i-1].value,PolylinesArr[i]].value)
                    gjspotArr.push({
    
    
                        keys: i,
                        value: movingLine,
                    })
                     let tempPoint = new AMap.Marker({
    
    
                        map: Amap,
                        position: PolylinesArr[i].value,
                        offset: new AMap.Pixel(-4, -4),
                        icon: new AMap.Icon({
    
    
                            image: 'https://a.amap.com/jsapi_demos/static/images/mass2.png', // Icon的图像
                            size: new AMap.Size(8, 8),
                            imageSize: new AMap.Size(8, 8),
                        }),
                        zIndex: 113
                    })
                    gjlineArr.push({
    
    
                        keys: i,
                        value: tempPoint,
                    })
                    }

                }
                moveAlongIndex.value=num+1
                marker.setPosition(PolylinesArr[num].value )
                   PauseOutlinedFlag.value = true
                  delayedpolylin()
            }
            // 重新播放
            const startAnimation = () => {
    
    
                if (PolylinesArr.length) {
    
    
                    marker.pauseMove();
                    PauseOutlinedFlag.value = false
                    closePolyline(false)
                    if (delayedpolylinTime) {
    
    
                        clearTimeout(delayedpolylinTime)
                    }
                    setTimeout(() => {
    
    
                        PauseOutlinedFlag.value = true
                        SetUppolyline(1)
                    }, 400)

                } else {
    
    
                    message.error("暂无行驶轨迹!")
                }
            }
            // 暂停
            const pauseAnimation = () => {
    
    
                marker.pauseMove();
                PauseOutlinedFlag.value = false
            }
            // 继续播放
            const resumeAnimation = () => {
    
    
                if (delayedpolylinTime) {
    
    
                    clearTimeout(delayedpolylinTime)
                }
                setTimeout(() => {
    
    
                    PauseOutlinedFlag.value = true
                    delayedpolylin()
                }, 400)
            }
            // 加速
            const linebackspeedMAX = () => {
    
    
                if (linebackspeed.value >= 10000) return
                linebackspeed.value += 500
            }
            // 减速
            const linebackspeedMIN = () => {
    
    
                if (linebackspeed.value <= 1000) return
                linebackspeed.value -= 500
            }
            // 监听表格动画 设置分页
            watch(moveAlongIndex, (e) => {
    
    
                tableDataIndex.value= ((e+1) / 5 <= 1) ? 1 : Math.ceil((e+1) / 5)
                if(e==  PolylinesArr.length -1 )return  sliderValue.value  =100
               let number= (e / (PolylinesArr.length+1) * 100)
                sliderValue.value = parseInt(number)
            })
            // 监听表格动画 表格样式

            const setRowClass = (record, index) => {
    
    
                if ((tableDataIndex.value-1) * 5 + index == moveAlongIndex.value) {
    
    
                    return "tableActive"
                } else {
    
    
                    return ""
                }
            }
            const currentChange = (e) => {
    
    
                tableDataIndex.value=e
                
            }





            return {
    
    
                // 参数
                tableData,
                columns,
                tableDataTotal,
                tableDataIndex,
                tableDataSize,
                sliderRef,
                sliderValue,
                totalmileage,
                PauseOutlinedFlag,
                ChangeAnimation,
                inputAnimation,
                afterChangeAnimation,
                formatTooltip,
                currentChange,









                // 方法
                handleTableChange,
                SpoUppolyline,
                SetUpbarPromoteFlag,
                startAnimation,
                pauseAnimation,
                resumeAnimation,
                linebackspeedMAX,
                linebackspeedMIN,
              
                closePolyline,
                setRowClass,
              
              
            }
        }
    });
</script>
<style lang="less">
    .homeInfo {
    
    
        position: relative;
        width: 100%;
        height: 100%;
        box-sizing: border-box;
        overflow: hidden;
        background: #00000C;

        .mapApp {
    
    
            position: absolute;
            top: 0;
            right: 0;
            bottom: 0;
            left: 0;
            width: 100%;
            height: 100%;
        }
        .homeInfoCar{
    
    
            position: absolute;
            bottom:0;
            left:10px;
            right:10px;
            height:350px;
            background:#FFF;
            padding: 20px;
            box-sizing: border-box;
        }
        .tableActive{
    
    
            color:aqua;
        }
    }


    // 高度地图
</style>

猜你喜欢

转载自blog.csdn.net/qq_44795810/article/details/128657874