Vue项目之使用百度地图、高德地图、谷歌地图


在开发带有地图的项目中我使用到了百度地图、高德地图、还有谷歌地图、说起来真令人心酸.

最近开发项目因为需要使用到地图展示每个设备的具体位置,但是每个设备的点非常的密集,然后使用到了地图的点聚合,将地图上密集的点聚合成一个圆,并且移动到点上可以查看这个设备点的一些信息,点击点可以进入设备的详细信息中.

  • 一开始我使用的是项目之前使用的百度地图,以前的老项目是使用jq写的,后面我使用vue重构,使用到了vue百度地图插件,一开始还好好的,但是发布到生产环境的时候却出现了问题,大概设备的点达到了3000左右的时候,网页会出现非常明显的卡顿与未响应.

后来我前往github上查找原因,原来出现这个问题的不止我一个人,有人推荐海量点,但是海量点并不符合我的业务要求,查看百度地图文档,发现官方的点聚合例子在点超过千位也会出现卡死的状态,遂放弃百度地图.

正好高德地图也有点聚合的例子,高德地图也封装了vue的地图插件,这次我小心了起来,先去文档中查看例子,发现大概超过3000点也会出现卡死的状态.

然后去高度地图官方文档查看,几万点加载完全无压力,然后我开始使用了高德地图.

