2012-02-28 65 views
0

我试图确定一个点沿谷歌地图上给定的多段线(从起点)的距离(假设用户点击了折线,并且我得到了事件中的点坐标)。谷歌地图确定沿线的距离

到目前为止,这是我想到的唯一的事情:直到我找到一个,使得 d(线,点)〜= 0,跟踪的

  • 遍历所有段折线到目前为止所覆盖的距离。
  • 在点上插入点,以找到相对于段起点的距离 。

不幸的是,这似乎是相当复杂的事情应该是直截了当的事情。

有没有更简单的方法?

PS:我使用的API V3

回答

2

于是,经过一番搜索,我决定为上述实施的算法。原来它并没有我想象的那么糟糕。如果没有人登陆这个页面上,完整代码如下:

var DistanceFromStart = function (/*latlng*/ markerPosition) { 

    var path = this.polyline.getPath();  
    var minValue = Infinity; 
    var minIndex = 0; 
    var x = markerPosition.lat(); 
    var y = markerPosition.lng(); 

    for (var i = 0; i < path.getLength() - 1; i++) { 

     var x1 = path.getAt(i).lat(); 
     var y1 = path.getAt(i).lng(); 

     var x2 = path.getAt(i + 1).lat(); 
     var y2 = path.getAt(i + 1).lng(); 

     var dist = pDistance(x, y, x1, y1, x2, y2); 

     if (dist < minValue) { 
      minIndex = i; 
      minValue = dist; 
     } 
    }  

    var gdist = google.maps.geometry.spherical.computeDistanceBetween; 
    var dinit = gdist(markerPosition, path.getAt(minIndex)); 
    var dtotal = gdist(path.getAt(minIndex), path.getAt(minIndex + 1)); 

    var distanceFromStart = 0; 

    for (var i = 0; i <= minIndex - 1; i++) { 
     distanceFromStart += gdist(path.getAt(i), path.getAt(i + 1)); 
    } 

    distanceFromStart += dtotal * dinit/dtotal; 

    return distanceFromStart; 
} 

function pDistance(x, y, x1, y1, x2, y2) { 

    var A = x - x1; 
    var B = y - y1; 
    var C = x2 - x1; 
    var D = y2 - y1; 

    var dot = A * C + B * D; 
    var len_sq = C * C + D * D; 
    var param = dot/len_sq; 

    var xx, yy; 

    if (param < 0 || (x1 == x2 && y1 == y2)) { 
     xx = x1; 
     yy = y1; 
    } 
    else if (param > 1) { 
     xx = x2; 
     yy = y2; 
    } 
    else { 
     xx = x1 + param * C; 
     yy = y1 + param * D; 
    } 

    var dx = x - xx; 
    var dy = y - yy; 
    return Math.sqrt(dx * dx + dy * dy); 
} 

如果你看到任何改善,不要让我知道。

-1

如果你的起点和终点的坐标,然后用半正矢算法来计算距离,你可以很容易地找到考虑到两点之间的距离地球曲率。

这里是公式(您可能需要在转换成您所使用的语言):

var R = 6371; // km 
var dLat = (lat2-lat1).toRad(); 
var dLon = (lon2-lon1).toRad(); 
var lat1 = lat1.toRad(); 
var lat2 = lat2.toRad(); 

var a = Math.sin(dLat/2) * Math.sin(dLat/2) + 
    Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2); 
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); 
var d = R * c; 

变量d是距离。

希望这有助于

+0

只有在折线中只有1段时才能使用。 – user472875 2012-02-28 23:40:25

+0

正如我上面所说,谢谢你的答案,但这将不适用于一般折线,因为有很多段。 – user472875 2012-02-29 04:31:06