微信小程序:位置API
目录
API介绍
首先我们看一下wx.getLocation函数
https://developers.weixin.qq.com/miniprogram/dev/api/location/wx.getLocation.html
作用
作用:获取当前的地理位置、速度。当用户离开小程序后,此接口无法调用。
开启高精度定位,接口耗时会增加,可指定 highAccuracyExpireTime 作为超时时间。地图相关使用的坐标格式应为 gcj02。高频率调用会导致耗电,如有需要可使用持续定位接口 wx.onLocationChange。基础库 2.17.0 版本起 wx.getLocation 增加调用频率限制
参数
Object object
gps:美国
gcj02:中国
object.success 回调函数
前置准备
登录
若想调用位置API,需要首先在创建app实例的时候调用登录接口: wx.login
. app.js:
// app.js App({ onLaunch() { // 展示本地存储能力 const logs = wx.getStorageSync('logs') || [] logs.unshift(Date.now()) wx.setStorageSync('logs', logs) // 登录 wx.login({ success: res => { // 发送 res.code 到后台换取 openId, sessionKey, unionId } }) }, globalData: { userInfo: null } })
简单测试
data
index.js:
data: { latitude: 0, longitude: 0, speed:0, accuracy:0 }
js
index.js:
注意:这里的var that = this 以及回调函数里的that.setData
回调函数中的this 和回调函数以外的this 不是一回事,所以这里用了一个that
geoInfo() { var that = this wx.getLocation({ type: 'gcj02', scale:18, success(res) { that.setData({ latitude: res.latitude, longitude: res.longitude, speed: res.speed, accuracy: res.accuracy, }) } }) console.log(this.data.latitude, this.data.longitude) },
WXML
<view class='top'> <button bindtap='geoInfo'>位置</button> </view>
WXSS
button{ margin:20rpx; }
效果图
点击开发者工具的‘真机调试'
手机上点击小程序的‘位置’按钮,
显示:
0 0 VM21:2 exparser SCL backend initialized index.js:43 0 0 index.js:43 36.69251736111111 117.01947916666667
位置API与地图结合
地图map组件
https://developers.weixin.qq.com/miniprogram/dev/component/map.html
wxml代码
<view class='top'> <button bindtap='geoInfo'>位置</button> </view> <map id='myMap' style="width:100%; height:350px" longitude='{{longitude}}' latitude='{{latitude}}' markers='{{markers}}' show-location > <view class='cover'> 经度:{{longitude}} 纬度:{{latitude}} 速度:{{speed}} </view> </map>
showlocation:显示带有方向的当前定位点
授权
https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/authorize.html
部分接口需要经过用户授权同意才能调用。我们把这些接口按使用范围分成多个 scope ,用户选择对 scope 来进行授权,当授权给一个 scope 之后,其对应的所有接口都可以直接使用。
此类接口调用时:
- 如果用户未接受或拒绝过此权限,会弹窗询问用户,用户点击同意后方可调用接口;
- 如果用户已授权,可以直接调用接口;
- 如果用户已拒绝授权,则不会出现弹窗,而是直接进入接口 fail 回调。请开发者兼容用户拒绝授权的场景
授权的全局设置
https://developers.weixin.qq.com/miniprogram/dev/reference/configuration/app.html
app.json:
"permission": { "scope.userLocation": { "desc": "你的位置信息将用于小程序位置接口的效果展示" } }
地图提示鉴权失败:2.12.2基础库以后就出现问题,会提示鉴权失败,基础库调到2.12.1之前就不会出现这个问题,能够正常使用
动态获得位置
wxml
添加如下代码:
<button bindtap='startRun'>开始</button> <button bindtap='stopRun'>结束</button>
data
data{ ... begin_la: 0, begin_lo: 0, ... }
js
定时器: https://developers.weixin.qq.com/miniprogram/dev/reference/api/setInterval.html
startRun(){ this.geoInfo() this.data.begin_la=this.data.latitude this.data.begin_lo = this.data. longitude }, stopRun(){ this.geoInfo() console.log('开始位置', this.data.begin_la, this.data.begin_lo) console.log('结束位置', this.data.latitude, this.data.longitude) console.log(this.data) }, running() { this.data.latitude += 0.0002 this.data.longitude += 0.0002 }, /** * 生命周期函数--监听页面加载 */ onLoad: function (options) { }, /** * 生命周期函数--监听页面初次渲染完成 */ onReady: function () { var interval = setInterval(O=>{this.running() },1000) },
控制台输出:
开始位置 36.654239999999994 117.12249000000008 index.js? [sm]:53 结束位置 36.65483999999999 117.1230900000001 index.js? [sm]:54 {demo_la: 48.1545, demo_lo: 82.3555907, latitude: 36.65483999999999, longitude: 117.1230900000001, begin_la: 36.654239999999994, …}
代码示例
index.js
Page({ /** * 页面的初始数据 */ data: { demo_la: 48.1545, demo_lo: 82.3555907, latitude: 0, longitude: 0, begin_la: 0, begin_lo: 0, interval: 0, speed: 0, accuracy: 0, markers: [{ iconPath: "../../imgs/pic.jpg", id: 0, latitude: 39.9205, longitude: 116.4605, width: 30, height: 30 }] }, openLoc() { this.mapCtx.includePoints({ padding: [10], points: [{ latitude: 23.10229, longitude: 113.3345211, }, { latitude: 23.00229, longitude: 113.3345211, }] }) }, geoInfo() { var that = this wx.getLocation({ type: 'gcj02', scale:18, success(res) { that.setData({ latitude: res.latitude, longitude: res.longitude, speed: res.speed, accuracy: res.accuracy, }) } }) console.log(this.data.latitude, this.data.longitude) }, startRun() { var that = this clearInterval(this.data.interval) wx.getLocation({ type: 'gcj02', success(res) { var la = res.latitude var lo = res.longitude that.setData({ begin_la: la, begin_lo: lo, 'markers[1]': { iconPath: "../../imgs/red.png", id: 1, latitude: la, longitude: lo, width: 20, height: 20 } }) } }) var interval = setInterval(() => { this.running() }, 1000) }, stopRun() { var that = this clearInterval(this.data.interval) wx.getLocation({ type: 'gcj02', success(res) { var la = res.latitude var lo = res.longitude that.setData({ latitude: la, longitude: lo, 'markers[2]': { iconPath: "../../imgs/yellow.png", id: 2, latitude: la, longitude: lo, width: 20, height: 20 } }) } }) console.log('开始位置', this.data.begin_la, this.data.begin_lo) console.log('结束位置', this.data.latitude, this.data.longitude) console.log(this.data) }, running() { this.data.latitude += 0.0002 this.data.longitude += 0.0002 }, center() { this.mapCtx.getCenterLocation({ success: function (res) { console.log(res.latitude,res.longitude) } }) }, trans() { this.mapCtx.translateMarker({ markerId: 0, autoRotate: false, duration: 3000, destination: { latitude: 40.30229, longitude: 116.7545211, }, animationEnd() { console.log('animation end') } }) }, onReady: function () { this.mapCtx = wx.createMapContext('myMap') }, })
//index.wxml <view class='top'>
<button bindtap='geoInfo'>位置</button> <button bindtap='openLoc'>打开</button> <button bindtap='center'>定心</button> <button bindtap='trans'>动</button>
</view>
index.wxml:
<map id='myMap' style="width:100%; height:350px" longitude='{{longitude}}' latitude='{{latitude}}' markers='{{markers}}' polyline="{{polyline}}" show-location subkey='IWLBZ-CK6R4-YXDUO-DQCXK-J5H4Z-DSBCI'> <cover-view calss='cover'> 经度:{{longitude}} 纬度:{{latitude}} 速度:{{speed}} </cover-view> </map> <button bindtap='startRun'>开始</button> <button bindtap='stopRun'>结束</button>
.