我想对一个数组进行排序,使每个元素与前一个位置的距离最短。
数组就像那样
locations=[{"loc1",lat,long},{"loc2",lat,long},{"loc3",lat,long},{"loc4",lat,long},{"loc5",lat,long}]
计算距离的函数是:
var distance = function(lat1, lon1, lat2, lon2)
{
var radlat1 = Math.PI * lat1/180;
var radlat2 = Math.PI * lat2/180;
var theta = lon1-lon2;
var radtheta = Math.PI * theta/180;
var 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;
}
此函数在传递值时提供两个位置之间的距离。
起点是位置数组的第一个元素 现在我想要一个将采用数组并返回已排序数组的函数。
答案 0 :(得分:0)
您需要在排序函数中执行距离计算:
由于距离计算非常密集,因此对象中的缓存距离会更快,因此您在排序方法中不会多次计算相同的距离:
var startingLoc = {lat:0.000,lng:0.000};//your starting location;
var distanceCache = {}; //a cache to hold your distance calculations
//sort the locations - assumes loc1 is {lat:some number, lng: some number}
locations.sort(function(loc1,loc2) {
var loc1Key = loc1.lat+'-'+loc1.lng;
var loc2Key = loc2.lat+'-'+loc2.lng;
if(!distanceCache.hasOwnProperty(loc1Key)) {
distanceCache[loc1Key] = distance(startingLoc.lat,startingLoc.lng,loc1.lat,loc1.lng);
}
if(!distanceCache.hasOwnProperty(loc2Key)) {
distanceCache[loc2Key] = distance(startingLoc.lat,startingLoc.lng,loc2.lat,loc2.lng);
}
return distanceCache[loc1Key] - distanceCache[loc2Key];
});
distanceCache = null; //done with distanceCache
答案 1 :(得分:0)
你可能会在这个上面找个漂亮的大兔子洞。我先来看看你是否可以使用Maps API Google Map V3, how to get list of best driving route for multiple destinations?。 optimizeWaypoints
设置旨在以最佳驾驶顺序返回位置列表。
显然这与纯距离比较不同,但它可能适合您的需要。
答案 2 :(得分:0)
您可以为Array原型上的sort方法提供自定义函数,如下所示:
locations = [
["loc1", 1, 1],
["loc2", 3, 3],
["loc3", 2, 2],
["loc4", 5, 4],
["loc5", 3, 5]
];
var distance = function(lat1, lon1, lat2, lon2) {
var radlat1 = Math.PI * lat1 / 180;
var radlat2 = Math.PI * lat2 / 180;
var theta = lon1 - lon2;
var radtheta = Math.PI * theta / 180;
var 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;
};
locations.sort(function(a, b) {
var origLat = 0,
origLong = 0;
return distance(origLat, origLong, a[1], a[2]) - distance(origLat, origLong, b[1], b[2]);
});
console.log(locations)

答案 3 :(得分:0)
如果没有真正的位置,就不会测试,但下面的内容应该可以完成这项工作:
(我不知道谷歌地图API,也许你可以找到更好的方法来做到这一点......)
var locations = [{
name : "loc1",
lat : 1001,
long : 2001
}, {
name : "loc2",
lat : 150,
long : 630
}, {
name : "loc3",
lat : 151,
long : 631
}, {
name : "loc4",
lat : 850,
long : 56
}, {
name : "loc5",
lat : 960,
long : 698
}
];
var distance = function (lat1, lon1, lat2, lon2) {
var radlat1 = Math.PI * lat1 / 180;
var radlat2 = Math.PI * lat2 / 180;
var theta = lon1 - lon2;
var radtheta = Math.PI * theta / 180;
var 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;
}
var locationWithDistFromPrevious = locations.map(function (l, i) {
if (i === 0) {
l.dist = 0;
} else {
l.dist = distance(l.lat, l.long, locations[i - 1].lat, locations[i - 1].long)
}
return l;
}).sort(function (a, b) {
return a.dist - b.dist
});
var locationWithDistFromFirst = locations.map(function (l, i) {
if (i === 0) {
l.dist = 0;
} else {
l.dist = distance(l.lat, l.long, locations[0].lat, locations[0].long)
}
return l;
}).sort(function (a, b) {
return a.dist - b.dist
});
document.getElementById("resultFromPrev").textContent = JSON.stringify(locationWithDistFromPrevious, null, 4);
document.getElementById("resultFromFirst").textContent = JSON.stringify(locationWithDistFromFirst, null, 4);
<body>
Sort by previous item<br/>
<pre id="resultFromPrev"></pre><br/>
Sort by first item dist <br/>
<pre id="resultFromFirst"></pre><br/>
</body>