背景:本人最近在開發一款天氣預報的微信小程式,在調用騰訊地圖API進行逆位址解析擷取詳細地名時,發現其官方文檔的描述模棱兩可、網絡上也沒有搜到确實可行的方法。在經過對官方文檔的逐句翻譯和數次嘗試之後,終于成功的擷取到了地理位置和地名。特做此記錄,以備不時之需。
一、微信小程式擷取地理位置和詳細地名的思路
1、使用微信小程式
wx.getLocation
API方法擷取使用者目前位置的經緯度,這個步驟比較簡單
2、使用拿到的經緯度請求地圖位置服務的逆位址解析接口,擷取省市縣和詳細位址。這是最關鍵的步驟,也是騰訊地圖API官網沒有寫清楚的一步
二、微信小程式擷取地理位置和詳細地名的思路
1、擷取使用者目前位置經緯度
小程式使用
wx.getLocation
方法擷取使用者的目前位置經緯度。
wx.getLocation
預設擷取的是
wgs84
坐标系,即 GPS 的坐标系,而國内地圖(除百度地圖外)一般用的都是
GCJ02
(國測局坐标,又稱為“火星坐标系”)的坐标系,是以需要傳入
type
來指定坐标系統。
// 微信api,擷取經緯度
getLocation() {
wx.getLocation({
type: 'gcj02',
success: this.updateLocation,
fail: (e)=> {
this.openLocation()
}
})
}
2、根據經緯度擷取目前位置
需要在騰訊地圖開放平台新增賬號,在
控制台 → key與配額 → key管理
中建立密鑰,建立密鑰後才能使用地圖SDK及WebService API等産品與服務。
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsICM38FdsYkRGZkRG9lcvx2bjxiNx8VZ6l2cs0TPn1kMFR0TykFROBDOsJGcohVYsR2MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnL2ITM0ADNxIjM1EzMwkTMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
在小程式裡調用騰訊地圖API的方式有主要兩種:
- 騰訊地圖提供的微信小程式JavaScript SDK
- WebService API,即直接發送請求,調用API接口
這裡我選擇了WebService API,原因如下:
- 小程式 SDK 和 WebService API 都很友善,不需要加密資料,密鑰都是對外暴露的
- WebService API 使用微信
方法可以直接發送請求,對代碼無侵入性wx.request
- 小程式 SDK 本質上還是用
封裝的 WebService APIwx.request
根據WebService API的相關說明頁面,需要傳入密鑰、location(latitude和longitude結合)、簽名計算sig資訊。
2.1、擷取簽名計算sig資訊
擷取簽名計算sig資訊需要進行
md5
計算,此處我選用GitHub上star數量最多的JavaScript語言的md5倉庫,下載下傳了其中的js檔案,複制到微信小程式的
utils
目錄下:
在需要擷取地理位置和地名資訊的page中,引入用于md5計算的庫:
// pages/index/index.js
import md5 from '../../utils/md5.js'
// 擷取應用執行個體
// ……
在本微信小程式中使用
JavaScript-MD5
庫時,直接調用
md5(value)
方法,其中value是
String
類型
2.2、完整的地理位置擷取流程
貼出完整的擷取地理位置和地名的代碼。如果需要擷取此地理位置的其他相關資訊,請檢視騰訊地圖開放平台的逆位址解析API文檔
//pages/index/index.js
// QQMapKey是在騰訊地圖開放平台設定的密鑰
// 請使用你自己的密鑰
const QQMapKey = 'NILBZ-BOIHP-SOOD3-LTPVO-ITVWK-*****';
// 在密鑰設定中開啟WebServiceAPI,選擇簽名校驗,即可擷取Secret key,即SK
// 請使用你自己的SK
const SK = '25rlrIUFfYbJkN54yqB7IX4sR*****';
// 引入MD5庫
import md5 from '../../utils/md5.js';
//擷取應用執行個體
const app = getApp()
Page({
data: {
lat: 40.056974,
lon: 116.307689,
address: '定位中'
},
onLoad() {
this.getLocation()
},
// 根據經緯度,逆位址解析
getAddress(lat, lon) {
// 在wx.request中,this指向wx.request,故無法setData,此處将this指向that
var that = this
wx.showLoading({
title: '定位中',
mask: true,
duration: 3000
})
let SIG = md5("/ws/geocoder/v1?key=" + QQMapKey +"&location="+String(lat)+","+String(lon)+SK)
wx.request({
url: 'https://apis.map.qq.com/ws/geocoder/v1',
data: {
key: QQMapKey,
location: `${lat},${lon}`,
sig: SIG
},
success(res) {
let result = res.data.result
// console.log(result)
// formatted_addresses.recommend是經過騰訊地圖優化過的描述方式,更具人性化特點
let formatted_addresses = result.formatted_addresses.recommend
// 此處的that指向app
that.setData({
address: formatted_addresses
})
wx.hideLoading()
},
fail:(e) => {
console.log(e)
wx.hideLoading()
}
})
},
// 根據經緯度,設定資料
updateLocation(res) {
let {latitude: lat, longitude: lon} = res
let data = {
lat,
lon
}
this.setData(data)
this.getAddress(lat, lon)
},
// 微信api,擷取經緯度
getLocation() {
wx.getLocation({
type: 'gcj02',
success: this.updateLocation,
fail: (e)=> {
console.log(e)
}
})
}
})