vue使用google地图(二)实现标记实时运动(基于websocket)

最近外卖项目,需要实现一些地图的功能,前几天写了一个关于marker 和 InfoWindow、自定义label的文章,只是简单地例子。详情点击vue中使用google地图(自定义label、信息窗口)

有不懂的欢迎留言,我每天都上博客,一定及时回复大家,如有不足希望批评指正。

那么,今天在这里写一个曾经我可望而不可即的功能,外卖骑手实时在地图上运动。具体需求是点击按钮创建弹窗,并且创建地图与websocket创建长连接。这个功能的原理是什么呢,我在这里把我的思路一一介绍,也算是记录心得。需求如下图:

  • 1、先创建地图实例,并在地图初始化的时候就渲染初始的骑手标记(也就是marker)
  • 2、建立websocket连接,获取数据
  • 3、在服务端给我数据的时候,清除地图上所有的marker,然后再重新添加,这里是最重要的一步,实现实时刷新标记的重要步骤,一定要先清除再进行添加
  • 4、地图标记线,也就是骑手历史路径也要在websocket发送消息的时候进行添加,

以上就是主要的步骤。在写项目的时候,遇到一个异步的坑,因为初始化地图和websocket连接的过程有一些时间差,说白了就是异步了,导致websocket给我发送的消息并不能及时渲染到地图上,我这边是在请求一个接口拿到后端给的数据后再进行地图初始化,一定要在地图初始化之后再进行连接,不同项目有不同需求,我这里只以我的项目思路来介绍。所以我这里有一个处理异步的步骤,使用的是ES6的async await,之后会有代码进行介绍

标记的API地址:https://developers.google.com/maps/documentation/javascript/markers

折线的API地址:https://developers.google.com/maps/documentation/javascript/shapes

我这里并没有使用原生的websocket的API。用的是这个websocket插件sockjs-client

下载
npm insall sockjs-client --save

引入
import SockJS from 'sockjs-client'

data里
websock:null,
sockjs:null,

methods里
//建立连接,listen为websocket的方法
this.sockjs = new SockJS(`这里为服务端websocket的请求地址`)
this.listen(this.sockjs)

// websocket方法
listen (sockjs) {
  sockjs.onopen = () => {
    console.log('启动websocket')
  }
   sockjs.onmessage = (e) => {
    let response = JSON.parse(e.data)
    
    /**
    这里去做你想做的判断,可以打印response去看看数据什么样
    */
  }
  sockjs.onclose = () => {
    console.log('关闭websocket')
  }
},
上面是websocket使用方法,下面是我写功能的逻辑,有基础的肯定能看懂,代码中有详细介绍,应该是比较详细的。

data和html我这里就不展示了,代码太多  都给也比较乱

created(){
this.orderList()
},
updated(){
//当弹窗dialogVisible 关闭的时候,清空websocket数组,我自己的项目逻辑
if(this.dialogVisible == false){
  this.flightPlanCoordinates = []
  this.center = {}
  this.qishouPsoition = []
  this.qishouPathShow = false
}

},
watch:{
//  监听websocket给的坐标点
flightPlanCoordinates(val,oldVal){
  return this.qishouPsoition = val
}
},
methods:{
//这里做了异步处理,先执行请求的接口,执行完之后在建立websocket连接
 async handleClick(id){
  await this.$api.qishou.get_position(data=>{    //我自己项目的接口,可忽略这里重要的是,初始化地图和websocket的先后顺序,初始化地图为先
    this.mapData = data;
    this.mapBuild() //请求成功调用地图
  },{
    orderId:id
  })
   //websocket
   this.sockjs = await new SockJS(`你的websocket请求地址`)
   await this.listen(this.sockjs)
},
//  地图实例
mapBuild(){
  //地图创建成功显示地图
  this.qishouPathShow = true
  //设置地图中心坐标点为请求接口的经纬度
  this.center = { lng:Number(this.mapData.shoplong),lat:Number(this.mapData.shoplat) }
  //创建地图实例
  let map = new google.maps.Map(document.getElementById('map_canvas'), {
    zoom: 17,
    center:this.qishouPsoition.length==0?this.center:this.qishouPsoition[this.qishouPsoition.length-1],
    mapTypeId: google.maps.MapTypeId.ROADMAP
  });
  //给地图实例赋值,存起来
  this.mapObj = map
  //骑手标记
  this.marker = new MarkerWithLabel({
    position: this.qishouPsoition.length==0?this.center:this.qishouPsoition[this.qishouPsoition.length-1],
    icon: this.qishouIcon, //标记图标
    draggable: false, //不可拖动
    map: map,
    //这里是自定义label,不懂得看上一篇google地图的文章,开头有链接
    labelContent: this.mapData.name,
    labelAnchor: new google.maps.Point(22, 0),
    labelClass: "labels", // the CSS class for the label
    labelStyle: { background:'#fff',padding:'5px' }
  });
  //目的地标记显示,是个汉堡(这个是接口定死的值)
  let position_destination = { lng:Number(this.mapData.conlong),lat:Number(this.mapData.conlat) }
  let destination = new MarkerWithLabel({
    position: position_destination,
    icon: this.destinationIcon, //目的地标记图标
    draggable: false, //不可拖动
    map: map,
    labelContent: 'Destination',
    labelAnchor: new google.maps.Point(33, 0),
    labelClass: "labels", // the CSS class for the label
    labelStyle: { background:'#fff',padding:'5px' }
  });
},
// websocket
listen (sockjs) {
  sockjs.onopen = () => {
    console.log('启动websocket')
  }
   sockjs.onmessage = (e) => {
    let response = JSON.parse(e.data)
    //判断给的状态
    switch (response.event){
      case "RESPONSE_POSITION":
        this.lat = response.data.latitude
        this.lng = response.data.longitude
        let position = {lat:this.lat,lng:this.lng}
        //向数组中添加从websocket中请求的数据
        this.flightPlanCoordinates.push(position)
        //websocket每次给值,那么就清空一次地图上原有的marker,清空后在创建一次marker,position为websocket最新的点
        this.marker.setMap(null);
        this.marker = new MarkerWithLabel({
          position: position,
          icon: this.qishouIcon, //骑手标记图标
          draggable: false, //不可拖动
          map: this.mapObj,
          labelContent: this.mapData.name,
          labelAnchor: new google.maps.Point(22, 0),
          labelClass: "labels", // the CSS class for the label
          labelStyle: { background:'#fff',padding:'5px' }
        });
        //创建路线,path是一个数组
        let flightPath = new google.maps.Polyline({
          path:this.qishouPsoition,
          geodesic: true,
          strokeColor: '#FF0000',
          strokeOpacity: 1.0,
          strokeWeight: 2
        });
        flightPath.setMap(this.mapObj);
        break
    }
  }
  sockjs.onclose = () => {
    console.log('关闭websocket')
  }
},

猜你喜欢

转载自blog.csdn.net/xr510002594/article/details/85345096
今日推荐