好了,我分享我的使用方法:

  1. 首先在我们的index.html中引入高德地图cdn js文件
    <script type="text/javascript" src="https://webapi.amap.com/maps?v=1.4.14&key=你申请的key"></script>
  • 将高德地图写成一个组件,创建一个.vue文件
    <div class="map" id="container"></div>
    //记得给map高度哦
    .map {
        width: 100%;
        margin: 0.2rem auto 0 auto;
        display: inline-block;
        height: 88vh;
    }
    //创建点
    mapObj=new AMap.Map('container', {//'map-location'是对应页面盒子的id
    resizeEnable: true,
    center: [105, 34],
    zoom: 4,
    zooms:[3,20],
    expandZoomRange:true,
    //添加下面这行代码能缩小到10米哦
    viewMode:'3D'
    })
    //创建信息窗体实例
    infoWindow = new AMap.InfoWindow({offset: new AMap.Pixel(0, -10)});
    //获取到所有的点
    getDeviceAddressList(this.offset,this.limit)
    .then((res)=>{
        res.data.data.list.forEach(element => {
            marker=new AMap.Marker({
            position: [element.deviceLongitude,element.deviceLatitude],//每个点的经纬度
            //自定义点的图标
            content: '<img src="https://webapi.amap.com/theme/v1.3/markers/n/mark_bs.png" class="markericon"  />',
            offset: new AMap.Pixel(-15, -15),
            //你如果需要在点里面添加其他信息
            deviceId:element.deviceId,
            deviceSn:element.deviceSn,
            deviceName:element.deviceName,
            deviceAddress:element.deviceAddress
        })
    //信息窗口需要显示的内容
        marker.content=`<p style="margin: 10px 0px 0px 0px;">${this.$t('lang.dashboard.Serials')}:${element.deviceSn}</p>
          <p>${this.$t('lang.dashboard.name')}:${element.deviceName}</p>
        <p>${this.$t('lang.dashboard.ADDRESS')}:${element.deviceAddress}</p>`
        //动态添加移入移出事件
        marker.on('mouseover', this.markeronmouseover)
        marker.on('mouseout',this.markeronmouseout)
        marker.on('click',this.routerpush)
        //添加到海量点聚合
        markers.push(marker)
        });
    //最后实例化点聚合
        mapObj.plugin(["AMap.MarkerClusterer"],()=> {
        cluster = new AMap.MarkerClusterer(
        mapObj,     // 地图实例
        markers,    // 海量点组成的数组
        )
        })
因为地图函数作用域的原因我们在在export default外定义这些变量
let mapObj=null
      let marker=null
      let markers=[]
      let cluster=null
      let infoWindow=null

高德地图就这样完成了,你认为这就结束了?哈哈,如果是国外的用户使用我们的项目呢?高德地图能显示国外吗?答案是不能,国外黑乎乎的一片.

然后我使用了谷歌地图,你问我为什么不直接使用谷歌地图?虽然谷歌地图有国内的源,但是在国内谷歌地图不如高德地图,显示的详细位置没有谷歌地图准确,当然我们的用户也大多是国内的.

还是一样的,在index.html中引入谷歌地图(需要科学上网才能显示出来哦,并且谷歌地图并不是免费的哦,每月有200美元的免费使用,设置好上限即可)

  1. 还是先引入js文件.
    <script src="https://maps.googleapis.com/maps/api/js?&key=你申请的key"></script>
    //谷歌地图点聚合插件
    <script src="https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/markerclusterer.js"></script>

    2.创建.vue文件

<div id="map"></div>
//记得加上宽度和高度
#map{
  width: 100%;
  margin: 0.2rem auto 0 auto;
  display: inline-block;
  height: 88vh;
}
  1. 还是在export default外定义好我们的变量.
    let map=null
      let markers=[]
      let marker=null
      let labels='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
      let markerCluster=null
      let contentString=''
      let infowindow=null
    //创建地图函数
    initMap() {
      //清空所有数据
      map=null
      markers=[]
      marker=null
      labels='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
      markerCluster=null
      contentString=''
      infowindow=null
      //创建地图
      var uluru = {lat: 1.3238320056192325, lng: 103.84289822703454};
      var map = new google.maps.Map(document.getElementById('map'), {
      zoom: 12,
      center: uluru,
      scaleControl: true,
      mapTypeId: google.maps.MapTypeId.ROADMAP
      });
      //信息窗体
      infowindow = new google.maps.InfoWindow({
      content: ''
      });
      //获取后端设备经纬度等信息
      getDeviceAddressList(this.offset,this.limit)
      .then((res)=>{
      res.data.data.list.forEach((element,index)=>{
        //创建点
          marker = new google.maps.Marker({
          position: {lat: Number(element.deviceLatitude) , lng: Number(element.deviceLongitude)},
          map: map,
          //添加点的信息
          con:`<p style="margin: 10px 0px 0px 0px;">${this.$t('lang.dashboard.Serials')}:${element.deviceSn}</p>
          <p>${this.$t('lang.dashboard.name')}:${element.deviceName}</p>
        <p>${this.$t('lang.dashboard.ADDRESS')}:${element.deviceAddress}</p>`
      })
      //鼠标移入事件
      marker.addListener('mouseover', ()=> {
      //如果语言被切换,重新给点的内容赋值
      markers[index].con=`<p style="margin: 10px 0px 0px 0px;">${this.$t('lang.dashboard.Serials')}:${element.deviceSn}</p>
          <p>${this.$t('lang.dashboard.name')}:${element.deviceName}</p>
        <p>${this.$t('lang.dashboard.ADDRESS')}:${element.deviceAddress}</p>`
      // 将点的信息添加至信息窗体
      infowindow.setContent(markers[index].con)
      //打开点
      infowindow.open(map,markers[index])
      })
      //鼠标移出事件
      marker.addListener('mouseout', ()=> {
        //关闭信息窗体
      infowindow.close()
      })
      //点击事件,点击跳转设备详细信息页面
      marker.addListener('click',()=>{
        this.$router.push({
        name: 'Particulars',
        params: {id: element.deviceId}
        })
      })
      //将点push到聚合数组
      markers.push(marker)
      })
      //创建点聚合
      markerCluster = new MarkerClusterer(map, markers,
             {imagePath: 'https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m'}
       )
      })
      }

    谷歌地图也介绍完了,你看懂了吗?

声明:Web前端小站 - 前端博客|版权所有,违者必究|如未注明,均为原创|本网站采用BY-NC-SA协议进行授权

转载:转载请注明原文链接 - Vue项目之使用百度地图、高德地图、谷歌地图


行路有良友,便是捷径。带上我吧,一起去看更大的世界。