作者: 做个文艺程序员
发布时间: 已于 2026-05-09 14:08:12 修改
来源: https://blog.csdn.net/qq_23625847/article/details/160880841
在移动互联网时代,位置服务(LBS)早已渗透到我们日常使用的每一款 App 中——外卖平台的实时配送轨迹、共享单车的就近找车、社交 App 的附近推荐……这些功能背后,都离不开一套稳定、高精度的地理位置能力支撑。
腾讯位置服务日均全球定位请求超过1800 亿次,覆盖用户超过10 亿,全球覆盖 200+ 国家和地区,是国内开发者接入 LBS 能力的主流选择之一。
本文将以一个**"周边美食探索"微信小程序为实战案例,手把手带你走完腾讯位置服务从注册 → 申请 Key → SDK 接入 → 核心 API 调用 → 上线避坑**的完整链路,配合真实代码,让你看完就能上手。
在动手写代码之前,先对腾讯位置服务的能力矩阵有一个整体认知,方便你根据业务场景做技术选型。
对于微信小程序开发者,官方提供了专属的JavaScript SDK,可以直接在小程序中调用 POI 检索、地址解析、逆地址解析等服务,极大降低了接入成本。
Tips:企业认证后,API 配额显著高于个人开发者,建议商业项目提前申请。
Key 示例:XXXXX-XXXXX-XXXXX-XXXXX-XXXXX-XXXXX(32位字符串)
在微信公众平台 → 开发 → 开发设置 → 服务器域名中,添加以下合法域名:
request 合法域名:
https://apis.map.qq.com
从腾讯位置服务官网下载微信小程序 JavaScript SDK(qqmap-wx-jssdk.js),放入项目目录,例如/utils/qqmap-wx-jssdk.js。
在需要使用地图服务的页面,引入并初始化:
// utils/mapService.js
const QQMapWX = require('./qqmap-wx-jssdk.js');
const qqmapsdk = new QQMapWX({
key: 'YOUR_KEY_HERE' // 替换为你申请的 Key
});
module.exports = qqmapsdk;
本案例实现以下核心功能:
<!-- pages/nearby/nearby.wxml -->
<view class="container">
<!-- 顶部位置信息 -->
<view class="location-bar">
<image class="loc-icon" src="/images/location.png"/>
<text class="loc-text">{{currentAddress}}</text>
<text class="refresh-btn" bindtap="refreshLocation">刷新</text>
</view>
<!-- 地图组件 -->
<map
id="map"
longitude="{{longitude}}"
latitude="{{latitude}}"
scale="15"
markers="{{markers}}"
show-location="true"
class="map-container"
/>
<!-- 餐厅列表 -->
<scroll-view scroll-y class="restaurant-list">
<view
class="restaurant-item"
wx:for="{{restaurants}}"
wx:key="id"
bindtap="onRestaurantTap"
data-item="{{item}}"
>
<view class="restaurant-name">{{item.title}}</view>
<view class="restaurant-address">{{item.address}}</view>
<view class="restaurant-distance">距你 {{item._distance}}m</view>
</view>
</scroll-view>
</view>
// pages/nearby/nearby.js
const qqmapsdk = require('../../utils/mapService.js');
Page({
data: {
latitude: 39.9042, // 默认坐标(北京)
longitude: 116.4074,
currentAddress: '定位中...',
restaurants: [],
markers: []
},
onLoad() {
this.getUserLocation();
},
// ① 获取用户当前位置
getUserLocation() {
wx.getLocation({
type: 'gcj02', // 腾讯/高德使用 gcj02 坐标系
success: (res) => {
const { latitude, longitude } = res;
this.setData({ latitude, longitude });
// 获取位置后,同步执行逆地址解析和 POI 搜索
this.reverseGeocoder(latitude, longitude);
this.searchNearbyRestaurants(latitude, longitude);
},
fail: () => {
wx.showToast({ title: '定位失败,请检查权限', icon: 'none' });
}
});
},
// ② 逆地址解析:坐标 → 可读地址
reverseGeocoder(lat, lng) {
qqmapsdk.reverseGeocoder({
location: { latitude: lat, longitude: lng },
success: (res) => {
const address = res.result.address;
this.setData({ currentAddress: address });
},
fail: (err) => {
console.error('逆地址解析失败:', err);
}
});
},
// ③ 周边 POI 搜索:搜索附近餐厅
searchNearbyRestaurants(lat, lng) {
wx.showLoading({ title: '搜索中...' });
qqmapsdk.search({
keyword: '餐厅', // 搜索关键词
location: { latitude: lat, longitude: lng },
distance: 1000, // 搜索半径:1000m
page_size: 20, // 每页数量
success: (res) => {
wx.hideLoading();
const pois = res.data || [];
// 构建地图标注 markers
const markers = pois.map((poi, index) => ({
id: index,
latitude: poi.location.lat,
longitude: poi.location.lng,
title: poi.title,
iconPath: '/images/restaurant-pin.png',
width: 32,
height: 40,
callout: {
content: poi.title,
display: 'BYCLICK',
padding: 6,
borderRadius: 4,
fontSize: 12
}
}));
this.setData({
restaurants: pois,
markers
});
},
fail: (err) => {
wx.hideLoading();
console.error('POI 搜索失败:', err);
}
});
},
// ④ 点击餐厅:规划步行路线
onRestaurantTap(e) {
const { item } = e.currentTarget.dataset;
const { latitude: fromLat, longitude: fromLng } = this.data;
qqmapsdk.direction({
mode: 'walking', // 步行模式
from: { latitude: fromLat, longitude: fromLng },
to: {
latitude: item.location.lat,
longitude: item.location.lng
},
success: (res) => {
const route = res.result.routes[0];
wx.showModal({
title: `步行至 ${item.title}`,
content: `距离约 ${route.distance}m,预计步行 ${Math.ceil(route.duration / 60)} 分钟`,
showCancel: false
});
}
});
},
// 刷新定位
refreshLocation() {
this.getUserLocation();
}
});
/* pages/nearby/nearby.wxss */
.container {
display: flex;
flex-direction: column;
height: 100vh;
}
.location-bar {
display: flex;
align-items: center;
padding: 12rpx 24rpx;
background: #fff;
border-bottom: 1rpx solid #f0f0f0;
}
.loc-icon { width: 32rpx; height: 32rpx; margin-right: 10rpx; }
.loc-text { flex: 1; font-size: 28rpx; color: #333; }
.refresh-btn { font-size: 26rpx; color: #07C160; }
.map-container {
width: 100%;
height: 500rpx;
}
.restaurant-list {
flex: 1;
background: #f8f8f8;
}
.restaurant-item {
background: #fff;
padding: 24rpx;
margin-bottom: 2rpx;
border-left: 6rpx solid #07C160;
}
.restaurant-name { font-size: 32rpx; font-weight: bold; color: #222; }
.restaurant-address { font-size: 26rpx; color: #888; margin-top: 6rpx; }
.restaurant-distance { font-size: 24rpx; color: #07C160; margin-top: 6rpx; }
在搜索框中实时展示地点联想,是提升用户体验的利器,腾讯 SDK 提供了getSuggestions接口:
// 实时搜索建议
onSearchInput(e) {
const keyword = e.detail.value;
if (!keyword) {
this.setData({ suggestions: [] });
return;
}
qqmapsdk.getSuggestions({
keyword,
region: '北京', // 限定城市范围,提高精准度
region_fix: 0, // 0=允许跨城市搜索
location: {
latitude: this.data.latitude,
longitude: this.data.longitude
},
success: (res) => {
this.setData({ suggestions: res.data });
}
});
},
原因:未在微信公众平台配置合法域名。
解决:登录微信公众平台 → 开发设置 → 添加https://apis.map.qq.com到 request 合法域名。
原因:Key 未开通 WebService API 权限,或未绑定对应小程序 AppID。 解决:进入腾讯位置服务控制台 → Key 管理 → 编辑 → 勾选 WebService API → 填写 AppID 保存。
原因:坐标系不一致。国内地图使用 GCJ-02(火星坐标),GPS 原始数据为 WGS-84。
解决:wx.getLocation调用时指定type: 'gcj02',腾讯地图原生支持 GCJ-02,无需额外转换。
原因:个人开发者每日 API 调用次数有限制。 解决方案:
本文通过"周边美食探索"这一完整案例,覆盖了腾讯位置服务在微信小程序中的核心使用链路:
腾讯位置服务凭借日均 1800 亿次定位请求的基础设施、与微信生态的深度整合、以及丰富的行业解决方案,是微信小程序 LBS 开发的不二之选。无论你是正在做外卖、社交、物流还是本地生活类产品,这套能力都能帮你快速构建扎实的位置服务底座。
欢迎在评论区交流你的接入经验,也欢迎 Star 本文的示例项目!
作者:[做个文艺的程序员]本文参与【腾讯位置服务 × CSDN 开发者征文大赛】