地图的运用是小程序中不可缺少的一部分,这里主要是利用了小程序提供的腾讯地图展示接口和定位接口进行实现的,可以去网页中搜索腾讯地图API,会有相关的文档提供
以下有以下知识点:
- 需获取微信地址授权
- 需得到经纬度信息进行逆地址解析
- 封装
- 解构
- promise封装
- async和await
在写程序之前,小程序需要获得用户的定位授权,详细可见微信公众平台的文档
在全局环境app.json中插入代码
"permission": {
"scope.userLocation": {
"desc": "你的位置信息将用于小程序位置接口的效果展示"
}
}
保存后点击按钮会出现是否授权的页面,点击确定
下面是页面:
<!--pages/home/home.wxml-->
<view>
<button bindtap="getAddress">获取位置</button>
</view>
<view>
<!-- 显示变量位置信息,从data中获取 -->
{{location}}
</view>
下面是提取当前位置的程序,微信中有一个API是获取位置信息的:wx.getLocation,可以得到当前位置的经纬度latitude和longitude
wx.getLocation({
success: function(res) {
console.log(res)
},
})
根据获取到的经纬度转化为地理位置,我用的是腾讯地图,可以去查腾讯地图API的文档,查看逆地址解析,可以将经纬度转为具体位置,需要注册获得key。
获取地址的代码如下:
wx.request({
url: 'https://apis.map.qq.com/ws/geocoder/v1/',
//data是该请求需要的数据,如文档,location和key是必须的
data:{
location: [res.latitude, res.longitude].join(','),
key: 你的key注意是字符串,
},
success: (res) => {
this.setData({
location: res.data.result.address
})
}
})
将两个代码结合,因为经纬度信息是请求需要的数据,所以请求需要写在wx.getLocation里面,如下:
getAddress() {
wx.getLocation({
type: 'bd09',
success: (res)=> {
console.log([res.latitude, res.longitude].join(','))
wx.request({
url: 'https://apis.map.qq.com/ws/geocoder/v1/',
// data是该请求需要的数据,如文档,location和key是必须的
data:{
location: [res.latitude, res.longitude].join(','),
key: 你的key注意是字符串,
},
success: (res) => {
this.setData({
location: res.data.result.address
})
}
})
},
})
},
成功,点击获取位置按钮将会在下面出现地址,如下图;
下面将代码封装,使代码看起来更简洁
将涉及到this的代码保留,作为回调函数(如果封装遇到this,需要将此代码作为回调函数,否则会报错)
封装的函数都放在统一的文件夹中,这样可以让其他页面都方便调用
//export将函数暴露出去,以便其他页面调用
export function getMyAddress(callback){
wx.getLocation({
type: 'bd09',
success: (res) => {
wx.request({
url: 'https://apis.map.qq.com/ws/geocoder/v1/',
// data是该请求需要的数据,如文档,location和key是必须的
data: {
location: [res.latitude, res.longitude].join(','),
key:你的key注意是字符串,
},
success: ({data}) => {
//callback中的变量将传递出去,因为每次需要的数据都在res.data.result中,所以可以将res.data.result传出去,再运用解构
callback(data.result)
}
})
},
})
}
调用此函数:
import {
getMyAddress
} from '../../utils/fun.js'
在函数getAddress中调用
getAddress() {
getMyAddress(res => {
this.setData({
location: res.address
})
})
}
用promise将代码再次封装,promise函数需要有返回值,promise的优势是解决回调地狱的问题,使代码看起来更简洁
export function getMyAddress() {
//返回值以便后期调用,因为成功失败出来的是resolve, rejected结果,所以就不需要回调函数传参
return new Promise((resolve, rejected) => {
wx.getLocation({
type: 'bd09',
success: (res) => {
wx.request({
url: 'https://apis.map.qq.com/ws/geocoder/v1/',
data: {
location: [res.latitude, res.longitude].join(','),
key: 你的key注意是字符串,
},
//成功执行resolve
success: ({
data
}) => {
resolve(data.result)
},
//失败执行reject
fail:(res)=>{
rejected(res)
}
})
},
})
})
}
调用此函数,用then来进行下一步动作
getAddress() {
getMyAddress().then(res=>{
this.setData({
location: res.address
})
})
},
调用函数时可以用async调用,用async和await,这个方法对异步的处理是一个优势,当await处理完后面的代码才会执行,重点:await必须放在async里面
async getAddress() {
let res = await getMyAddress()
//当await执行完毕,进行下一步操作
this.setData({
location: res.address
})
},
到此,对promise,async和await差不多了解了,将代码再封装下,ajax的封装已经完成,
下面将wx.getLocation封装下,获取经纬度信息:
export function getLocation() {
return new Promise((resolve, reject) => {
wx.getLocation({
type: 'bd09',
success: ({
longitude: lng,
latitude: lat
}) => {
resolve({
lat,
lng
})
},
})
})
}
调用此函数可以获得当前位置的经纬度
async getAddress() {
let { lat, lng } = await getLocation()
console.log(lat,lng)
},
封装一个函数,当传入经纬度时获取当前的位置,思路:将当前的经纬度传入$get函数,将得到的结果解构得到result,return出去
export function getMyAddress({
lat,
lng
}) {
return new Promise(async(resolve, rejected) => {
let {
result
} = await $get(TENCENTMAPURL, {
location: [lat, lng].join(','),
key: TENCENTMAPKEY
})
resolve(result)
})
}
点击时通过getAddress获取经纬度信息,在传递给getMyAddress获得的对象中的属性名中的address值(百度地图是formatted_address)
import {
$get,
getMyAddress,
getLocation
} from '../../utils/fun.js'
import {
TENCENTMAPURL,
TENCENTMAPKEY,
} from '../../utils/const.js'
//点击按钮触发,下面的函数是写在page里面的
async getAddress() {
let { lat, lng } = await getLocation()
let res = await getMyAddress({ lat, lng })
this.setData({
location: res.address
})
}
最后再来一个输入经纬度提取中文地址的方法,与上面类似,运用地图的地址解析
export function getMyAddressNum(address) {
return new Promise(async(res, rej) => {
let {
result
} = await $get(TENCENTMAPURL, {
address,
key: TENCENTMAPKEY
})
res(result)
})
}