有点小九九
简单的事情认真做

  前些天经手写了一个物流项目,发现使用地图的时候,真的是大坑套小坑(还是浅显使用),所以就来记录一下,也分享一下一些心得吧。(本文方法不兼容电脑浏览器使用,所以调试的时候请使用手机调试)

  因为项目需要兼容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         },

 

  以上就是我接触地图的全部内容了,唉,磕磕绊绊的总算搞完了,心累,什么时候我才能变强啊~ 

posted on 2020-09-26 17:06  有点小九九  阅读(5204)  评论(0编辑  收藏  举报