目标
有两个目标:
- 按距离排序纬度和经度
- 基于公差将纬度和经度分组
期望结果
按照距离的顺序对纬度和经度进行排序,并根据公差进行分组。
实际结果
纬度和经度按距离排序,但分组感觉不太正确。
尝试过的方法
我使用了几个 StackOverflow 答案中的Haversine 公式,例如 示例 1、示例 2、示例 3,并成功地按照距离排序了位置(目标 #1 - 我认为)。我尝试使用 Math.abs(lat - lastLat) < tolerance
来通过公差进行分组,但我不确定它是否有效或灵活(目标 #2)。
代码
const locations = [
{ lat: 77.62279999, lng: 12.95248389 },
{ lat: 77.62517676, lng: 12.95027966 },
{ lat: 77.62753442, lng: 12.93745478 },
{ lat: 77.62217671, lng: 12.93353553 },
];
const distance = (lat1, lon1, lat2, lon2) => {
const radlat1 = (Math.PI * lat1) / 180;
const radlat2 = (Math.PI * lat2) / 180;
const theta = lon1 - lon2;
const radtheta = (Math.PI * theta) / 180;
let dist =
Math.sin(radlat1) * Math.sin(radlat2) +
Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta);
dist = Math.acos(dist);
dist = (dist * 180) / Math.PI;
dist = dist * 60 * 1.1515;
dist = dist * 1.609344;
return dist;
};
const sortedLocationsByDistance = locations.sort(function (a, b) {
return distance(0, 0, a.lat, a.lng) - distance(0, 0, b.lat, b.lng);
});
console.log('Sorted:', sortedLocationsByDistance);
const groupedLocationsByTolerance = {};
const tolerance = 0.001;
sortedLocationsByDistance.forEach(({ lat, lng }, index) => {
if (
Object.keys(groupedLocationsByTolerance).length &&
Math.abs(lat - sortedLocationsByDistance.slice(-1)[0].lat) < tolerance &&
Math.abs(lng - sortedLocationsByDistance.slice(-1)[0].lng) < tolerance
) {
groupedLocationsByTolerance[Object.keys(groupedLocationsByTolerance).slice(-1)[0]].push({ lat, lng });
return;
}
groupedLocationsByTolerance[index] = groupedLocationsByTolerance[index] || [];
groupedLocationsByTolerance[index].push({ lat, lng });
});
console.log('Grouped:', groupedLocationsByTolerance);
j = i + 1
更改为j = i
,则内部循环将从将位置与自身进行比较开始,属性将包括自身,结果将与您一直看到的相匹配... - Trentiumperformance.now()
测试后,它因实现方法而异。我喜欢新语法的可读性。 - PaddydistanceFromOrigin
在公差范围内的位置,并在此基础上创建一个新数组(!)... - Trentium