uniapp h5获取经纬度 (坑点)
开发uniapp h5时,涉及到获取经纬度需求,起初在浏览器调试,获取经纬度失败,但是可以正常在手机上获取,只获取经纬度就没必要去用第三方sdk
封装通用js amap-locationCur-web.js
/**
* 通用地理位置获取工具(支持 H5、小程序、App)
* 返回:经纬度 + 地址信息(国家、省、市、区、街道)
*
* 使用方式:
* import Location from '@/utils/location.js';
* const res = await Location.getLocation();
*/
export default {
/**
* 获取当前位置(主入口)
* @returns {Promise<Object>} 包含经纬度和地址信息
*/
getLocation() {
return new Promise((resolve, reject) => {
// 判断是否为 H5 平台
if (process.env.UNI_PLATFORM === 'h5') {
this._getH5Location().then(resolve).catch(reject);
} else {
this._getUniLocation().then(resolve).catch(reject);
}
});
},
/**
* H5 端使用浏览器原生 Geolocation API
*/
_getH5Location() {
return new Promise((resolve, reject) => {
if (!navigator.geolocation) {
reject(new Error('您的浏览器不支持地理定位功能'));
return;
}
const options = {
enableHighAccuracy: true, // 高精度
timeout: 10000, // 10秒超时
maximumAge: 1000 // 缓存1分钟
};
navigator.geolocation.getCurrentPosition(
async (position) => {
const coords = position.coords;
const lat = coords.latitude;
const lng = coords.longitude;
const accuracy = coords.accuracy;
const altitude = coords.altitude;
try {
// 获取地址信息(逆地理编码)
const address = await this._reverseGeocodeH5(lat, lng);
resolve({
lat: lat,
lng: lng,
accuracy: Math.round(accuracy),
altitude: altitude ? Math.round(altitude) : null,
...address,
success: true
});
} catch (err) {
// 解析失败仍返回坐标
resolve({
lat: lat,
lng: lng,
accuracy: Math.round(accuracy),
altitude: altitude ? Math.round(altitude) : null,
country: '未知',
province: '未知',
city: '未知',
district: '未知',
street: '未知',
warning: '地址解析失败: ' + (err.message || '网络错误')
});
}
},
(error) => {
let msg;
switch (error.code) {
case error.PERMISSION_DENIED:
msg = '用户拒绝了定位权限请求';
break;
case error.POSITION_UNAVAILABLE:
msg = '无法获取当前位置信息';
break;
case error.TIMEOUT:
msg = '定位请求超时,请重试';
break;
default:
msg = '定位失败:未知错误';
}
reject(new Error(msg));
},
options
);
});
},
/**
* 小程序 / App 端使用 uni.getLocation
*/
_getUniLocation() {
return new Promise((resolve, reject) => {
uni.getLocation({
type: 'gcj02', // 使用国测局坐标系(微信推荐)
enableHighAccuracy: true,
timeout: 10000,
success: async (res) => {
const lat = res.latitude;
const lng = res.longitude;
const accuracy = res.accuracy;
const altitude = res.altitude;
try {
const address = await this._reverseGeocodeUni(lat, lng);
resolve({
latitude: lat,
longitude: lng,
accuracy: Math.round(accuracy),
altitude: altitude ? Math.round(altitude) : null,
...address,
success: true
});
} catch (err) {
resolve({
latitude: lat,
longitude: lng,
accuracy: Math.round(accuracy),
altitude: altitude ? Math.round(altitude) : null,
country: '未知',
province: '未知',
city: '未知',
district: '未知',
street: '未知',
warning: '地址解析失败: ' + (err.message || '网络错误')
});
}
},
fail: (err) => {
let msg = '定位失败';
if (err.errMsg.includes('auth deny')) {
msg = '未授权定位,请在设置中开启位置权限';
} else if (err.errMsg.includes('timeout')) {
msg = '定位超时';
} else if (err.errMsg.includes('fail')) {
msg = '设备不支持或未开启GPS';
}
reject(new Error(msg));
}
});
});
},
/**
* H5 逆地理编码(模拟实现)
* ⚠️ 实际项目请替换为真实 API:高德、腾讯地图等
*/
_reverseGeocodeH5(lat, lng) {
return new Promise((resolve, reject) => {
// 模拟不同区域返回不同地址(随机)
const mockAddresses = [
{ country: "中国", province: "广东省", city: "深圳市", district: "南山区", street: "科技南一路" },
{ country: "中国", province: "北京市", city: "北京市", district: "海淀区", street: "中关村大街" },
{ country: "中国", province: "上海市", city: "上海市", district: "浦东新区", street: "张江路" },
{ country: "中国", province: "浙江省", city: "杭州市", district: "西湖区", street: "文三路" },
{ country: "中国", province: "江苏省", city: "南京市", district: "鼓楼区", street: "中山北路" }
];
// 模拟网络延迟
setTimeout(() => {
const randomIndex = Math.floor(Math.random() * mockAddresses.length);
resolve(mockAddresses[randomIndex]);
}, 800);
});
},
/**
* 小程序/App 逆地理编码(模拟)
* ⚠️ 建议接入真实服务:
* 腾讯地图:https://apis.map.qq.com/ws/geocoder/v1/
* 高德地图:https://restapi.amap.com/v3/geocode/regeo
*/
_reverseGeocodeUni(lat, lng) {
return new Promise((resolve, reject) => {
const mockAddresses = [
{ country: "中国", province: "广东省", city: "广州市", district: "天河区", street: "科韵路" },
{ country: "中国", province: "四川省", city: "成都市", district: "武侯区", street: "天府大道" },
{ country: "中国", province: "湖北省", city: "武汉市", district: "洪山区", street: "光谷大道" }
];
setTimeout(() => {
const randomIndex = Math.floor(Math.random() * mockAddresses.length);
resolve(mockAddresses[randomIndex]);
}, 1000);
});
}
};
/**
* 通用地理位置获取工具(支持 H5、小程序、App)
* 返回:经纬度 + 地址信息(国家、省、市、区、街道)
*
* 使用方式:
* import Location from '@/utils/location.js';
* const res = await Location.getLocation();
*/
export default {
/**
* 获取当前位置(主入口)
* @returns {Promise<Object>} 包含经纬度和地址信息
*/
getLocation() {
return new Promise((resolve, reject) => {
// 判断是否为 H5 平台
if (process.env.UNI_PLATFORM === 'h5') {
this._getH5Location().then(resolve).catch(reject);
} else {
this._getUniLocation().then(resolve).catch(reject);
}
});
},
/**
* H5 端使用浏览器原生 Geolocation API
*/
_getH5Location() {
return new Promise((resolve, reject) => {
if (!navigator.geolocation) {
reject(new Error('您的浏览器不支持地理定位功能'));
return;
}
const options = {
enableHighAccuracy: true, // 高精度
timeout: 10000, // 10秒超时
maximumAge: 1000 // 缓存1分钟
};
navigator.geolocation.getCurrentPosition(
async (position) => {
const coords = position.coords;
const lat = coords.latitude;
const lng = coords.longitude;
const accuracy = coords.accuracy;
const altitude = coords.altitude;
try {
// 获取地址信息(逆地理编码)
const address = await this._reverseGeocodeH5(lat, lng);
resolve({
lat: lat,
lng: lng,
accuracy: Math.round(accuracy),
altitude: altitude ? Math.round(altitude) : null,
...address,
success: true
});
} catch (err) {
// 解析失败仍返回坐标
resolve({
lat: lat,
lng: lng,
accuracy: Math.round(accuracy),
altitude: altitude ? Math.round(altitude) : null,
country: '未知',
province: '未知',
city: '未知',
district: '未知',
street: '未知',
warning: '地址解析失败: ' + (err.message || '网络错误')
});
}
},
(error) => {
let msg;
switch (error.code) {
case error.PERMISSION_DENIED:
msg = '用户拒绝了定位权限请求';
break;
case error.POSITION_UNAVAILABLE:
msg = '无法获取当前位置信息';
break;
case error.TIMEOUT:
msg = '定位请求超时,请重试';
break;
default:
msg = '定位失败:未知错误';
}
reject(new Error(msg));
},
options
);
});
},
/**
* 小程序 / App 端使用 uni.getLocation
*/
_getUniLocation() {
return new Promise((resolve, reject) => {
uni.getLocation({
type: 'gcj02', // 使用国测局坐标系(微信推荐)
enableHighAccuracy: true,
timeout: 10000,
success: async (res) => {
const lat = res.latitude;
const lng = res.longitude;
const accuracy = res.accuracy;
const altitude = res.altitude;
try {
const address = await this._reverseGeocodeUni(lat, lng);
resolve({
latitude: lat,
longitude: lng,
accuracy: Math.round(accuracy),
altitude: altitude ? Math.round(altitude) : null,
...address,
success: true
});
} catch (err) {
resolve({
latitude: lat,
longitude: lng,
accuracy: Math.round(accuracy),
altitude: altitude ? Math.round(altitude) : null,
country: '未知',
province: '未知',
city: '未知',
district: '未知',
street: '未知',
warning: '地址解析失败: ' + (err.message || '网络错误')
});
}
},
fail: (err) => {
let msg = '定位失败';
if (err.errMsg.includes('auth deny')) {
msg = '未授权定位,请在设置中开启位置权限';
} else if (err.errMsg.includes('timeout')) {
msg = '定位超时';
} else if (err.errMsg.includes('fail')) {
msg = '设备不支持或未开启GPS';
}
reject(new Error(msg));
}
});
});
},
/**
* H5 逆地理编码(模拟实现)
* ⚠️ 实际项目请替换为真实 API:高德、腾讯地图等
*/
_reverseGeocodeH5(lat, lng) {
return new Promise((resolve, reject) => {
// 模拟不同区域返回不同地址(随机)
const mockAddresses = [
{ country: "中国", province: "广东省", city: "深圳市", district: "南山区", street: "科技南一路" },
{ country: "中国", province: "北京市", city: "北京市", district: "海淀区", street: "中关村大街" },
{ country: "中国", province: "上海市", city: "上海市", district: "浦东新区", street: "张江路" },
{ country: "中国", province: "浙江省", city: "杭州市", district: "西湖区", street: "文三路" },
{ country: "中国", province: "江苏省", city: "南京市", district: "鼓楼区", street: "中山北路" }
];
// 模拟网络延迟
setTimeout(() => {
const randomIndex = Math.floor(Math.random() * mockAddresses.length);
resolve(mockAddresses[randomIndex]);
}, 800);
});
},
/**
* 小程序/App 逆地理编码(模拟)
* ⚠️ 建议接入真实服务:
* 腾讯地图:https://apis.map.qq.com/ws/geocoder/v1/
* 高德地图:https://restapi.amap.com/v3/geocode/regeo
*/
_reverseGeocodeUni(lat, lng) {
return new Promise((resolve, reject) => {
const mockAddresses = [
{ country: "中国", province: "广东省", city: "广州市", district: "天河区", street: "科韵路" },
{ country: "中国", province: "四川省", city: "成都市", district: "武侯区", street: "天府大道" },
{ country: "中国", province: "湖北省", city: "武汉市", district: "洪山区", street: "光谷大道" }
];
setTimeout(() => {
const randomIndex = Math.floor(Math.random() * mockAddresses.length);
resolve(mockAddresses[randomIndex]);
}, 1000);
});
}
};
使用
<!-- pages/index/index.vue -->
<template>
<view class="container">
<button @click="getLocation">获取位置</button>
<p>经度:{{ lat }}</p>
<p>纬度:{{ lng }}</p>
</view>
</template>
<script>
import Location from "@/utils/amap-locationCur-web.js";
export default {
data() {
return {
location: null,
lat:'',
lng:''
};
},
methods: {
async getLocation() {
const { lat, lng } = await Location.getLocation();
console.log(lat, lng);
this.lat = lat
this.lng = lng
},
},
};
</script>
<style>
.container {
padding: 20px;
}
button {
margin-bottom: 20px;
}
p {
font-size: 14px;
color: #333;
line-height: 1.6;
}
</style>
<!-- pages/index/index.vue -->
<template>
<view class="container">
<button @click="getLocation">获取位置</button>
<p>经度:{{ lat }}</p>
<p>纬度:{{ lng }}</p>
</view>
</template>
<script>
import Location from "@/utils/amap-locationCur-web.js";
export default {
data() {
return {
location: null,
lat:'',
lng:''
};
},
methods: {
async getLocation() {
const { lat, lng } = await Location.getLocation();
console.log(lat, lng);
this.lat = lat
this.lng = lng
},
},
};
</script>
<style>
.container {
padding: 20px;
}
button {
margin-bottom: 20px;
}
p {
font-size: 14px;
color: #333;
line-height: 1.6;
}
</style>
更多推荐


所有评论(0)