JavaScript中计算地理坐标距离最常用Haversine公式,精度高(误差约0.5%以内),需将经纬度转为弧度后代入公式,地球半径取6371008.8米,结果单位为米。

JavaScript 计算两个地理坐标(经纬度)之间的距离,最常用的是球面余弦公式或更精确的Haversine 公式。接口返回的坐标通常是 WGS84 坐标系下的 [经度, 纬度] 或 {lng: x, lat: y} 格式,直接代入公式即可,无需额外转换。
用 Haversine 公式计算两点间球面距离
这是行业通用方法,精度高(误差约 0.5% 以内),适合大多数场景(如附近门店、打车距离估算)。
核心逻辑:把经纬度转为弧度,套用 Haversine 公式求大圆距离(单位:米):
- 地球平均半径取 6371008.8 米
- 注意:JavaScript 的
Math.sin/Math.cos接收的是弧度,需用deg * Math.PI / 180转换 - 输入坐标建议统一为
{lat: number, lng: number}结构,避免混淆经纬顺序
示例函数:
立即学习“Java免费学习笔记(深入)”;
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
function getDistance(p1, p2) {
const R = 6371008.8; // 地球平均半径(米)
const lat1 = (p1.lat * Math.PI) / 180;
const lng1 = (p1.lng * Math.PI) / 180;
const lat2 = (p2.lat * Math.PI) / 180;
const lng2 = (p2.lng * Math.PI) / 180;
<p>const dLat = lat2 - lat1;
const dLng = lng2 - lng1;</p><p>const a = Math.sin(dLat / 2) <em> Math.sin(dLat / 2) +
Math.cos(lat1) </em> Math.cos(lat2) <em>
Math.sin(dLng / 2) </em> Math.sin(dLng / 2);
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));</p><p>return R * c; // 单位:米
}</p><p>// 使用示例(来自接口的数据)
const userPos = { lat: 39.9042, lng: 116.4074 }; // 北京
const shopPos = { lat: 39.9139, lng: 116.3917 }; // 某门店
console.log(Math.round(getDistance(userPos, shopPos))); // 输出约 1124 米
处理接口返回的坐标数组并批量计算
实际中接口常返回多个 POI 坐标(如搜索附近的咖啡馆),需要对每个点计算与用户位置的距离,并排序或筛选。
- 先确保用户当前位置已获取(可用
navigator.geolocation) - 遍历接口数据,为每项添加
distance字段 - 可配合
.sort()实现“最近优先”,或用.filter(d => d.distance 筛选 5km 内
简写示例:
const user = await getCurrentPosition(); // 自定义获取用户位置
const pois = response.data; // 接口返回的 [{id:1, lat:..., lng:...}, ...]
<p>const poisWithDist = pois.map(p => ({
...p,
distance: Math.round(getDistance(user, p))
})).sort((a, b) => a.distance - b.distance);
注意坐标顺序和常见坑
很多接口(如高德、百度、OpenStreetMap)返回的是 [lng, lat] 数组,而 GeoJSON 规范也是 [longitude, latitude]。但部分地图 SDK(如 Leaflet)的 L.latLng(lat, lng) 是 lat 在前 —— 容易传反!
- 务必检查接口文档明确字段名:是
lng/lon还是x?是lat还是y? - 调试时打印前几个坐标,用地图工具(如 GPS Visualizer)验证是否落在合理位置
- 若结果明显偏大(如北京到上海算出 2000km),大概率是经纬度顺序颠倒或未转弧度
需要更高精度?考虑使用 Turf.js
如果项目已用地图库或需复杂空间运算(如测面内点、路径缓冲区),推荐引入轻量库 Turf.js:
- 一行代码搞定:
turf.distance(point1, point2, {units: 'meters'}) - 自动处理坐标顺序(默认 [lng, lat])、投影、单位转换
- 支持浏览器和 Node.js,可通过 CDN 或 npm 引入
小项目不建议为单个距离计算引入整个库,但中大型地理应用值得考虑。

















