百度地图坐标距离计算,源于百度地图JS API 2.0
前言
开始没有考虑周全,一直按平面距离计算结果自然不正确,后来在网上找到一些计算方法还是跟百度官方得出的值有很大差异,看了百度API源码才知道,原来是这样计算球面距离的,不多说了,上代码!
JS精简版
function OD(a, b, c) {
while (a > c) a -= c - b;
while (a < b) a += c - b;
return a;
}
function SD(a, b, c) {
b != null && (a = Math.max(a, b));
c != null && (a = Math.min(a, c));
return a;
}
function getDistance(a_lat,a_lng,b_lat,b_lng) {
var a = Math.PI * OD(a_lat, -180, 180) / 180;
var b = Math.PI * OD(b_lat, -180, 180) / 180;
var c = Math.PI * SD(a_lng, -74, 74) / 180;
var d = Math.PI * SD(b_lng, -74, 74) / 180;
return 6370996.81 * Math.acos(Math.sin(c) * Math.sin(d) + Math.cos(c) * Math.cos(d) * Math.cos(b-a));
}
//使用并保留小数点后两位
var m =getDistance(106.486654,29.490295,106.581515,29.615467).toFixed(2);
//获取到的单位是 米
alert(m);
JS 转 PHP版
function OD($a, $b, $c) {
while ($a > $c) $a -= $c - $b;
while ($a < $b) $a += $c - $b;
return $a;
}
function SD($a, $b, $c) {
$b != null && ($a = max($a, $b));
$c != null && ($a = min($a, $c));
return $a;
}
function getDistance($a_lat,$a_lng,$b_lat,$b_lng) {
//由于php的pi() 与 js的Math.PI的差异,为保证和JS计算的值统一故直接使用近似值
$a = 3.141592653589793 * OD($a_lat, -180, 180) / 180;
$b = 3.141592653589793 * OD($b_lat, -180, 180) / 180;
$c = 3.141592653589793 * SD($a_lng, -74, 74) / 180;
$d = 3.141592653589793 * SD($b_lng, -74, 74) / 180;
return 6370996.81 * acos(sin($c) * sin($d) + cos($c) * cos($d) * cos($b-$a));
}
//使用并保留小数点后两位
echo number_format(getDistance(106.486654,29.490295,106.581515,29.615467),2,'.','');
百度JS API 2.0算法完整版
//百度坐标距离计算,从压缩代码里扣出来的,故可读性差些,将就着还能看
var R = 6370996.81,//地球半径(米)
p=null,
j = void 0,
Ib = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
function Jb(a) {
var b = "", c, d, e = "", f, g = "", i = 0;
f = /[^A-Za-z0-9\+\/\=]/g;
if (!a || f.exec(a)) return a;
a = a.replace(/[^A-Za-z0-9\+\/\=]/g, "");
do c = Ib.indexOf(a.charAt(i++)),
d = Ib.indexOf(a.charAt(i++)),
f = Ib.indexOf(a.charAt(i++)),
g = Ib.indexOf(a.charAt(i++)),
c = c << 2 | d >> 4,
d = (d & 15) << 4 | f >> 2,
e = (f & 3) << 6 | g,
b += String.fromCharCode(c), 64 != f && (b += String.fromCharCode(d)), 64 != g && (b += String.fromCharCode(e));
while (i < a.length);
return b;
}
function Za(a) {
return "string" == typeof a;
}
function Point(a, b) {
isNaN(a) && (a = Jb(a), a = isNaN(a) ? 0 : a);
Za(a) && (a = parseFloat(a));
isNaN(b) && (b = Jb(b), b = isNaN(b) ? 0 : b);
Za(b) && (b = parseFloat(b));
this.lng = a;
this.lat = b
}
Point.prototype.mb = function (a) {
return a && this.lat == a.lat && this.lng == a.lng
};
function OD(a, b, c) {
for (; a > c;) a -= c - b;
for (; a < b;) a += c - b;
return a;
}
function SD(a, b, c) {
b != p && (a = Math.max(a, b));
c != p && (a = Math.min(a, c));
return a;
}
function Tk(a) {
return Math.PI * a / 180;
}
function Pe(a, b, c, d) {
return R * Math.acos(Math.sin(c) * Math.sin(d) + Math.cos(c) * Math.cos(d) * Math.cos(b - a));
}
function Vo(a, b) {
if (!a || !b) return 0;
a.lng = OD(a.lng, -180, 180);
a.lat = SD(a.lat, -74, 74);
b.lng = OD(b.lng, -180, 180);
b.lat = SD(b.lat, -74, 74);
return Pe(Tk(a.lng),Tk(b.lng),Tk(a.lat),Tk(b.lat))
}
function getDistance(a, b) {
if (a && b) {
if (a.mb(b)) return 0;
var c;
c = Vo(a, b);
if (c === p || c === j) c = 0;
return c;
}
}
//使用并保留小数点后两位
var p1 = new Point(106.486654,29.490295);
var p2 = new Point(106.581515,29.615467);
var m = getDistance(p1,p2).toFixed(2);
//获取到的单位是 米
alert(m);
注:都看到这了,点个赞吧 ^_^