地理坐标范围去重需用Haversine公式计算球面距离,按业务容忍半径(如10米)判定邻近重复,遍历保留首个代表点,剔除簇内冗余点。

JavaScript 数组去重按地理坐标范围去重,本质不是“完全相等才去重”,而是“在某个距离阈值内视为重复”,需结合经纬度计算两点间球面距离(如 Haversine 公式),再根据业务设定容忍半径(例如 10 米、100 米)进行聚类或筛选。
理解“范围去重”的核心逻辑
普通去重(Set、filter + findIndex)依赖精确相等,但地理坐标存在精度误差、采集抖动、同一地点多次上报等情况。真正需求常是:保留每个位置簇中一个代表点,剔除邻近冗余点。这属于空间去重(spatial deduplication),关键在定义“多近算重复”和“选哪个留下”。
用 Haversine 计算两点球面距离(单位:米)
地球是球体,不能直接用平面勾股定理。Haversine 是常用且足够精确的近似公式:
(以下函数返回单位为米的距离)
function haversineDistance(lat1, lon1, lat2, lon2) {
const R = 6371000; // 地球平均半径,单位:米
const toRad = x => x * Math.PI / 180;
const φ1 = toRad(lat1);
const φ2 = toRad(lat2);
const Δφ = toRad(lat2 - lat1);
const Δλ = toRad(lon2 - lon1);
<p>const a = Math.sin(Δφ/2) <em> Math.sin(Δφ/2) +
Math.cos(φ1) </em> Math.cos(φ2) <em>
Math.sin(Δλ/2) </em> Math.sin(Δλ/2);
const c = 2 <em> Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
return R </em> c;
}</p>
实现范围去重(保留首个代表点)
遍历数组,对每个点检查是否与已保留的点距离
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 适合数据量不大(
- 时间复杂度 O(n²),但实际中因提前跳出,多数情况可接受
- 示例:保留所有与其他已选点距离 ≥ 50 米的坐标
function dedupeByDistance(points, thresholdMeters = 50) {
if (points.length === 0) return [];
<p>const result = [points[0]]; // 首个点必保留</p><p>for (let i = 1; i </p><pre class="brush:php;toolbar:false;">for (const kept of result) {
const dist = haversineDistance(
p.lat, p.lng,
kept.lat, kept.lng
);
if (dist <p>}</p><p>return result;
}</p><p>// 使用示例
const locations = [
{ lat: 39.9087, lng: 116.3975 }, // 北京天安门
{ lat: 39.9086, lng: 116.3976 }, // 偏移约 12 米 → 视为重复
{ lat: 39.9100, lng: 116.4000 }, // 距离 > 200 米 → 保留
];
console.log(dedupeByDistance(locations, 20)); // 输出 2 个点</p>进阶建议:提升效率或优化结果
- 网格预分桶(Grid Binning):先按经纬度四舍五入到固定精度(如 `lat.toFixed(4)` + `lng.toFixed(4)`)生成“地理格子 ID”,仅在同格子内做 Haversine 比较,大幅减少计算量
- 选最优代表点:不总选第一个,可选该簇中时间最新、信号最强、或几何中心点(需额外聚类)
-
用 GeoJSON + Turf.js:大型项目推荐使用 Turf.js 的
turf.clustersDbscan或turf.difference实现更鲁棒的空间聚类 -
注意坐标顺序:确保统一为
[lat, lng](WGS84 标准),避免传反导致距离爆炸式错误
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










