1、实现需求

小程序中需要使用到地图导航定位,所以在客户端填写基础信息时需要填写详细地址,同时得到经纬度坐标,从而实现地图导航。
1.1 实现方式一
根据用户选择的省、市、县(区)以及输入的详细地址信息,通过百度官方提供的地址编码解析从而得到地址经纬度坐标。
先下载vue-jsonp: npm(cnpm) install --save vue-jsonp
在main中引入:import * as VueJsonp from 'vue-jsonp	(这里注意 加上” * as  “)
						Vue.prototype.$jsonp = VueJsonp
方法如下:
getLocation() {
  // addres 详细的地址信息
  let addres = '省' + '市' + '县(区)' + '详细地址';
  this.$jsonp.jsonp('https://api.map.baidu.com/geocoding/v3/', {
    address: addres,
    output: 'json',
    ak: 'ak密钥'
  }).then(res => {
    if (res.status == 0) {
      // status == 0 就是定位成功,lat\lng就是经纬度坐标
      let data = res.result.location;
      let Latitude = data.lat
      let Longitude = data.lng
    } else {
      this.$message.warning('未获取到地址定位信息请确认输入地址正确在提交')
    }
  }).catch(err => {
    console.log(err);
  })
},
在你以为可以的时候,事情往往没有这么简单。因为详细地址是输入的,这就在可控范围之外了,很多输入不是街道门牌号的,使用地址
接卸根本无法精确定位,但前头有省市区,它依旧能大致定位,在更具后面某些关键字,这就造成了定位不精准,导航地址会出错。于是
给出了第二种方法,让用户自己去点击地图给出定位坐标。
1.2 实现方法二
前头说到让用户自己去点击地图定位,那就得用到地图,所以下载了vue-baidu-map这个依赖
中文文档:[vue-baidui-map](https://dafrok.github.io/vue-baidu-map/#/zh/index)
同时为了方便多处使用,做成组件引用。
<template>
  <div>
  	<!-- @moving、@moveend、@zoomend 缩放拖动地图更改地图显示层级 @dragend:拖动图标结束时执行getClickInfo获取经纬度坐标或点击地图获取点击地方的经纬度 -->
    <baidu-map v-bind:style="mapStyle" class="bm-view" ak="密钥" :center="center" :zoom="zoom" :scroll-wheel-zoom="true" @click="getClickInfo" @moving="syncCenterAndZoom" @moveend="syncCenterAndZoom" @zoomend="syncCenterAndZoom">
      <bm-view style="width: 100%; height:600px;"></bm-view>
      <!-- animation="BMAP_ANIMATION_BOUNCE" --> 
      <bm-marker :position="{lng: center.lng, lat: center.lat}" :dragging="true" @dragend="getClickInfo">
      </bm-marker>
      <bm-control :offset="{width: '10px', height: '10px'}">
        <bm-auto-complete v-model="keyword" :sugStyle="{zIndex: 999999}">
          <input type="text" placeholder="请输入搜索关键字" class="serachinput">
        </bm-auto-complete>
      </bm-control>
      <bm-local-search :keyword="keyword" :auto-viewport="true" style="width:0px;height:0px;overflow: hidden;"></bm-local-search>
    </baidu-map>
    <div slot="footer" style="margin-top: 20px;text-align:right;">
      <el-button @click="cancel">取消
      </el-button>
      <el-button type="primary" @click="confirm">确定</el-button>
    </div>
  </div>
</template>
<script>
  import { BaiduMap, BmControl, BmView, BmAutoComplete, BmLocalSearch, BmMarker } from 'vue-baidu-map'
  export default {
    components: {
      BaiduMap,
      BmControl,
      BmView,
      BmAutoComplete,
      BmLocalSearch,
      BmMarker
    },
    data: function() {
      return {
        keyword: '', // 通过BmLocalSearch搜素地址,然后再进行定位
        mapStyle: {
          width: '100%',
          height: this.mapHeight + 'px'
        },
        center: { lng: 114.986373, lat: 27.111699 }, // 地图中心位置(也是标记点图标的位置)
        zoom: 17, // 地图层级
        addres: '', // 地址
      }
    },
    props: {
      mapHeight: { // 地图样式,默认高度(可随意)
        type: Number,
        default: 600
      },
      mapLat: Number, // 传入的经纬度,用于初始化显示地理中心位置
      mapLng: Number, 
    },
    methods: {
   	  // 初始化地图,地图进入时默认显示的中心位置
      initCB() {
        this.center = {
          lat: (this.mapLat !== undefined && this.mapLat > 0) ? this.mapLat : 27.111183,
          lng: (this.mapLng !== undefined && this.mapLng > 0) ? this.mapLng : 115.027531
        }
      },
      /***
       * 地图点击事件、定位图标拖拽移动事件
       */
      getClickInfo(e) {
        let that = this;
        this.center.lng = e.point.lng
        this.center.lat = e.point.lat
        var geoc = new BMap.Geocoder();
        geoc.getLocation(e.point, function(rs) {
          var addComp = rs.addressComponents;
          let addr = addComp.province + addComp.city + addComp.district + addComp.street + addComp.streetNumber
          that.addres = addr;
          console.log("当前所在位置信息" + addr);
        });
      },
      syncCenterAndZoom(e) {
        this.zoom = e.target.getZoom()
      },
      /***
       * 确认
       */
      confirm: function() {
        let params = {
          center: this.center,
          addres: this.addres
        }
        this.$emit('mapConfirm', params)
      },
      /***
       * 取消
       */
      cancel: function() {
        this.$emit('mapCancel', false)
      }
    }
  }
</script>

<style scoped>
  .serachinput {
    width: 300px;
    box-sizing: border-box;
    padding: 9px;
    border: 1px solid #dddee1;
    line-height: 20px;
    font-size: 16px;
    height: 38px;
    color: #333;
    position: relative;
    border-radius: 4px;
    -webkit-box-shadow: #666 0px 0px 10px;
    -moz-box-shadow: #666 0px 0px 10px;
    box-shadow: #666 0px 0px 10px;
  }

</style>
<style>
  .anchorBL{
    display: none;
  }
</style>
<el-dialog title="标注详细地址" :visible.sync="showMap" top="60px" width="80%" height="800px" @opened="handlerMapOpened" :close-on-click-modal="false">
  <Mapset ref="mapset" title="地图标注" @mapConfirm="handlerMapClose" @mapCancel="handlerMapClose" :mapLat="CompanyBaseInfo.Latitude" :mapLng="CompanyBaseInfo.Longitude"></Mapset>
</el-dialog>

<!-- js部分 -->
handlerMapOpened() {
  // 打开弹窗时去加载地图 mapLat、mapLng传参
  this.$refs.mapset.initCB();
},
handlerMapClose(data) {
 console.log(data);
 if(data!=false){
 	// 点击确认时执行
 }
 this.showMap = false;
},

最后实现效果,点击地图红色标注就会到点击的地方,也可以拖动红色标记点到指定地方
在这里插入图片描述
目前还存在的缺陷就是这个搜索,明明点击了某一个地址,但地图上还是标记了A、B、C、D…一大堆标记。
同时注意一个问题:小程序中一般默认都使用腾讯地图,而腾讯地图经纬度坐标和百度地图是不同的,所以在使用时需要转换!!!

Logo

前往低代码交流专区

更多推荐