记一次小程序内地图的使用

1,179 阅读6分钟

前言

    今天在做新需求的时候发现个很尬的问题:我们项目的小程序是直接输入账号密码进行登录的,不是平常的获得用户授权登录的模式,所以当我使用wx.getLocation一直拉不下来授权一直进fail不去success的时候我开始慌了

    我以为是由于这个登录模式不同导致,然后我就开始疯狂骚扰我的小伙伴,问是不是这种登录模式会拉不到用户授权(在这里感谢我的小伙伴们没打死我,反而认真给我解惑),后来我清了下开发者工具缓存就能拉下来了(在这里求求TX的大佬们再做做开发者工具的优化吧,写原生的真的要流泪了)

     如果觉得上面屁话太多可以不看哈,只要记住:

     使用输入账号密码和用户授权的登录模式都是可以拉下来授权的(小声bb:其实我感觉平地都能拉授权)

使用

获得经纬度加逆解析得到详细地址

先要有个腾讯地图的key
官网:lbs.qq.com/
贴上百度经验申请腾讯地图key的链接(比我自己写的详细得多):jingyan.baidu.com/article/656…
贴上官网API地址:developers.weixin.qq.com/miniprogram…

记得在app.json里面配置:

  "permission": {
    "scope.userLocation": {      "desc": "我们将根据您的定位进行服务分类"    }  },

参数什么的以官方的为准,以下为具体代码:

var QQMapWX = require('../../../utils/qqmap-wx-jssdk.js');
const { request } = require("../../../utils/util");
var qqmapsdk
//onload里面写的:
 // 实例化腾讯地图API核心类
   qqmapsdk = new QQMapWX({
      key: '###MiaoWu~###'//这个去腾讯地图申请
    });

  // 获取用户的实时位置  getAddress() {
    var that = this;
    //1、获取当前位置坐标
    wx.getLocation({
      type: 'wgs84',
      success: function (res) {
        //2、根据坐标获取当前位置名称,显示在顶部:腾讯地图逆地址解析
        qqmapsdk.reverseGeocoder({
          location: {
            latitude: res.latitude,
            longitude: res.longitude
          },
          success: function (addressRes) {
            // 显示位置
            var address = addressRes.result.formatted_addresses.recommend;
            console.log(address);
            that.setData({ 
             latitude: res.latitude, 
             longitude: res.longitude,
              addressNow: address
            })
          }
        })
      },
      fail: function () {
        console.log("调取失败")
      }
    })
  },

画地图并获得经纬度以及详细地址

方法和上面写的相差无几,就是多了点wxml的东西

官方map地址:developers.weixin.qq.com/miniprogram…

<map id="map" longitude="{{longitude}}" latitude="{{latitude}}" 
    scale="14" show-scale show-location style="width: 100%; height: 100vh;"> 
 <cover-view class="dosomething fr">    
    <cover-image class="img" src="/assets/icon/refresh.png" bindtap="toRefresh"></cover-image>
     <cover-image class="img" src="/assets/icon/goSelf.png"  bindtap="toRefresh"></cover-image>
  </cover-view>
  <cover-view class="sureLocation" bindtap="sureLocation">确定</cover-view>
</map>

业务需求不能让用户搜索以及选点,只能看自己所在位置,再加上开发者工具上暂不支持比例尺,所以这个图就当看着意思意思(还有开发者工具上定位贼不准,都给我整到区政府去了,各位在用的时候还是看自己手机调吧)



最后贴上逆解析文件qqmap-wx-jssdk.js的代码:

(不是我写的哈,我只是大佬的搬运工QAQ)

/** * 微信小程序JavaScriptSDK *
  * @version 1.0
 * @date 2017-01-10 
* @author jaysonzhou@tencent.com
 */
