微信小程序中正确使用地图的方法实例

目录
  • 前言
  • 1. 准备
  • 2. 实战
    • 2.1 配置小程序权限
    • 2.2 封装工具函数
      • 2.2.1 全局函数与变量
      • 2.2.2 工具函数
    • 2.3 跳转选址页面前的处理
    • 2.4 跳转后的处理
      • 2.4.1 页面初始化
      • 2.4.2 搜索功能实现
      • 2.4.3 下滑到底获取更多
      • 2.4.4 提交数据
      • 2.4.5 切换城市
  • 总结

前言

今天是我的小兄弟(微信小程序方面)在工作中遇到的一个场景——选择某个位置周围的学校,感觉很有用,就让他给大家分享一下。

这次想分享一下关于微信小程序中选择全国中的一个学校和地址的方法,经过调研发现大多网站提供全国学校名称的是比较老的一些学校,像比较新或者地方比较偏僻的学校一般都找不到。想想这样是肯定不行的,那就继续寻找能更全面的方式,最终想到了地图中提供的服务提供的学校最全面,这里就采用腾讯地图的开放接口作为示例演示。

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(){
    }
  })
}

到此,微信小程序学校选择就全部完成了,此次实战一步一步慢慢实现下来逻辑并不复杂。

总结

到此这篇关于微信小程序中正确使用地图的文章就介绍到这了,更多相关微信小程序使用地图内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 微信小程序开发之map地图实现教程

    前言 微信小程序地图操作比较简单,api也很少,使用map组件来展示.说到地图,那就先来看基础定位: 定位用到wx.getLocation(OBJECT)函数,代码如下: wx.getLocation({ type: 'wgs84', success: function(res) { var latitude = res.latitude var longitude = res.longitude var speed = res.speed var accuracy = res.accuracy

  • 微信小程序地图(map)组件点击(tap)获取经纬度的方法

    微信小程序中使用地图(map)组件,通过点击(tap)获取经纬度,按照官方的回应,暂时是没法做到的,从地图组件API多有残缺判断,怀疑是个实习生干的... 做个变通,适用性有限,请大家参考.基本思路就是在地图上铺满一层marker,从而通过点击marker获得经纬度. 复制代码 代码如下: <map id="map" longitude="102.324520" latitude="40.099994" scale="4"

  • 微信小程序 使用腾讯地图SDK详解及实现步骤

    微信小程序 使用腾讯地图SDK详解及实现步骤 近期在做一款彩票服务类项目中用到了腾讯地图提供的小程序解决方案,拿来给大家分享一下! 使用起来非常简单,就是一些功能还有待完善. 官方文档:http://lbs.qq.com/qqmap_wx_jssdk/index.html 步骤: 申请开发者密钥(key):申请密匙 下载微信小程序JavaScriptSDK,微信小程序JavaScriptSDK v1.0 安全域名设置,需要在微信公众平台添加域名地址https://apis.map.qq.com

  • 微信小程序 地图map详解及简单实例

    微信小程序 地图map 微信小程序map 地图 属性名 类型 默认值 说明 longitude Number   中心经度 latitude Number   中心纬度 scale Number 1 缩放级别 markers Array   标记点 covers Array   覆盖物 标记点 标记点用于在地图上显示标记的位置,不能自定义图标和样式 属性 说明 类型 必填 备注 latitude 纬度 Number 是 浮点数,范围 -90 ~ 90 longitude 经度 Number 是

  • 微信小程序 地图(map)实例详解

    微信小程序 地图(map)实例 这里是小编对微信小程序 地图(map API )做的资料整理,获取当前的地址,应该如何实现的实例,大家可以看下. 今天做到地图定位的模块.模拟器肯定是获取不到位置的.下面为真机测试结果. 上图: 经纬度不说了.定位用的,我这里直接输入的数字定位.但是有许多问题 下图中scale是缩放比例,这个属性目前无效.后期微信团队应该会修复.毕竟现在刚开始公测.这样就导致我不管怎么修改scale,我的地图都是在默认的缩放比例.如上图. markers中的rotate是图标的旋

  • 微信小程序之获取当前位置经纬度以及地图显示详解

    最近刚开始接触微信小程序,在弄懂其结构以及相关接口之后,准备着手实现一个小程序,功能包括--获取用户当前位置的经纬度,在地图上查看位置,通过地图获取不同位置的经纬度. 微信小程序的主体部分包括: 新增页面需要在app.json进行配置: "pages":[ "pages/index/index", "pages/location/location", "pages/logs/logs" ] 通过在视图层调用bindtap与逻辑

  • 微信小程序 地图定位简单实例

    微信小程序开发地图定位. 微信小程序 刚刚公布没多久,自己学习一下内容,以便以后的开发,想落后别人,这里做了一个简单的小程序示例,大家可以参考下 要求要完成的功能: 1.要完成的要点是城市定位. 2.就是切换城市. 首页我们先参照微信小程序开放的官方文档找到: 在这里我们可以找到"当前位置经纬度" getLocation: function () { var that = this wx.getLocation( { success: function (res) { console.

  • 微信小程序 高德地图SDK详解及简单实例(源码下载)

    微信小程序 高德地图SDK: 简介 微信小程序 SDK 帮您在微信小程序中获取高德丰富的地址描述.POI和实时天气数据. 功能介绍 账号与Key的申请 注册成为高德开发者需要分三步: 第一步,注册高德开发者:第二步,去控制台创建应用:第三步,获取Key. 1注册高德开发者 2创建应用 3获取API key 获取API Key 入门指南 最后更新时间: 2017年1月9日 本指南是使用微信小程序SDK的快速入门指南. 第 1 步:下载并安装微信小程序开发工具 按照微信小程序开发文档下载并安装微信小

  • 微信小程序中进行地图导航功能的实现方法

    前段时间一直都在做小程序做了两个月了,其中对于小程序还是有很不理解的地方看着一些大企业的小程序自己模仿其实还是有一些难度的,我觉得学习小程序看一遍文档是不够的我们要做的是看别人的例子对着文档一一对照! 好这次我们来开始我们的开发,其实微信小程序里面是不能导航的,原因是小程序的代码最多只能有1M,他的运行内存只能有10M,一个区域地图下载下来就不止1M了所以在应用内我们无法做到导航的,但是应用外呢! 我问过很多做安卓和IOS的同僚一般如果导航这个功能不是很重要的话就会放到应用外来做这个功能,但是高

  • 微信小程序教程之本地图片上传(leancloud)实例详解

    微信小程序 leancloud --本地图片上传 由于本站最近学习微信小程序的知识,这里记录下微信小程序实现本地上传的功能实现方法,以下是网上找的资料,大家看下. 将本地图片上传至leancloud后台. 获取本地图片或者拍照,我在上一篇博文中写过.这里就不说了.我的博客 直接上代码: 1.index.js //index.js //获取应用实例 var app = getApp() const AV = require('../../utils/av-weapp.js'); Page({ da

随机推荐