5分钟搞定uniapp小程序地图功能:wx.chooseLocation选点+wx.getLocation实时定位全流程
5分钟实现UniApp小程序地图功能:从定位到选点全流程实战
第一次接触UniApp开发微信小程序时,最让我头疼的就是地图功能的实现。记得当时为了赶项目进度,我翻遍了各种文档和教程,却始终找不到一个完整、清晰的解决方案。直到后来经过多次实践,才总结出这套高效的地图功能实现方案。今天,我将分享如何在5分钟内完成从用户定位到位置选择的完整流程,帮助你快速实现这一常见但关键的功能需求。
1. 基础配置与环境准备
在开始编码前,我们需要确保开发环境和小程序配置正确。这就像盖房子前要打好地基一样重要。首先,确保你已经安装了最新版的HBuilder X和微信开发者工具。这两个工具是我们开发UniApp微信小程序的必备利器。
1.1 权限配置
微信小程序对用户位置信息有严格的权限控制,我们需要在manifest.json中进行正确配置。打开项目中的manifest.json文件,找到"微信小程序配置"部分,添加以下代码:
"mp-weixin": {
"permission": {
"scope.userLocation": {
"desc": "需要获取您的位置信息以便提供更好的服务"
}
},
"requiredPrivateInfos": [
"getLocation",
"chooseLocation"
]
}
注意:desc字段的内容会直接展示给用户,建议写得清晰友好,提高用户授权率。
1.2 腾讯地图SDK准备
为了实现逆地理编码(将经纬度转换为具体地址),我们需要使用腾讯地图的SDK。在项目根目录的index.html文件中添加以下代码:
<script src="https://map.qq.com/api/gljs?v=1.exp&key=您申请的腾讯地图KEY"></script>
申请腾讯地图KEY的步骤很简单:
- 访问腾讯位置服务官网
- 注册开发者账号
- 创建应用并获取KEY
- 将KEY替换到上面的URL中
2. 获取用户当前位置
获取用户当前位置是地图功能的基础,微信小程序提供了wx.getLocation API来实现这一功能。让我们看看如何优雅地调用它。
2.1 基本定位实现
在页面或组件中,我们可以这样实现定位功能:
methods: {
getCurrentLocation() {
const that = this
wx.getLocation({
type: 'wgs84',
success(res) {
console.log('定位成功:', res)
that.latitude = res.latitude
that.longitude = res.longitude
that.getAddressByCoordinates(res.latitude, res.longitude)
},
fail(err) {
console.error('定位失败:', err)
uni.showToast({
title: '获取位置失败',
icon: 'none'
})
}
})
}
}
参数说明:
type: 指定返回的坐标类型,'wgs84'是国际通用的GPS坐标success: 定位成功回调,返回包含latitude和longitude的对象fail: 定位失败回调,需要做好错误处理
2.2 错误处理与用户体验优化
在实际开发中,我们需要考虑各种边界情况:
getCurrentLocation() {
// 检查是否已授权
wx.getSetting({
success(res) {
if (!res.authSetting['scope.userLocation']) {
// 未授权,引导用户授权
wx.authorize({
scope: 'scope.userLocation',
success() {
// 授权成功,执行定位
this._doGetLocation()
},
fail() {
// 授权被拒绝,提示用户
uni.showModal({
title: '提示',
content: '需要位置权限才能使用此功能',
confirmText: '去设置',
success(res) {
if (res.confirm) {
wx.openSetting()
}
}
})
}
})
} else {
// 已授权,直接执行定位
this._doGetLocation()
}
}
})
}
这种渐进式的授权策略能显著提高用户体验和功能可用性。
3. 实现位置选择功能
除了获取当前位置,让用户在地图上选择特定位置也是常见需求。wx.chooseLocation API完美解决了这个问题。
3.1 基本选点实现
methods: {
chooseLocation() {
const that = this
wx.chooseLocation({
latitude: this.latitude, // 默认中心点纬度
longitude: this.longitude, // 默认中心点经度
success(res) {
console.log('位置选择成功:', res)
that.selectedLatitude = res.latitude
that.selectedLongitude = res.longitude
that.selectedAddress = res.name + ' ' + res.address
},
fail(err) {
console.error('位置选择失败:', err)
}
})
}
}
关键参数解析:
latitude/longitude: 设置地图初始中心点坐标success回调返回对象包含:- name: 位置名称
- address: 详细地址
- latitude/longitude: 坐标
3.2 选点功能增强实践
在实际项目中,我们通常需要将选中的位置在地图上标记出来。这里分享一个实用的标记方案:
// 在chooseLocation的success回调中添加
that.markers = [{
id: 1,
latitude: res.latitude,
longitude: res.longitude,
title: res.name,
iconPath: '/static/location-marker.png',
width: 30,
height: 30,
callout: {
content: res.name,
color: '#333',
fontSize: 14,
borderRadius: 5,
padding: 5,
display: 'ALWAYS'
}
}]
技巧:使用高质量的标记图标(custom iconPath)能显著提升用户体验。建议图标尺寸为30-50px,透明背景PNG格式最佳。
4. 高级功能:逆地理编码与坐标转换
单纯的经纬度对用户来说没有意义,我们需要将其转换为可读的地址信息。这就是逆地理编码的作用。
4.1 使用腾讯地图实现逆地理编码
methods: {
getAddressByCoordinates(lat, lng) {
const qqMap = new qq.maps.Geocoder({
complete: (res) => {
if (res.status === 0) {
this.address = res.result.address
this.formattedAddress = this._formatAddress(res.result)
} else {
console.error('逆地理编码失败:', res)
}
}
})
qqMap.getAddress({
location: new qq.maps.LatLng(lat, lng)
})
},
_formatAddress(result) {
// 结构化地址信息
let address = result.address
if (result.address_component) {
const comp = result.address_component
address = `${comp.province}${comp.city}${comp.district}${comp.street}${comp.street_number}`
}
return address
}
}
地址信息处理技巧:
- 优先使用address_component中的结构化数据
- 对直辖市等特殊情况做兼容处理
- 考虑添加缓存机制减少API调用
4.2 坐标转换与纠偏
不同地图服务可能使用不同的坐标体系,我们需要了解常见的三种:
- WGS-84: GPS原始坐标,国际标准
- GCJ-02: 国测局坐标,中国标准
- BD-09: 百度坐标,百度地图专用
微信小程序返回的是WGS-84坐标,而腾讯地图使用的是GCJ-02坐标。如果发现位置偏移,可能需要坐标转换:
// WGS-84转GCJ-02
function wgs84ToGcj02(wgsLat, wgsLng) {
if (outOfChina(wgsLat, wgsLng)) {
return [wgsLat, wgsLng]
}
const a = 6378245.0
const ee = 0.00669342162296594323
let dLat = transformLat(wgsLng - 105.0, wgsLat - 35.0)
let dLng = transformLng(wgsLng - 105.0, wgsLat - 35.0)
const radLat = wgsLat / 180.0 * Math.PI
let magic = Math.sin(radLat)
magic = 1 - ee * magic * magic
const sqrtMagic = Math.sqrt(magic)
dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * Math.PI)
dLng = (dLng * 180.0) / (a / sqrtMagic * Math.cos(radLat) * Math.PI)
return [wgsLat + dLat, wgsLng + dLng]
}
注意:实际项目中建议使用成熟的第三方库处理坐标转换,如coordtransform。
5. 性能优化与最佳实践
在多个项目中实现地图功能后,我总结出以下提升性能和用户体验的关键点。
5.1 定位频率控制
频繁调用定位API会导致性能问题和电量消耗。推荐策略:
- 缓存机制:短期(5分钟内)重复定位直接使用缓存
- 节流处理:滚动等高频场景下限制定位频率
- 精度选择:根据场景选择合适的定位精度
data() {
return {
lastLocation: null,
lastLocationTime: 0
}
},
methods: {
getLocationWithCache() {
const now = Date.now()
if (this.lastLocation && now - this.lastLocationTime < 5 * 60 * 1000) {
return Promise.resolve(this.lastLocation)
}
return new Promise((resolve, reject) => {
wx.getLocation({
type: 'wgs84',
success: (res) => {
this.lastLocation = res
this.lastLocationTime = now
resolve(res)
},
fail: reject
})
})
}
}
5.2 地图组件优化技巧
使用微信小程序原生map组件时,这些技巧能提升性能:
- 合理设置scale:根据业务需求设置合适的地图缩放级别
- 优化markers:控制marker数量,合并相近点
- 使用include-points:自动计算最佳视野区域
- 懒加载:非可视区域的地图延迟初始化
<map
id="myMap"
style="width: 100%; height: 300px;"
:latitude="latitude"
:longitude="longitude"
:scale="14"
:markers="markers"
:include-points="markers"
@regionchange="onRegionChange"
show-location
></map>
5.3 错误监控与降级方案
建立完善的错误监控体系非常重要:
- 关键API监控:记录getLocation/chooseLocation的成功失败率
- 用户授权统计:分析用户授权拒绝原因
- 降级方案:
- 定位失败时提供手动输入地址
- 逆地理编码失败时显示经纬度
- 地图加载失败显示静态地图截图
// 错误监控示例
wx.getLocation({
type: 'wgs84',
success(res) {
// 业务代码
this._trackApiSuccess('getLocation')
},
fail(err) {
this._trackApiError('getLocation', err)
this.showAddressInput = true // 降级方案
}
})
实现UniApp小程序地图功能看似简单,但要把体验做到极致需要关注很多细节。从权限处理到错误降级,从性能优化到用户体验,每个环节都值得深入打磨。在实际项目中,我通常会建立一个地图工具类,将这些最佳实践封装起来,方便团队复用。
更多推荐

所有评论(0)