百度地图坐标距离计算,源于百度地图JS API 2.0

百度地图坐标距离计算,源于百度地图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);

注:都看到这了,点个赞吧 ^_^

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值