zoukankan      html  css  js  c++  java
  • Vue项目引用百度地图并实现搜索定位等功能 Marco

    Tip:本篇文章为案例分析,技术点较多,所以篇幅较长,认真阅览的你一定会学到很多知识。

    前言百度地图开放平台 给开发者们提供了丰富的地图功能与服务,使我们的项目中可以轻松地实现地图定位、地址搜索、路线导航等功能。本文给大家介绍如何在vue项目中引用百度地图,并设计实现简单的地图定位、地址搜索功能。

    一、效果图及功能点

    先来看一下效果图
    效果图
    效果图看不够? 点此 试试在线操作!(初次进入加载较慢,请耐心等待)

    功能点:

    1. 挂载百度地图
    2. 封装逆地址解析函数(根据坐标点获取详细地址)
    3. 设置图像标注并绑定拖拽标注结束后事件
    4. 添加(右上角)平移缩放控件
    5. 添加(左下角)定位控件
    6. 浏览器定位(定位当前地点)
    7. 绑定点击地图任意点事件
    8. 结合element-ui实现输入提示选取地址并定位功能

    二、前期准备

    在正式开发之前,我们先做好以下准备:

    • 在你的vue项目中引入element-ui (引入方法 戳这
      说明:本案例是结合element-ui进行开发,主要是为方便实现上面第8点功能,大家若是引入其他UI框架也可以,功能实现方法参照本案例自行修改即可。
    • 申请百度地图AK
      前往 百度地图开放平台控制台 ,登录百度账号,创建应用即得。申请百度地图AK

    三、引入百度地图

    下面介绍如何在vue项目中引入百度地图
    方法一
    第1步:在 index.html 中引入下面代码,注意将你的AK代入

    <script type="text/javascript" src="http://api.map.baidu.com/api?v=3.0&ak=您的密钥"></script>
    

    第2步:在 webpack.base.conf.js 添加externals.BMap配置,与entry平级,内容如下,

    entry: {
      app: ['babel-polyfill', './src/main.js']
    },
    externals: {
      BMap: 'BMap'
    }
    

    第3步:在组件中引入BMap

    import BMap from 'BMap'
    

    方法二
    我们知道,vue-cli 3.0+ 的版本已经取消了webpack.conf这些文件了,所以上面的方法就不适用了。而且,方法一在index.html中全局引入百度api,有点耗性能。更多时候我们只希望在单个组件里按需引入即可,所以下面介绍的是以封装的方法引入。
    第1步:在你的项目js资源文件夹下新建loadBMap.js文件,内容如下:

    /**
     * 动态加载百度地图api函数
     * @param {String} ak  百度地图AK,必传
     */
    export default function loadBMap(ak) {
      return new Promise(function(resolve, reject) {
        if (typeof window.BMap !== 'undefined') {
          resolve(window.BMap)
          return true
        }
        window.onBMapCallback = function() {
          resolve(window.BMap)
        }
        let script = document.createElement('script')
        script.type = 'text/javascript'
        script.src =
          'http://api.map.baidu.com/api?v=3.0&ak=' + ak + '&callback=onBMapCallback'
        script.onerror = reject
        document.head.appendChild(script)
      })
    }
    

    第2步:在组件中引入loadBMap函数

    import loadBMap from '@/<js资源文件夹>/loadBMap.js'
    

    第3步:在mounted中调用 loadBMap()

    //这里运用async/await 进行异步处理,保证BMap加载进来后才执行后面的操作
    async mounted() {
      await loadBMap('您的密钥') //加载引入BMap
      ...
    }
    

    这样就在当前组件中引入百度地图 BMap 了,可以开始开发了。

    四、功能解析

    下面开始对上述所列 8 点功能进行详细的代码解析。
    说明:本文用的是方法一引入百度地图,源码 用的是方法二
    1、挂载百度地图
    首先需要给地图分配一个容器,并设置宽高

    <div id="map-container" style="100%;height:500px;"></div>
    

    根据需求,定义data参数

    data() {
      return {
        form: {
          address: '', //详细地址
          addrPoint: { //详细地址经纬度
            lng: 0,
            lat: 0
          }
        },
        map: '', //地图实例
        mk: '' //Marker实例
      }
    }
    

    初始化地图

    methods: {
      initMap() {
        var that = this;
        this.map = new BMap.Map("map-container", {enableMapClick:false})  //新建地图实例,enableMapClick:false :禁用地图默认点击弹框
        var point = new BMap.Point(113.30765,23.12005);
        this.map.centerAndZoom(point,19)
      }
    },
    mounted() {
      this.initMap()
    }
    

    到此,就可以在你的页面上看到地图啦!
    2、封装逆地址解析函数
    参考百度地图 逆地址解析 示例demo,封装一个逆地址解析函数,供下面的功能调用。

    /**
     * 逆地址解析函数(根据坐标点获取详细地址)
     * @param {Object} point   百度地图坐标点,必传
     */
    getAddrByPoint(point){
      var that = this;
      var geco = new BMap.Geocoder();
      geco.getLocation(point, function(res){
      	console.log(res)  //内容见下图
        that.mk.setPosition(point) //重新设置标注的地理坐标
        that.map.panTo(point)  //将地图的中心点更改为给定的点
        that.form.address = res.address;  //记录该点的详细地址信息
        that.form.addrPoint = point;  //记录当前坐标点
      })
    }
    

    逆地址解析获取的信息
    3、设置图像标注并绑定拖拽标注结束后事件
    图像标注Marker是百度地图覆盖物类中的其中一种,它用来标识当前坐标点的位置,也就是我们在地图上所看到的小红点(当然这个点也可以自定义图标样式,这里我们不说,有兴趣的可以参考百度地图覆盖物示例 - 设置点的新图标)。
    设置图像标注很简单,只需要下面两行代码

    initMap() {
      ...
      this.mk = new BMap.Marker(point,{enableDragging:true}) //创建一个图像标注实例,enableDragging:是否启用拖拽,默认为false
      this.map.addOverlay(this.mk) //将覆盖物添加到地图中
    }
    

    这样你就可以在地图上看到小红点啦,接下来我们给这个点绑定拖拽事件。
    拖拽事件有三类,dragstart(开始拖拽时触发)、dragging(拖拽过程中触发)和dragend(拖拽结束时触发),实际项目中我们更注重的是拖拽标注结束后的位置信息,因此我们在这给标注绑定拖拽结束后事件:

    initMap() {
      ...
      this.mk.addEventListener('dragend', function(e){
        that.getAddrByPoint(e.point) //拖拽结束后调用逆地址解析函数,e.point为拖拽后的地理坐标
      })
    }
    

    注意:这里我们将代码写在上面定义的 initMap 函数中,地图初始化时一同执行即可
    4、添加(右上角)平移缩放控件
    百度地图提供了很多的 控件类,方便我们查看和操作地图。本案例只解析平移缩放控件NavigationControl 和 地图定位控件GeolocationControl,其他控件可 参考示例 自行学习。
    下面我们先引入平移缩放控件并将其位置置于右上角:

    initMap() {
      ...
      var navigationControl = new BMap.NavigationControl({ //创建一个特定样式的地图平移缩放控件
        anchor: BMAP_ANCHOR_TOP_RIGHT, //靠右上角位置
        type: BMAP_NAVIGATION_CONTROL_SMALL //SMALL控件类型
      })
      this.map.addControl(navigationControl ) //将控件添加到地图
    }
    

    附:
    anchor参数解析
    BMAP_ANCHOR_TOP_LEFT | 控件将定位到地图的左上角
    BMAP_ANCHOR_TOP_RIGHT | 控件将定位到地图的右上角
    BMAP_ANCHOR_BOTTOM_LEFT | 控件将定位到地图的左下角
    BMAP_ANCHOR_BOTTOM_RIGHT | 控件将定位到地图的右下角
    type参数解析
    BMAP_NAVIGATION_CONTROL_LARGE | 标准的平移缩放控件(包括平移、缩放按钮和滑块)
    BMAP_NAVIGATION_CONTROL_SMALL | 仅包含平移和缩放按钮
    BMAP_NAVIGATION_CONTROL_PAN | 仅包含平移按钮
    BMAP_NAVIGATION_CONTROL_ZOOM | 仅包含缩放按钮
    5、添加(左下角)定位控件
    下面我们引入地图定位控件并将其位置置于左下角:

    initMap() {
      ...
      var geolocationControl = new BMap.GeolocationControl({anchor: BMAP_ANCHOR_BOTTOM_LEFT}) //创建一个地图定位控件
      geolocationControl.addEventListener("locationSuccess", function(e){ //绑定定位成功后事件
        that.getAddrByPoint(e.point) //定位成功后调用逆地址解析函数
      });
      geolocationControl.addEventListener("locationError",function(e){ //绑定定位失败后事件
        alert(e.message);
      });
      this.map.addControl(geolocationControl) //将控件添加到地图
    }
    

    6、浏览器定位
    参考百度地图 浏览器定位 示例demo,进入页面,我们将坐标定位到当前所在地坐标。

    /**
     * 浏览器定位函数
     */
    geolocation() {
      var that = this;
      var geolocation = new BMap.Geolocation();
      geolocation.getCurrentPosition(function(res){
        if(this.getStatus() == BMAP_STATUS_SUCCESS){
          that.getAddrByPoint(res.point) //当成功时,调用逆地址解析函数
        } else {
          alert('failed'+this.getStatus()); //失败时,弹出失败状态码
        }        
      },{enableHighAccuracy: true}) //enableHighAccuracy:是否要求浏览器获取最佳效果,默认为false
    }
    

    同样在initMap中调用即可

    initMap() {
      ...
      this.geolocation()
    }
    

    7、绑定点击地图任意点事件
    在地图上选取地址。点击地图上任意点,都将获取该点的地址信息。

    initMap() {
      ...
      this.map.addEventListener('click', function(e){ //给地图绑定点击事件
        that.getAddrByPoint(e.point) //点击后调用逆地址解析函数
      })
    }
    

    8、结合element-ui实现输入提示选取地址并定位功能
    最后是本案例的主要功能,输入框输入关键字搜索地址,调用百度地图LocalSearch服务进行检索。
    首先,我们需要写入一个输入框。这里利用的是element-ui的 <el-autocomplete>组件,该组件提供了fetch-suggestions属性和select事件【参考文档】,方便我们把检索结果遍历显示出来并进行选择操作。

    <el-autocomplete
      style="100%;"
      popper-class="autoAddressClass"
      v-model="form.address"
      :fetch-suggestions="querySearchAsync"
      :trigger-on-focus="false"
      placeholder="详细地址"
      @select="handleSelect"
      clearable>
      <template slot-scope="{ item }">
        <i class="el-icon-search fl mgr10"></i>
        <div style="overflow:hidden;">
          <div class="title">{{ item.title }}</div>
          <span class="address ellipsis">{{ item.address }}</span>
        </div>
      </template>
    </el-autocomplete>
    

    接下来需提供两个方法:

    querySearchAsync(str,cb){
      var options = {
        onSearchComplete: function(res){ //检索完成后的回调函数
          var s = [];
          if (local.getStatus() == BMAP_STATUS_SUCCESS){
            for (var i = 0; i < res.getCurrentNumPois(); i ++){
              s.push(res.getPoi(i));
            }
            cb(s) //获取到数据时,通过回调函数cb返回到<el-autocomplete>组件中进行显示
          } else{
            cb(s)
          }
        }
      }
      var local = new BMap.LocalSearch(this.map, options) //创建LocalSearch构造函数
      local.search(str) //调用search方法,根据检索词str发起检索
    }
    
    • handleSelect:点击选中建议项时触发的方法
    handleSelect(item) {
      this.form.address = item.address + item.title; //记录详细地址,含建筑物名
      this.form.addrPoint = item.point; //记录当前选中地址坐标
      this.map.clearOverlays() //清除地图上所有覆盖物
      this.mk = new BMap.Marker(item.point) //根据所选坐标重新创建Marker
      this.map.addOverlay(this.mk) //将覆盖物重新添加到地图中
      this.map.panTo(item.point) //将地图的中心点更改为选定坐标点
    }
    

    最后再稍微处理一下autocomplete组件的下拉款样式

    .autoAddressClass{
      li {
        i.el-icon-search {margin-top:11px;}
        .mgr10 {margin-right: 10px;}
        .title {
          text-overflow: ellipsis;
          overflow: hidden;
        }
        .address {
          line-height: 1;
          font-size: 12px;
          color: #b4b4b4;
          margin-bottom: 5px;
        }
      }
    }
    

    至此,我们就完成了上面所有的功能点。

    附:
    项目源码git地址:vue-admin-web
    项目线上地址:vue-admin-web/BMap

    希望本篇案列可以帮助大家了解百度地图的使用。
    觉得这篇文章有用的话就点个赞吧~~么么哒(づ ̄ 3 ̄)づ

  • 相关阅读:
    Update语句到底是如何操作记录的?
    sp_helptext输出错行问题解决
    SSMS查询快捷方式设置
    快速定义临时表或表变量
    T-SQL逻辑查询
    基于交换的排序算法
    插入排序及其扩展
    Python之django基础第一天,认识django
    flask虚拟环境的安装和注意事项
    Linux基础
  • 原文地址:https://www.cnblogs.com/Marco-hui/p/12155995.html
Copyright © 2011-2022 走看看