uni-app 实现市级定位
uni-app 实现市级定位
一、实现思路
获取当前定位所在城市的实现思路:
- 通过 API 获取当前定位的经纬度
- 通过高德/百度/腾讯等地图服务提供的地址逆解析服务接口解析经纬度所在城市
二、实现代码
<template>
<view class=""> </view>
</template>
<script>
export default {
data() {
return {};
},
onLoad(option) {
const self = this;
self.getLocation();
},
methods: {
async getLocation() {
const self = this;
const { latitude, longitude } = await self.getLocationByUniAPI();
// // #ifdef H5
// const { latitude, longitude } = await self.getLocationByGeoAPI();
// // #endif
// // #ifdef MP-WEIXIN
// const { latitude, longitude } = await self.getLocationByWxAPI();
// // #endif
const resp = await self.getAddressInfo(latitude, longitude);
const city = await self.getCityFromAddressInfo(resp);
},
// 通过 uni-app API 获取经纬度定位(该方法兼容性高)
getLocationByUniAPI() {
return new Promise((resolve, reject) => {
uni.getLocation({
type: "wgs84",
success: function (res) {
resolve({
longitude: res.longitude,
latitude: res.latitude,
});
},
fail(res) {
reject(res);
},
});
});
},
// 通过浏览器 Geolocation API 获取经纬度定位
getLocationByGeoAPI() {
return new Promise((resolve, reject) => {
// 检查浏览器是否支持 Geolocation API
if (window && window.navigator && window.navigator.geolocation) {
// 获取设备位置信息
navigator.geolocation.getCurrentPosition(
function (position) {
// 获取经度和纬度
var latitude = position.coords.latitude;
var longitude = position.coords.longitude;
resolve({
longitude: longitude,
latitude: latitude,
});
},
function (error) {
// 处理获取位置信息失败的情况
reject("Failed to get location: " + error.message);
}
);
} else {
reject("Geolocation is not supported by this browser.");
}
});
},
// 通过微信小程序 API 获取经纬度定位
getLocationByWxAPI() {
// 开放能力 /用户信息 /授权
// https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/authorize.html
return new Promise((resolve, reject) => {
if (wx && wx.getSetting) {
wx.getSetting({
success: function (res) {
if (!res.authSetting["scope.userLocation"]) {
wx.authorize({
scope: "scope.userLocation",
success() {
// 用户已经同意小程序获取地理位置信息
wx.getLocation({
type: "wgs84",
success(lRes) {
resolve({
longitude: lRes.longitude,
latitude: lRes.latitude,
});
},
fail() {
reject("获取定位失败");
},
});
},
fail() {
// 用户拒绝授权,需要提示用户进行授权
reject("获取定位权限失败");
},
});
} else {
wx.getLocation({
type: "wgs84",
success(lRes) {
resolve({
longitude: lRes.longitude,
latitude: lRes.latitude,
});
},
fail() {
reject("获取定位失败");
},
});
}
},
fail() {
reject("获取用户的当前设置失败");
},
});
} else {
reject("不支持微信小程序 API");
}
});
},
// 通过高德的逆地理解析接口解析经纬度所在地址
getAddressInfo(latitude, longitude) {
return new Promise((resolve, reject) => {
uni.request({
// 要使用该接口,在应用配置时,服务平台需要选择Web服务
// 接口说明:https://lbs.amap.com/api/webservice/guide/api/georegeo#regeo
url: `https://restapi.amap.com/v3/geocode/regeo?location=${longitude},${latitude}&key=<your key>`,
success: function (res) {
resolve(res.data);
},
fail: function (res) {
console.log(res);
reject("逆地址解析失败");
},
});
});
},
// 从地址信息中获取所在城市
getCityFromAddressInfo(addressInfo) {
let retCity = "";
if (addressInfo.status === "1") {
const addressComponent = addressInfo.regeocode.addressComponent;
if (Array.isArray(addressComponent.city)) {
if (addressComponent.citycode.length === 3) {
// citycode 为3位时,直辖市,取省份字段
retCity = addressComponent.province;
} else {
// 省直辖县列表:https://lbs.amap.com/faq/webservice/webservice-api/geocoding/43267
// citycode 为4位时,省直辖县,取地区字段
retCity = addressComponent.district;
}
} else {
retCity = addressComponent.city;
}
} else {
uni.showToast({
title: "逆地址解析失败",
icon: "none",
duration: 3000,
});
}
return retCity;
},
},
};
</script>
<style scoped></style>
上述代码在 H5 和微信小程序上测试成功。
注意:
-
通过 uni-app API 获取经纬度定位的方法
getLocationByUniAPI
实现在 H5 上定位时,如需增加IP 定位的备选方案,可增加如下配置:经测试,选择使用高德地图,并配置 key 和 securityJsCode,定位失败。
-
此外,在实现通过微信小程序 API 获取经纬度定位方法
getLocationByWxAPI
时,需要配置manifest.json
文件:{ /* 小程序特有相关 */ "mp-weixin": { "permission": { "scope.userLocation": { "desc": "小程序需要您的地理位置信息", "warn": "请确认授权,否则无法使用地图功能", "tips": "授权后,我们将使用您的地理位置信息进行定位" } }, "requiredPrivateInfos": ["getLocation"] } }
三、uni.getLocation
注事事项
H5 平台
- 在较新的浏览器上,H5 端获取定位信息,要求部署在 https 服务上,本地预览(localhost)仍然可以使用 http 协议。
- 国产安卓手机上,H5 若无法定位,检查手机是否开通位置服务、GPS,ROM 是否给该浏览器位置权限、浏览器是否对网页弹出请求给予定位的询问框。
- 安卓手机 在原生 App 内嵌 H5 时,无法定位需要原生 App 处理 Webview。
- 移动端浏览器 普遍仅支持 GPS 定位,在 GPS 信号弱的地方可能定位失败。
- PC 设备 使用 Chrome 浏览器的时候,位置信息是连接谷歌服务器获取的,国内用户可能获取位置信息失败。
- 微信公众号可使用微信 js sdk,详见
- 2.9.9 版本以上,优化 uni.getLocation 支持通过 IP 定位。默认通过 GPS 获取,如果获取失败,备选方案是通过 IP 定位获取,需填写三方地图服务平台的秘钥(key)。key 配置:manifest.json ---> H5 配置 ---> 定位和地图 ---> key。
小程序平台
- api 默认不返回详细地址中文描述。需要中文地址有 2 种方式:
- 1、使用高德地图小程序 sdk,在 app 和微信上都可以获得中文地址,参考。
- 2、只考虑 app,使用 plus.geolocation 也可以获取中文地址。manifest 里的 App SDK 配置仅用于 app,小程序无需在这里配置。
- 可以通过用户授权 API 来判断用户是否给应用授予定位权限,详见
- 在 微信小程序 中,当用户离开应用后,此接口无法调用,需要申请 后台持续定位权限,另外新版本中需要使用 wx.onLocationChange 监听位置信息变化;当用户点击“显示在聊天顶部”时,此接口可继续调用。