Карты Google определяют расстояние по линии - PullRequest
2 голосов
/ 29 февраля 2012

Я пытаюсь определить расстояние от точки вдоль заданной полилинии (от начальной точки) на картах Google (учитывая, что пользователь нажимает на полилинию, а я получаю координаты точки в событии).

Пока что это единственное, что приходит на ум:

  • Перебирать все сегменты полилинии, пока не найду такой, что d (линия, точка) ~ = 0, отслеживая пройденное расстояние.
  • интерполировать на отрезке, на котором находится точка, чтобы найти расстояние относительно начала сегмента.

К сожалению, это кажется довольно сложным для того, что должно быть простым делом.

Есть ли более простой способ?

П.С .: Я использую API v3

Ответы [ 2 ]

3 голосов
/ 29 февраля 2012

Итак, после долгих поисков я решил реализовать алгоритм, как описано выше.Оказалось, что это не так плохо, как я думал.Если кто-нибудь попадет на эту страницу, полный код приведен ниже:

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);
}

Если вы хотите что-то улучшить, сообщите мне.

0 голосов
/ 29 февраля 2012

Если вы получите координаты для начальной и конечной точек, то используйте алгоритм haversine, чтобы вычислить расстояние, по которому вы можете легко найти расстояние между двумя точками с учетом кривизны земли.

Вот формула (вам может потребоваться перейти на язык, который вы используете):

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 - ваше расстояние.

Надеюсь, это поможет

...