var ERROR_CONF = {
    KEY_ERR: 311,
    KEY_ERR_MSG: 'key格式错误',
    PARAM_ERR: 310,
    PARAM_ERR_MSG: '请求参数信息有误',
    SYSTEM_ERR: 600,
    SYSTEM_ERR_MSG: '系统错误',
    WX_ERR_CODE: 1000,
    WX_OK_CODE: 200};var BASE_URL = 'https://apis.map.qq.com/ws/';
var URL_SEARCH = BASE_URL + 'place/v1/search';var URL_SUGGESTION = BASE_URL + 'place/v1/suggestion';var URL_GET_GEOCODER = BASE_URL + 'geocoder/v1/';var URL_CITY_LIST = BASE_URL + 'district/v1/list';
var URL_AREA_LIST = BASE_URL + 'district/v1/getchildren';
var URL_DISTANCE = BASE_URL + 'distance/v1/';
var Utils = {
    /**
     * 得到终点query字符串 
    * @param {Array|String} 检索数据
     */
    location2query(data) {
        if (typeof data == 'string') {
            return data; 
       }
        var query = '';
        for (var i = 0; i < data.length; i++) {
            var d = data[i];
            if (!!query) { 
               query += ';';
            }
            if (d.location) {
                query = query + d.location.lat + ',' + d.location.lng;
            }
            if (d.latitude && d.longitude) {
                query = query + d.latitude + ',' + d.longitude;
            }
        }
        return query;
    },
    /**
     * 使用微信接口进行定位
     */ 
   getWXLocation(success, fail, complete) {
        wx.getLocation({
            type: 'gcj02',
            success: success,
            fail: fail, 
           complete: complete 
       });
    },
    /**
     * 获取location参数
     */ 
   getLocationParam(location) {
        if (typeof location == 'string') {
            var locationArr = location.split(',');
            if (locationArr.length === 2) {
                location = {
                    latitude: location.split(',')[0], 
                   longitude: location.split(',')[1] 
               }; 
           } else {
                location = {};
            }
        } 
       return location;
    },
    /**
     * 回调函数默认处理
     */
    polyfillParam(param) {
        param.success = param.success || function () { };
        param.fail = param.fail || function () { };
        param.complete = param.complete || function () { };
    },
    /** 
    * 验证param对应的key值是否为空
     *
      * @param {Object} param 接口参数 
    * @param {String} key 对应参数的key
     */
    checkParamKeyEmpty(param, key) {
        if (!param[key]) {
            var errconf = this.buildErrorConfig(ERROR_CONF.PARAM_ERR, ERROR_CONF.PARAM_ERR_MSG + key +'参数格式有误');
            param.fail(errconf);
            param.complete(errconf);
            return true;
        }
        return false;
    },
    /**
     * 验证参数中是否存在检索词keyword
     *
      * @param {Object} param 接口参数
     */
    checkKeyword(param){
        return !this.checkParamKeyEmpty(param, 'keyword');
    },
    /**
     * 验证location值
     *
      * @param {Object} param 接口参数
     */
    checkLocation(param) {
        var location = this.getLocationParam(param.location);
        if (!location || !location.latitude || !location.longitude) {
            var errconf = this.buildErrorConfig(ERROR_CONF.PARAM_ERR, ERROR_CONF.PARAM_ERR_MSG + ' location参数格式有误')
            param.fail(errconf);
            param.complete(errconf);
            return false;
        }
        return true;
    },
    /**
     * 构造错误数据结构
     * @param {Number} errCode 错误码
     * @param {Number} errMsg 错误描述
     */
    buildErrorConfig(errCode, errMsg) { 
       return {
            status: errCode, 
           message: errMsg 
       };
    },
    /**
     * 构造微信请求参数,公共属性处理
     *
      * @param {Object} param 接口参数
     * @param {Object} param 配置项
     */
    buildWxRequestConfig(param, options) {
        var that = this;
        options.header = { "content-type": "application/json" };
        options.method = 'GET';
        options.success = function (res) {
            var data = res.data;
            if (data.status === 0) {
                param.success(data);
            } else {
                param.fail(data);
            }
        };
        options.fail = function (res) {
            res.statusCode = ERROR_CONF.WX_ERR_CODE;
            param.fail(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, result.errMsg)); 
       };
        options.complete = function (res) {
            var statusCode = +res.statusCode;
            switch(statusCode) {
                case ERROR_CONF.WX_ERR_CODE: {
                    param.complete(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, res.errMsg)); 
                   break;
                }
                case ERROR_CONF.WX_OK_CODE: { 
                   var data = res.data;
                    if (data.status === 0) { 
                       param.complete(data); 
                   } else {  
                      param.complete(that.buildErrorConfig(data.status, data.message));
                    }
                    break;
                }
                default:{
                    param.complete(that.buildErrorConfig(ERROR_CONF.SYSTEM_ERR, ERROR_CONF.SYSTEM_ERR_MSG));
               } 
           }
        }
        return options;
    },
    /**
     * 处理用户参数是否传入坐标进行不同的处理 
    */ 
   locationProcess(param, locationsuccess, locationfail, locationcomplete) {
        var that = this;
        locationfail = locationfail || function (res) { 
           res.statusCode = ERROR_CONF.WX_ERR_CODE;
            param.fail(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, res.errMsg));
        };
        locationcomplete = locationcomplete || function (res) {
            if (res.statusCode == ERROR_CONF.WX_ERR_CODE) { 
               param.complete(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, res.errMsg));
            }
        };
        if (!param.location) { 
           that.getWXLocation(locationsuccess, locationfail, locationcomplete); 
       } else if (that.checkLocation(param)) { 
           var location = Utils.getLocationParam(param.location); 
           locationsuccess(location);
        }
    }}class QQMapWX {
    /**
     * 构造函数  
     *
      * @param {Object} options 接口参数,key 为必选参数
     */
    constructor(options) {
        if (!options.key) {
            throw Error('key值不能为空');
        }
        this.key = options.key;
    }
    /**
     * POI周边检索
     *
     * @param {Object} options 接口参数对象
     * 
     * 参数对象结构可以参考
     * @see http://lbs.qq.com/webservice_v1/guide-search.html
     */
    search(options) {
        var that = this; 
       options = options || {}; 
       Utils.polyfillParam(options);
       if (!Utils.checkKeyword(options)) { 
           return;
        }
        var requestParam = {
            keyword: options.keyword,
            orderby: options.orderby || '_distance',
            page_size: options.page_size || 10,
            page_index: options.page_index || 1,
            output: 'json',
            key: that.key
        };
        if (options.address_format) {
            requestParam.address_format = options.address_format;
        }
        if (options.filter) { 
           requestParam.filter = options.filter;
        }
        var distance = options.distance || "1000";
        var auto_extend = options.auto_extend || 1; 
       var locationsuccess = function (result) {
            requestParam.boundary = "nearby(" + result.latitude + "," + result.longitude + "," + distance + "," + auto_extend +")";
            wx.request(Utils.buildWxRequestConfig(options, {
                url: URL_SEARCH,
                data: requestParam
            }));
        }
        Utils.locationProcess(options, locationsuccess);
    }
    /** 
    * sug模糊检索
     * 
    * @param {Object} options 接口参数对象
     *
      * 参数对象结构可以参考
     * http://lbs.qq.com/webservice_v1/guide-suggestion.html
     */
    getSuggestion(options) {
        var that = this; 
       options = options || {};
        Utils.polyfillParam(options);
        if (!Utils.checkKeyword(options)) {
            return;
        }
        var requestParam = {
            keyword: options.keyword,
            region: options.region || '全国',
            region_fix: options.region_fix || 0,
            policy: options.policy || 0,  
            output: 'json',
            key: that.key 
       };
        wx.request(Utils.buildWxRequestConfig(options, { 
           url: URL_SUGGESTION, 
           data: requestParam  
      }));
    }
    /**
     * 逆地址解析
     *
     * @param {Object} options 接口参数对象 
    *
      * 请求参数结构可以参考
     * http://lbs.qq.com/webservice_v1/guide-gcoder.html
     */
    reverseGeocoder(options) {
        var that = this; 
       options = options || {};
        Utils.polyfillParam(options);
        var requestParam = {
            coord_type: options.coord_type || 5,
            get_poi: options.get_poi || 0, 
            output: 'json',
            key: that.key
        };
        if (options.poi_options) {
            requestParam.poi_options = options.poi_options
        }
        var locationsuccess = function (result) {
            requestParam.location = result.latitude + ',' + result.longitude;
            wx.request(Utils.buildWxRequestConfig(options, {
                url: URL_GET_GEOCODER,
                data: requestParam
            }));
        };
        Utils.locationProcess(options, locationsuccess);
    }
    /**
     * 地址解析
     *
     * @param {Object} options 接口参数对象
     *
      * 请求参数结构可以参考
     * http://lbs.qq.com/webservice_v1/guide-geocoder.html
     */
    geocoder(options) {
        var that = this;
        options = options || {};
        Utils.polyfillParam(options);
        if (Utils.checkParamKeyEmpty(options, 'address')) {
            return;
        }
        var requestParam = {
            address: options.address,
            output: 'json',
            key: that.key
        };
        wx.request(Utils.buildWxRequestConfig(options, {
            url: URL_GET_GEOCODER, 
           data: requestParam
        }));
    }
    /**
     * 获取城市列表
     *
     * @param {Object} options 接口参数对象
     *
     * 请求参数结构可以参考
     * http://lbs.qq.com/webservice_v1/guide-region.html
     */
    getCityList(options) {
        var that = this;
        options = options || {}; 
       Utils.polyfillParam(options);
        var requestParam = { 
           output: 'json', 
           key: that.key 
       };
        wx.request(Utils.buildWxRequestConfig(options, {
            url: URL_CITY_LIST,
            data: requestParam
        }));
    }
    /**
     * 获取对应城市ID的区县列表
     *
     * @param {Object} options 接口参数对象
     * 
     * 请求参数结构可以参考
     * http://lbs.qq.com/webservice_v1/guide-region.html
     */
    getDistrictByCityId(options) {
        var that = this;
        options = options || {};
        Utils.polyfillParam(options);
        if (Utils.checkParamKeyEmpty(options, 'id')) {
            return;
        }
        var requestParam = {
            id: options.id || '',
            output: 'json',
            key: that.key
        };
        wx.request(Utils.buildWxRequestConfig(options, {
            url: URL_AREA_LIST,
            data: requestParam
        }));
    }
    /**
     * 用于单起点到多终点的路线距离(非直线距离)计算:
     * 支持两种距离计算方式:步行和驾车。
     * 起点到终点最大限制直线距离10公里。
     *  
     * @param {Object} options 接口参数对象
     * 
     * 请求参数结构可以参考
     * http://lbs.qq.com/webservice_v1/guide-distance.html
     */
    calculateDistance(options) {
        var that = this;
        options = options || {};
        Utils.polyfillParam(options);
        if (Utils.checkParamKeyEmpty(options, 'to')) {
            return;
        } 
       var requestParam = {
            mode: options.mode || 'walking',
            to: Utils.location2query(options.to),
            output: 'json',
            key: that.key
        }; 
       var locationsuccess = function (result) {
            requestParam.from = result.latitude + ',' + result.longitude;
            wx.request(Utils.buildWxRequestConfig(options, {
                url: URL_DISTANCE,
                data: requestParam 
           }));
        }
        if (options.from) {
            options.location = options.from;
        }
                Utils.locationProcess(options, locationsuccess);
    }}
module.exports = QQMapWX;

总感觉还有啥没写,但又想不起来了,回头记起来补吧

实话感觉自己写的这个没什么技术含量,就当给自己的一个总结,所以求各位轻喷

使用如果有问题的话就在评论区滴滴,我会的都跟你说

啾咪,就这样啦~