前些天经手写了一个物流项目,发现使用地图的时候,真的是大坑套小坑(还是浅显使用),所以就来记录一下,也分享一下一些心得吧。(本文方法不兼容电脑浏览器使用,所以调试的时候请使用手机调试)
因为项目需要兼容h5,而我又是直接用的原生 <map> 标签,所以引入了外部jdk: qqmap-wx-jssdk.js,可以直接在 微信小程序JavaScript SDK 下载,下载完成以后就可以把js文件解压到项目中,因为需要改写一点点地方,所以不推荐使用压缩版的js
因为是wxjdk,所以第一步就先修改一些东西来兼容,(以下代码均为查询结果)
html地图部分代码:其中宽高大家自行根据需求更改
<map v-if="showMap" class="choose-map" style="width: 750rpx;height: 540rpx;" id="isUseMap" ref="UseMap" :latitude="selfLatitude" :longitude="selfLongitude" :markers="marker" :polyline="polyline" @tap="selectPoint" @markertap="markettap" @callouttap="callouttap" @regionchange="regionchange" :scale="scale" ></map>
其中所代表的是什么我就不一一说明了,v-if判断是为了解决地图展示后标记点有可能会失败的情况,所以我在获取到当前位置标点的时候在渲染地图,这里所谓仁者见仁,智者见智吧。
qqmap-wx-jssdk.js:
1 /** 2 * 这里是重写部分 3 */ 4 var vm = '' 5 6 var wx = { 7 request(obj){ 8 obj.data.output = 'jsonp' 9 vm.$jsonp(obj.url,obj.data) 10 .then(json => { 11 if(json.status == 0){ 12 obj.success(json) 13 }else { 14 obj.fail(json) 15 } 16 }) 17 .catch(err => { 18 obj.fail(err) 19 }) 20 } 21 }
改完以后保存、引入。
引入以后首先创建实例:
1 import QQMapWX from '@/common/qqmap-wx-jssdk.js'; 2 // TXMapkey是申请的qqmap key值 3 this.qqMap = new QQMapWX({ key: this.TXMapkey, vm: this });
创建完成后,就可以开始使用地图了,使用当前地图实例的时候可以参照上面分享的微信jdk文档,亲试可用(我觉得我应该说了句废话)。
使用地图:① 定位(getLocation) --> ② 标点(market) --> ③ 搜索(chooseAddress) --> ④ 路线 ;(本人技术有限,只写了这四种常用功能,写起代码来很混乱兼用了好几种方法)
① 定位(getLocation):
uniapp官方原生也给了一种获取定位的方法(但是总是会有一些顾及不到的地方):
其中获取定位类型有好几种,官方原生App给出的是高德地图支持 gcj02 类型,但是为了兼容h5所以这里使用 wgs84 类型坐标;
uni.getLocation({ type: 'wgs84', geocode: true, // 获取地址详情 success: res => { _that.selfLatitude = res.latitude; _that.selfLongitude = res.longitude; _that.addMarkets(res, 0); // 定位标出自身所在点 }, fail: err => {...}, complete: () => {...} });
官方原生获取定位坐标的API,但是很可惜,他好像并不兼容h5,所以我再执行完以后(complete)里面执行了WXSDK:
// #ifdef H5 _that.qqMap.reverseGeocoder({ location: { latitude: _that.selfLatitude, longitude: _that.selfLongitude }, success: function(res) { _that.selfLatitude = res.result.location.lat; _that.selfLongitude = res.result.location.lng; _that.keyword = res.result.address; _that.addMarkets(res, 1); }, fail: function(res) {}, complete: function(res) {} }); // #endif
到这里为止可以说有百分之八十的几率能获取到当前位置,但是总是还有一些问题,就比如标记点的问题,也可能是定位失败,这个坑我没有本事直接给添上,只能又加了一种办法(在WXJDK失败的时候fail):
fail: function(res) { plus.geolocation.getCurrentPosition( res => { let lati = res.coords.latitude, long = res.coords.longitude, positionAddress = gcoord.transform([long, lati], gcoord.WGS84, gcoord.GCJ02); _that.selfLatitude = positionAddress[1]; _that.selfLongitude = positionAddress[0]; _that.qqMap.reverseGeocoder({ location: { latitude: positionAddress[1], longitude: positionAddress[0] }, success: function(res) { _that.selfLatitude = res.result.location.lat; _that.selfLongitude = res.result.location.lng; _that.keyword = res.result.address; _that.addMarkets(res, 1); }, fail: err => {} }); },function(err){}, { enableHighAccuracy: true, geocode: true, maximumAge: 30000, timeout: 20000 } ) }
是的!你没有看错,我再疯狂的套娃,其中还是用了html5plus API plus.geolocation.getCurrentPosition 但这其中有一些问题,所以需要一个插件gcoord来把获取到的经纬度给处理一下,我也不知道该怎么解释,反正就是直接获取的经纬度不能用...对
在获取到经纬度以后我又一次的使用了WXJDK来确定当前位置并且添加标记点,到这里定位并且标记应该是没有问题了
② 标点(market) :
// 首次添加 标记点 addMarkets(res, type) { let result; if (type == 0 || type == 2) { // 原生定位 result = { latitude: res.result.location.lat, longitude: res.result.location.lng, name: (res.address && res.address.poiName) || '' }; console.log(JSON.stringify(result)); // console.log('原生定位') } else if (type == 1) { // 腾讯定位 result = { latitude: res.result.location.lat, longitude: res.result.location.lng, name: res.result.address || '' }; // console.log('腾讯定位') } let _that = this; let market = { id: ++_that.mid, latitude: result.latitude, longitude: result.longitude, iconPath: '/static/images/market-img.png', callout: { content: result.name, color: '#ffffff', fontSize: '14', display: 'ALWAYS', bgColor: '#FF6F1E', padding: '20', textAlign: 'center', borderRadius: '25' } }; _that.markers[0] = market; _that.markers = [..._that.markers]; _that.fromAddress = result.name; _that.showMap = true; },
上面获取定位的时候一部分上就是因为market点的问题,以上代码就是标记点,官网比我这边清楚。
③ 搜索(chooseAddress):
chooseAddress(type, index) {
// type是我的逻辑,index是出发地(0)与目的地(1) let _that = this; uni.chooseLocation({ keyword: _that.keyword, success: res => { let market = { id: ++_that.mid, latitude: res.latitude, longitude: res.longitude, iconPath: '/static/images/market-img.png', callout: { content: res.name, color: '#ffffff', fontSize: '14', display: 'ALWAYS', bgColor: '#FF6F1E', padding: '20', textAlign: 'center', borderRadius: '25' } }; if (index == 0) { _that.fromAddress = res.name; } if (index == 1) { _that.toAddress = res.name; } _that.includePoints[index] = market; _that.includePoints = [..._that.includePoints]; _that.markers[index] = market; _that.markers = [..._that.markers]; // 路线 _that.getTXDirection(); } });
其中标记点又出问题,问题出在了什么地方我也解释不清楚(希望有大佬看到的话可以告知小弟),可以用计算属性来解决:
computed: { marker() { return this.markers.slice(0, 2); }, include() { return this.includePoints.slice(0, 2); } },
④ 路线 :
这里路线我给出了两种获取路线的方法,大家可以参照一下:
第一种:高德地图
// 高德获取路线 getDirection() { let _that = this, origins = _that.markers[0].longitude + ',' + _that.markers[0].latitude, destination = _that.markers[1].longitude + ',' + _that.markers[1].latitude; this.aMapPlugin.getDrivingRoute({ origin: origins, destination: destination, success: data => { let points = []; if (data.paths && data.paths[0] && data.paths[0].steps) { var steps = data.paths[0].steps; for (var i = 0; i < steps.length; i++) { var poLen = steps[i].polyline.split(';'); for (var j = 0; j < poLen.length; j++) { points.push({ longitude: parseFloat(poLen[j].split(',')[0]), latitude: parseFloat(poLen[j].split(',')[1]) }); } } } // 线的样式:组成点,颜色,宽度 _that.polyline = [ { points: points, color: '#FF701E', width: 7 } ]; // console.log(_that.polyline) // if (data.paths[0] && data.paths[0].distance) { // that.setData({ // distance: data.paths[0].distance + '米' // }); // } // if (data.taxi_cost) { // that.setData({ // cost: '打车约' + parseInt(data.taxi_cost) + '元' // }); // } }, fail: err => { // console.log(err); // console.log('高德获取路线'); } }); },
第二种:腾讯地图
1 // 腾讯地图获取路线 2 getTXDirection() { 3 let _that = this, 4 origins = _that.markers[0].latitude + ',' + _that.markers[0].longitude, 5 destination = _that.markers[1].latitude + ',' + _that.markers[1].longitude; 6 this.qqMap.direction({ 7 from: origins, 8 to: destination, 9 success: res => { 10 // console.log(res); 11 var ret = res; 12 var coors = ret.result.routes[0].polyline, 13 points = []; 14 //坐标解压(返回的点串坐标,通过前向差分进行压缩) 15 var kr = 1000000; 16 for (var i = 2; i < coors.length; i++) { 17 coors[i] = Number(coors[i - 2]) + Number(coors[i]) / kr; 18 } 19 //将解压后的坐标放入点串数组points中 20 for (var i = 0; i < coors.length; i += 2) { 21 points.push({ latitude: coors[i], longitude: coors[i + 1] }); 22 } 23 let distance = res.result.routes[0].distance; 24 // 这个缩放问题我处理不了,头大 25 if (distance > 500000) { 26 this.scale = 3; 27 } else if (distance > 100000) { 28 this.scale = 7; 29 } else if (distance > 10000) { 30 this.scale = 9; 31 } else if (distance > 1000) { 32 this.scale = 14; 33 } 34 _that.polyline = [ 35 { 36 points: points, 37 color: '#FF701E', 38 width: 7 39 } 40 ]; 41 // console.log(_that.polyline) 42 }, 43 fail: err => { 44 // console.log(err); 45 } 46 }); 47 },
以上就是我接触地图的全部内容了,唉,磕磕绊绊的总算搞完了,心累,什么时候我才能变强啊~