如何在javascripts中按经纬度距离对数组项进行排序?

Posted

技术标签:

【中文标题】如何在javascripts中按经纬度距离对数组项进行排序?【英文标题】:How to sort array items by longitude latitude distance in javascripts? 【发布时间】:2015-01-06 07:19:12 【问题描述】:

我有以下 6 个位置的 JSON 数组。有没有办法根据附近位置在数组中的下一个经度和纬度对这些进行排序?

[
"id" : 279, "longitude":79.853239,"latitude":6.912283,
"id" : 284, "longitude":79.865699,"latitude":6.885697,
"id" : 13,  "longitude":79.851187,"latitude":6.912220,
"id" : 282, "longitude":79.858904,"latitude":6.871041,
"id" : 281, "longitude":79.853346,"latitude":6.899757,
"id" : 16,  "longitude":79.854786,"latitude":6.894039
]

排序可以从第一项开始,结果应该是这样的

[
"id" : 279, "longitute":79.853239,"latitude":6.912283,
"id" : 13,  "longitute":79.851187,"latitude":6.912220,
"id" : 281, "longitute":79.853346,"latitude":6.899757,
"id" : 16,  "longitute":79.854786,"latitude":6.894039,
"id" : 284, "longitute":79.865699,"latitude":6.885697,
"id" : 282, "longitute":79.858904,"latitude":6.871041
]

【问题讨论】:

如果第一项是 id=279,则数组的下一项应该最接近第一项(在这种情况下,它是 id=13)。那么它应该 b 最接近 id=13 那么如果你按照彼此之间的距离排序,你会如何选择哪个是第一个,哪个是最后一个? 作为第一个元素,我们可以获取第一个项目,然后基于该项目我们可以对下一个项目进行排序。正如我上面解释的,如果第一项是 id=279,那么最近的一项将是第二项 id=13,那么第三项应该最接近 id=13。 所以 - 创建另一个以 0 开头的数组,并且每个下一个元素包含从第一个元素到其他每个元素的距离 【参考方案1】:

通过添加另一个名为距离的属性解决了问题。使用以下函数计算两点之间的距离

function calculateDistance(lat1, lon1, lat2, lon2, unit) 
  var radlat1 = Math.PI * lat1/180
  var radlat2 = Math.PI * lat2/180
  var radlon1 = Math.PI * lon1/180
  var radlon2 = Math.PI * lon2/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
  if (unit=="K")  dist = dist * 1.609344 
  if (unit=="N")  dist = dist * 0.8684 
  return dist

然后使用上述函数计算数组中每个项目的距离。然后按距离对数组进行排序。

for ( i = 0; i < uniqueNodes.length; i++) 
  uniqueNodes[i]["distance"] = calculateDistance(uniqueNodes[0]["latitude"],uniqueNodes[0]["longitute"],uniqueNodes[i]["latitude"],uniqueNodes[i]["longitute"],"K");


uniqueNodes.sort(function(a, b)  
  return a.distance - b.distance;
);

【讨论】:

calculateDistance 函数定义了 radlon1 和 radlon2,但从不使用它们。这是算法的问题吗? 这使用 余弦球面定律 movable-type.co.uk/scripts/latlong.html。单位是什么意思? K 为公里?和 N 表示英制单位/英里? 非常有用,请您解释一下。我们如何将 uniqueNodes[0]["latitude"] 更改为下一个最近的位置,以便它找到下一个最近的位置等等? @KevinNewman 不,radllon2radlong2 可以删除。 @solsTiCe 看起来 K = km 和 N = 海里。如果您使用它进行排序,您可以完全删除 unit 参数。【参考方案2】:

其他想要这样做的人,如果您有可用的经度和纬度,您可以对其进行线性排序以获得如下所示的简单线图。这会给你一个上升/运行线性结果。

var $array = [
[79.853239, 6.912283, 279],
[79.851187, 6.912220, 13],
[79.853346, 6.899757, 281],
[79.854786, 6.894039, 16],
[79.865699, 6.885697, 284],
[79.858904, 6.87104, 282]
]

function sortLngLat(a, b)
var x = a[0] / a[1];
var y = b[0] / b[1];

var sortedArray = $array.sort(sortLngLat);
console.log(sortedArray);

输出应该如下图所示,您可以使用负数和正数调整值以获得不同的角度和方向。

 ---------------
|       |  /    |
| -1/1  | / 1/1 |
|       |/      |
|--------------
|      /|       |
|-1/-1/ | 1/-1  |
|    /  |       |
 ---------------

【讨论】:

【参考方案3】:

您可以循环遍历数组,并嵌套另一个循环以找到最近的循环。

var finalArray = [];

while(entries)
  //for each item
  while(what's left)
    //find the nearest against the current item
    //push to final
  

这假设数组中的第一个是参考点,接下来的将是最接近该点的,依此类推。

【讨论】:

以上是关于如何在javascripts中按经纬度距离对数组项进行排序?的主要内容,如果未能解决你的问题,请参考以下文章

Swift如何按距离对表格视图进行排序

在 ONGR ElasticsearchDSL 中按距离对结果进行排序

如何在reactjs / javascript中按值对对象数组进行分组

Javascript排序数组 - 在比较函数中调用函数

在javascript中按子数组属性值对对象数组进行排序

oracle数据库中 如果按商家的距离排序?