小编给大家分享一下微信小程序中如何使用地图,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!
通过阅读腾讯地图开放平台可以得知微信小程序可以下载SDK提供直接调用接口来使用腾讯地图,当然也可以自己对URL进行封装请求并返回自己的数据,本示例均使用了,因为SDK中封装时会调用某些接口,而在示例中会多时间内调用同一接口,那么就会造成频繁调用接口的错误。
过程中我也会用有赞团队的vant来展示学校信息,所以也需要提前安装好依赖备用,具体安装步骤见官网
首先就是在进入小程序时让用户给我们的小程序开启定位的权限,需要我们在app.json文件中添加以下代码:
"permission": { "scope.userLocation": { "desc": "你的位置信息将用于小程序位置接口的效果展示" } }
加上这一字段,当小程序用到定位系统时,发现小程序的权限没给到就会让用户将权限给到小程序,效果如下:
app.js
// 全局变量 globalData: { userInfo: null }, // 全局引入方法,简便引入第三方包 require: ($url)=> require($url)
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中的,这里为了方便演示就在前端做处理了。
手机要定位不仅需要微信权限开启,还有我们的手机也有一个定位系统权限也要开启,所以在正式开始定位前,为了用户的更好体验我们这一块功能我们通常还需要一系列的操作,这里我简单的用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没有对手机定位系统未开做处理,这个演示在这个方面的处理比较简单,仅仅是提示一下就没了,日常开发中一般会有其他的更好的处理方式,未开的效果如下:
经过上一步的处理我们已经已经确定了,手机的两个权限都给到了,那么我们开始处理地图选址页面的处理,开始之前先看看成品是什么样的,如下:
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); }
// 如果输入的是一个城市,就只会显示城市而不会显示学校 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) } }); } },
// 下滑到底生命周期函数 onReachBottom: function () { _this.data.pageIndex = ++_this.data.pageIndex; _this.data.count && _this.qqSearch(); },
对于提交数据这里就不多做处理了,选择的话就提示一下,在实际开发中一般都需要将数据存到数据库中另作他用。
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" }) } }) }
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(){ } }) }
以上是“微信小程序中如何使用地图”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注亿速云行业资讯频道!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。