【问题标题】:How to get shortest distance between two shapes on Google Maps, using JavaScript?如何使用 JavaScript 在 Google 地图上获得两个形状之间的最短距离?
【发布时间】:2013-02-15 16:35:56
【问题描述】:

我在我的应用程序中使用 Google Maps API(带有 MVC 的 ASP.NET)。

我有一个坐标数组(每个都由纬度和经度组成),我们称之为“原点”(可以是多边形、折线或标记)和另一个坐标数组,我们称之为“目的地”(可以是多边形、折线或标记)。

我想计算“起点”和“终点”之间的最短距离。我该怎么做?

【问题讨论】:

标签: javascript google-maps google-maps-api-3 maps distance


【解决方案1】:

一种解决方案是采用找到here 的选项之一,并计算从原点每个点到目的地每个点的距离。最小的距离是两个形状之间的距离。

代码可能如下所示(未经测试):

var minDistance = Number.POSITIVE_INFINITY;
for (var i=0; i<origin.length; i++){
   for (var j=0; j<destination.length; j++){
      var dist = google.maps.geometry.spherical.computeDistanceBetween(origin[i], destination[j]);
      if (dist < minDistance) 
         minDistance = dist;
   }
}

如果性能是一个问题,这可能会被优化。有关这方面的更多信息,我会查看此question 及其解决相同问题的答案,尽管是从纯数学的角度来看。

【讨论】:

【解决方案2】:

我建议您使用余弦球定律来计算点之间的距离。如果您有一个起点的纬度和经度数组,以及目的地的纬度和经度坐标数组,那么您可以执行以下操作:

var origins = [{lat: "35.5", lon: "-80.0"}, ...]; // Array of origin coordinates
var destinations = [{lat: "34.5", lon: "-80.0"}, ...]; // Array of destination coordinates
var shortestDistance = null;
var shortestPair = [];

for (i = 0; i < origins.length; i++) {
    for (j = 0; j < destinations.length; j++) {

        var lat1 = origins[i].lat.toRadians();
        var lat2 = destinations[j].lat.toRadians();
        var lon = (destinations[j].lon - origins[i].lon).toRadians();
        var R = 6371; // gives distance in kilometers
        var calcDistance = Math.acos(Math.sin(lat1) * Math.sin(lat2) + Math.cos(lat1) * Math.cos(lat2) * Math.cos(lon)) * R;

        if (shortestDistance === null || calcDistance < shortestDistance) {
            shortestPair[0] = origins[i]; // Store the origin coordinates
            shortestPair[1] = destinations[j]; // Store the destination coordinates
            shortestDistance = calcDistance; // Update the shortest distance
        }
    }
}

/* After this runs, you'll have the array indexes for the origin and 
destination with the shortest distance as well as the actual distance (kilometers) 
in the array shortestPair and the variable shortestDistance respectively.

For miles, divide shortestDistance by 1.609344
For nautical miles, divide shortestDistance by 1.852

*/

这似乎是一种比尝试使用 Maps API 计算距离更简单的方法。以上公式来源于http://www.movable-type.co.uk/scripts/latlong.html。如果您需要计算更准确,也可以使用半正弦公式;它在我链接的页面上有详细说明。

【讨论】:

  • 您的解决方案存在逻辑错误。看看this graphical demonstration of the problem
  • @Matmarbon:是的,我按原样实施的解决方案无法解决这种情况,但通过比较多边形的每个顶点,我的解决方案仍然有效。要走得更远,需要计算每个多边形中每个线段上的点的接近度,这是一个计算量很大的 NP-Complete 问题。
  • 那么,长话短说:“算了吧,它太复杂了”?看,确切地说,这个问题并没有说明性能,而是需要解决这个问题。无论如何,到目前为止,我感谢您的帮助:)
【解决方案3】:
function moveAlongPath(points, distance, index) {  
  index = index || 0;  

  if (index < points.length && typeof points[index +1] !="undefined") {
    var polyline = new google.maps.Polyline({
      path: [points[index], points[index + 1]],
      geodesic: true,
      strokeColor: '#FF0000',
      strokeOpacity: 1.0,
      strokeWeight: 2
    });

    var distanceToNextPoint = polyline.Distance();
    if (distance <= distanceToNextPoint) {
      return polyline_des(points[index],points[index + 1], distance);
    }
    else {
      return moveAlongPath(points,
            distance - distanceToNextPoint,
            index + 1);
    }
  }
  else {
    return null;
  }  
}

【讨论】:

  • 什么是polyline_des?
  • 它是一种谷歌地图路线模式,它在纬度之间直接绘制路径,如果你不使用它,请忽略它使用你的溃败点
【解决方案4】:

好吧,从数学的角度来看:

您的问题是找到空间中的一点与矢量线或平面之间的最短距离。

因此,如果您的坐标位于 [a1,a2,a3] 和 [b1,b2,b3] 等数组中,则这 2 个点在 3 维空间中的距离就像勾股定理一样,包含三个元素: sqrt[(a1-b1)²+(a2-b2)²+(a3-b3)²]=d(a,b).

我知道这没有考虑地球的曲率,但对于“短”距离来说这并不重要。

如果您了解一些数学知识,维基百科文章也可能对您有所帮助。 http://en.wikipedia.org/wiki/Euclidean_distance#Three_dimensions

编辑 12.08.14:
要考虑地球的曲率,可以做一个简单的计算:
(1) 你已经知道地球的距离
(2) 你知道大约。地球半径

知道您的起点 (A) 和目的地 (B),您现在可以构建一个以地心 (C) 为中心的三角形。您现在这样做是为了计算 (C) 处的角度 (sin/cos/tan)。使用该角度,您现在可以获得地球的长度(包括曲率)。

([地球边界]/360°)*[在 (C) 处的角度] = (A) 到 (B) 在地球曲率上的距离。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多