场景:
项目需求为到店打卡的功能。店铺信息后台设置经纬度坐标,客户端定位计算与坐标距离,500米内即可打卡成功。
先看一下wx.getLocation()方法
这里的type我使用了gcj02的坐标系统
但是运营同事在后台设置的是百度地图里拿到的经纬度坐标,所以计算出来的距离偏差非常大。
关于坐标系统转换可以点这里查看原文章
我这里就要使用百度坐标(BD09)转GCJ坐标的方法
function BD09toGCJ(bd_lon, bd_lat) {
//定义一些常量
var x_PI = 3.14159265358979324 * 3000.0 / 180.0;
var PI = 3.1415926535897932384626;
var a = 6378245.0;
var ee = 0.00669342162296594323;
/**
* 百度坐标系 (BD-09) 与 火星坐标系 (GCJ-02)的转换
* 即 百度 转 谷歌、高德
* @param bd_lon
* @param bd_lat
* @returns {*[]}
*/
var x_pi = 3.14159265358979324 * 3000.0 / 180.0;
var x = bd_lon - 0.0065;
var y = bd_lat - 0.006;
var z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi);
var theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi);
var gg_lng = z * Math.cos(theta);
var gg_lat = z * Math.sin(theta);
return [gg_lng, gg_lat]
}
然后是计算距离的方法。
//经纬度距离计算
function getDistance(lat1, lng1, lat2, lng2, unit = true) {
var radLat1 = lat1 * Math.PI / 180.0
var radLat2 = lat2 * Math.PI / 180.0
var a = radLat1 - radLat2
var b = lng1 * Math.PI / 180.0 - lng2 * Math.PI / 180.0
var s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) +
Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)))
s = s * 6378.137 // EARTH_RADIUS;
s = Math.round(s * 10000) / 10000 //输出为公里
if (unit) { //是否返回带单位
if (s < 1) { //如果距离小于1km返回m
s = s.toFixed(3)
s = s * 1000 + "m"
} else {
s = s.toFixed(2)
s = s + "km"
}
} else {
s = s.toFixed(3)
s = s * 1000
}
return s
}
具体使用示例:
let _this = this
wx.getLocation({
type: 'gcj02',
isHighAccuracy: true,
highAccuracyExpireTime: 3000,
success(res) {
_this.location = res
console.log('获取到的微信定位数据', res)
console.log('微信定位纬度:', res.latitude)
console.log('微信定位经度:', res.longitude)
console.log('店铺纬度:', _this.item.latitude)
console.log('店铺经度:', _this.item.longitude)
let changeGCJ = BD09toGCJ(_this.item.longitude, _this.item.latitude)
console.log('转换后的坐标:', changeGCJ)
let distance = getDistance(res.latitude, res.longitude, changeGCJ[1], changeGCJ[0], false)
console.log('计算出的距离:', distance)
//...接下来的操作
if(distance < 500){
console.log('打卡成功')
}
}
})