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./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.latlet 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.lngthis.center.lat = e.point.latvar 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.streetNumberthat.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…一大堆标记。
同时注意一个问题:小程序中一般默认都使用腾讯地图,而腾讯地图经纬度坐标和百度地图是不同的,所以在使用时需要转换!!!
vue+vue-baidu-map(百度地图)实现点击地图标注地理信息并获取经纬度坐标或拖拽图标获取地理坐标信息