温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

微信小程序中如何使用地图

发布时间:2021-09-05 09:52:55 来源:亿速云 阅读:225 作者:小新 栏目:开发技术

小编给大家分享一下微信小程序中如何使用地图,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

    1. 准备

    通过阅读腾讯地图开放平台可以得知微信小程序可以下载SDK提供直接调用接口来使用腾讯地图,当然也可以自己对URL进行封装请求并返回自己的数据,本示例均使用了,因为SDK中封装时会调用某些接口,而在示例中会多时间内调用同一接口,那么就会造成频繁调用接口的错误。

    过程中我也会用有赞团队的vant来展示学校信息,所以也需要提前安装好依赖备用,具体安装步骤见官网

    2. 实战

    2.1 配置小程序权限

    首先就是在进入小程序时让用户给我们的小程序开启定位的权限,需要我们在app.json文件中添加以下代码:

    "permission": {
      "scope.userLocation": {
        "desc": "你的位置信息将用于小程序位置接口的效果展示"
      }
    }

    加上这一字段,当小程序用到定位系统时,发现小程序的权限没给到就会让用户将权限给到小程序,效果如下:

    微信小程序中如何使用地图

    2.2 封装工具函数

    2.2.1 全局函数与变量

    app.js

    // 全局变量
    globalData: {
        userInfo: null
      },
    // 全局引入方法,简便引入第三方包
    require: ($url)=> require($url)
    2.2.2 工具函数

    util.js

    // 引入SDK核心类
    const QQMapWX = require('./qqmap-wx-jssdk.min.js');
    // 实例化API核心类
    let key = '';
    let qqmapsdk;
    key &&(qqmapsdk = new QQMapWX({
      key // 必填
    }));
    module.exports = {
      qqmapsdk,
      key
    }

    这里我们引入SDK,并且将实例化对象直接传出去,但是这里需要给上腾讯的地图开放接口秘钥,这里我的key就不提供了,将key传出去是因为我们后面需要使用,为了不暴露自己的key,一般在开发时,key一般存储在后端的config中的,这里为了方便演示就在前端做处理了。

    2.3 跳转选址页面前的处理

    手机要定位不仅需要微信权限开启,还有我们的手机也有一个定位系统权限也要开启,所以在正式开始定位前,为了用户的更好体验我们这一块功能我们通常还需要一系列的操作,这里我简单的用button来用作跳转。

    wxml

    <view>
    	<van-btn bind:tap="gotoMap" type="info">前往使用地图</van-btn>
    </view>

    首先我们需要为按钮添加一个点击事件,这里我们可以处理很多事情;接下来让我们来看看js代码吧!

    // 引入所需的工具函数
    const app = getApp();
    const {qqmapsdk} = app.require('utils/util');
    Page({
      /**
       * 地图开始位置
       */
      // 点击按钮跳转到地图页面
       gotoMap(){
         wx.showLoading({
           title: "正在跳转至地图页"
         })
        // 跳转前要做几件事情提高用户体验性
        // 1. 要验证用户是否开启了定位,没有的话就引导
        // 2. 还需验证程序的定位权限,没有的话就引导
        // 3. 做好上面的两点才可以开始跳转了
        wx.getLocation({
          success(res){
            wx.navigateTo({
              url: "/pages/map/index"
            })
          },
          fail(e){
            if (e && (e.errCode == 2 || e.errCode == 404)) {
              wx.showModal({
                title: "提示",
                content: '位置信息获取失败,请检查手机“位置信息”是否未开启',
                showCancel: false
              })
            } else if (e && ((e.errMsg.indexOf('getLocation:fail auth deny') != -1) || (e.errMsg.indexOf('system permission denied') != -1))) {
              showModal({
                title: "提示",
                content: '位置信息获取失败,请检查微信是否有定位权限',
                confirmText: "重新获取",
                success(res){
                  if(res.confirm === true){
                    detectSettings()
                  } else if(res.cancel == true){
                    return;
                  }
                }
              })
            } else if(e.errMsg.indexOf("频繁") !== -1){
              wx.showModal({
                title: "提示",
                content: "位置信息接口调用太频繁了,请等10-30秒后再操作。",
                showCancel: false
              })
            }
          },
          complete(){
            wx.hideLoading()
          }
        })
        // 引导开启微信定位权限
        function detectSettings(){
          wx.getSetting({
            success(res){
              if(res && (res.authSetting["scope.userLocation"] !== undefined && res.authSetting["scope.userLocation"] !==true)){
                wx.showModal({
                  title: "提示",
                  content:"小程序没有定位权限,请前往设置微信小程序的定位权限。",
                  confirmText: "前往设置",
                  success(res){
                    if(res.cancel == true){
                      return
                    } else if (res.confirm === true){
                      wx.openSetting({
                        success(result){
                          if(result && (result.authSetting["scope.userLocation"] !== undefined && result.authSetting["scope.userLocation"] ===true)){
                            wx.navigateTo({
                              url: "/pages/map/index"
                            })
                          } else {
                            wx.navigateTo({
                              url: "/pages/index/index"
                            })
                          }
                        },
                      })
                    } 
                  },
                  fail(){
                    wx.navigateTo({
                      url: "/pages/index/index"
                    })
                  }
                })
              } else {
                wx.navigateTo({
                  url: "/pages/map/index"
                })
              }
            },
            complete(){
              wx.hideLoading()
            }
          })
        }
       }
    })

    看完代码就看看效果吧,我们这里着重说明没有符合跳转的条件,效果如下GIF所示:

    微信小程序中如何使用地图

    上面的GIF没有对手机定位系统未开做处理,这个演示在这个方面的处理比较简单,仅仅是提示一下就没了,日常开发中一般会有其他的更好的处理方式,未开的效果如下:

    微信小程序中如何使用地图

    2.4 跳转后的处理

    2.4.1 页面初始化

    经过上一步的处理我们已经已经确定了,手机的两个权限都给到了,那么我们开始处理地图选址页面的处理,开始之前先看看成品是什么样的,如下:

    微信小程序中如何使用地图

    wxml

    <!--pages/map/index.wxml-->
    <view class="fixed top">
      <van-search bind:search="searchSchool" placeholder="请输入学校名称" model:value="{{schoolName}}" />
      <view class="school-nav">
        <text class="left">附近的学校</text>
        <view class="right" bind:tap="changeCity">
          <van-icon name="location-o" />
          <text>{{city || "北京市"}}</text>
        </view>
      </view>
    </view>
    <view class="addr-cell" bindtap="subData">
      <block wx:for="{{options}}" wx:key="index">
        <van-cell data-chooseOpt="{{item}}" title-width="70vw" title="{{item.title}}" value="" label="{{item.address}}" />
      </block>
      <view id="txt" class="btm">
        <text wx:if="{{options.length}}">{{count>0 ? "下拉刷新获取更多信息" : "已经到底了"}}</text>
        <text class="no-data" wx:else>没有获取到相关的数据。。。</text>
      </view>
    </view>	

    整体框架就如上面的wxml所示,如果将数据全部提供就会像上图所示。那么接着说明一下他的逻辑实现吧!

    // 引入所需的工具函数
    const app = getApp();
    const {qqmapsdk,key} = app.require('utils/util');
    // 初始化生命周期函数
    onLoad: function (options) {
      _this = this;
      _this.init()
    },

    下面的函数不仅仅在加载时用到,在后面也会用到,我用传入的参数来区别。如果是在加载时调用,他仅仅是为了获取到用户的当前位置,获取到的位置用于显示;如果传入一个地址就将用于地址逆解析的。

    // 你地址解析和获取当前位置
    init(location){
      let query = {
        success(res){
          console.log(res)
          if(res.status === 0) {
            // console.log(res.result.location)
            app.globalData.adInfo = res.result.ad_info;
            _this.setData({
              city: res.result.ad_info.city,
              lat: res.result.location.lat,
              lng: res.result.location.lng,
            })
            _this.qqSearch();
          } else {
            wx.showModal({
              title: '提示',
              content:res.message || "获取地理位置信息失败。",
              showCancel: false
            })
          }
        },
        fail(e){
          console.log(e)
        }
      }
      location && (query.location = location);
      qqmapsdk.reverseGeocoder(query);
    }
    2.4.2 搜索功能实现
    // 如果输入的是一个城市,就只会显示城市而不会显示学校
    searchSchool(e){
      // 没输入或者输入空格
      if(e && (!e.detail || e.detail.trim() === '')){
        wx.showToast({
          title: "请输入有效的学校名称",
          icon: 'none',
          duration: 2000
        })
        return
      }
      _this.setData({
        options:[],
        count: -2
      })
      _this.qqSearch(e.detail);
    },
    qqSearch(name){
      // 输入框输入的学校名称
      wx.showLoading({
        title: "正在获取信息"
      })
      const mks = [];
      let count,
          boundary= `nearby(${_this.data.lat},${_this.data.lng},1000)`;
      search(name)
      function search(name){
        const opts = {
          keyword: '大学',  //搜索关键词
          page_size: 15,
          page_index: _this.data.pageIndex, // 获取更多
          key: key,
          boundary
        };
        if(name){
          opts.boundary = `region(${_this.data.city})`
          opts.keyword = name
        }
        // 这里主要是避免高频调用接口而导致的错误,所以只能使用URL获取相关信息
        wx.request({
          url: "https://apis.map.qq.com/ws/place/v1/search",
          method: "get",
          data:{
            ...opts
          },
          success: function (res) { //搜索成功后的回调
            console.log(res)
            if(res.statusCode !== 200 || (res.data && res.data.status !== 0)) return;
            // 初始化和其他状态
            // 计算可以下滑几次获取更多
            if(_this.data.count === -1 || _this.data.count === -2){
              count = res.data.count && Math.floor(res.data.count/10);
            }else {
              count = --_this.data.count;
            }
            for (let i = 0; i < res.data.data.length; i++) {
              mks.push({ // 获取返回结果,放到mks数组中
                title: res.data.data[i].title,
                address: res.data.data[i].address,
              })
            }
          },
          fail: function (e) {
            console.log(e)
            wx.showToast({
              title: JSON.stringify(e) || "获取地图信息失败",
              icon: "none",
              duration: 3000
            })
          },
          complete: function (){
            setTimeout(()=>{
              wx.hideLoading()
              mks.push(..._this.data.options);
              _this.setData({ //设置markers属性,将搜索结果显示在地图中
                options: mks,
                count
              })
            },1000)
          }
        });
      }
    },
    2.4.3 下滑到底获取更多
    // 下滑到底生命周期函数
    onReachBottom: function () {
      _this.data.pageIndex = ++_this.data.pageIndex;
      _this.data.count && _this.qqSearch();
    },
    2.4.4 提交数据

    对于提交数据这里就不多做处理了,选择的话就提示一下,在实际开发中一般都需要将数据存到数据库中另作他用。

    subData(e){
      const data = e.target.dataset.chooseopt;
      // 处理点击提示文字的情况
      if(!data) return;
      wx.showModal({
        title: "提示",
        content: `您所在学校是【${data.title}】吗?`,
        success(res){
          // 取消
          if(res.cancel) {
            return;
          } else if (res.confirm){
            // 确定
            // 向后端请求添加或者修改,一般需要详细的地址,这里简单处理
            wx.showToast({
              title: data.title,
              icon: "none"
            })
          }
        },
        fail(){
          wx.showToast({
            title: "失败",
            icon: "error"
          })
        }
      })
    }
    2.4.5 切换城市
    changeCity(){
      _this.setData({
        options:[],
        count:-2,
        // 简易的双向数据绑定,进入就清空输入框的内容
        schoolName: ''
      })
      wx.chooseLocation({
        latitude:_this.data.lat,
        longitude:_this.data.lng,
        success(res){
          if(res.errMsg === "chooseLocation:ok"){
            // 获取到选择的位置,会通过地址逆解析去解析经纬度
            _this.init(`${res.latitude},${res.longitude}`);
          }
        },
        // 按取消按钮
        fail(e){
          if(e.errMsg === "chooseLocation:fail cancel"){
            _this.init();
          }
        },
        complete(){
        }
      })
    }

    以上是“微信小程序中如何使用地图”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注亿速云行业资讯频道!

    向AI问一下细节

    免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

    AI