js根据经纬度计算两点之间的距离
·
一、根据Haversine 公式进行计算:
公式:

函数定义:
function getDistance(point1, point2) {
let R = 6371000; // 地球平均半径,单位:米
let lat1 = point1.latitude * Math.PI / 180;
let lat2 = point2.latitude * Math.PI / 180;
let lon1 = point1.longitude * Math.PI / 180;
let lon2 = point2.longitude * Math.PI / 180;
let a = Math.sin((lat2 - lat1) / 2) * Math.sin((lat2 - lat1) / 2) +
Math.cos(lat1) * Math.cos(lat2) * Math.sin((lon2 - lon1) / 2) * Math.sin((lon2 - lon1) / 2);
let c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
let d = R * c; // 初始计算得到的距离,单位:米
if (d >= 1000) {
// 如果距离大于等于1000米(即1千米),则换算为千米并保留两位小数
return (d / 1000).toFixed(2) + "千米";
} else {
return d + "米";
}
}
使用方式:
// 示例用法
let point1 = {
latitude: 39.9042,
longitude: 116.4074
};
let point2 = {
latitude: 31.2304,
longitude: 121.4737
};
let distance = getDistance(point1, point2);
console.log(distance);
二、根据vincenty算法计算(长距离精度更高)
函数定义:
function vincentyDistance(point1, point2) {
const a = 6378137.0; // 半长轴,单位:米(WGS84椭球体)
const f = 1 / 298.257223563; // 扁率(WGS84椭球体)
const b = a * (1 - f); // 半短轴,单位:米
const φ1 = point1.latitude * (Math.PI / 180);
const λ1 = point1.longitude * (Math.PI / 180);
const φ2 = point2.latitude * (Math.PI / 180);
const λ2 = point2.longitude * (Math.PI / 180);
let L = λ2 - λ1;
let tanU1 = (1 - f) * Math.tan(φ1);
let tanU2 = (1 - f) * Math.tan(φ2);
let cosU1 = 1 / Math.sqrt(1 + tanU1 * tanU1);
let cosU2 = 1 / Math.sqrt(1 + tanU2 * tanU2);
let sinU1 = tanU1 * cosU1;
let sinU2 = tanU2 * cosU2;
let λ = L;
let iterLimit = 100;
let iter = 0;
let sinλ = 0;
let cosλ = 0;
let sinσ = 0;
let cosσ = 0;
let σ = 0;
let Δσ = 0;
do {
sinλ = Math.sin(λ);
cosλ = Math.cos(λ);
sinσ = Math.sqrt((cosU2 * sinλ) * (cosU2 * sinλ) + (cosU1 * sinU2 - sinU1 * cosU2 * cosλ) * (cosU1 * sinU2 - sinU1 * cosU2 * cosλ));
if (sinσ === 0) {
return 0; // 重合点,距离为0
}
cosσ = sinU1 * sinU2 + cosU1 * cosU2 * cosλ;
σ = Math.atan2(sinσ, cosσ);
let sinα = cosU1 * cosU2 * sinλ / sinσ;
let cos2α = 1 - sinα * sinα;
let cos2σm = cosσ - 2 * sinU1 * sinU2 / cos2α;
if (isNaN(cos2σm)) {
cos2σm = 0; // 避免出现NaN情况
}
let C = f / 16 * cos2α * (4 + f * (4 - 3 * cos2α));
Δσ = C * sinσ * (cos2σm + C * cosσ * (-1 + 2 * cos2σm * cos2σm));
λ = L + (1 - C) * f * sinα * (σ + C * sinσ * (cos2σm + C * cosσ * (-1 + 2 * cos2σm * cos2σm)));
iter++;
} while (Math.abs(Δσ) > 1e-12 && iter < iterLimit);
if (iter >= iterLimit) {
// 如果迭代次数超过限制,可能无法收敛,可根据实际情况处理错误,这里简单返回一个较大值表示异常情况
return Number.MAX_VALUE;
}
let u2 = cos2α * (a * a - b * b) / (b * b);
let A = 1 + u2 / 16384 * (4096 + u2 * (-768 + u2 * (320 - 175 * u2)));
let B = u2 / 1024 * (256 + u2 * (-128 + u2 * (74 - 47 * u2)));
let Δs = B * sinσ * (cos2σm + B / 4 * (cosσ * (-1 + 2 * cos2σm * cos2σm) - B / 6 * cos2σm * (-3 + 4 * sinσ * sinσ) * (-3 + 4 * cos2σm * cos2σm)));
let s = b * A * (σ - Δs);
if (s >= 1000) {
// 如果距离大于等于1000米(即1千米),则换算为千米并保留两位小数
return (s / 1000).toFixed(2) + "千米";
} else {
return s + "米";
}
}
使用方法同上
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐
所有评论(0)