Как получить кратчайшее расстояние между двумя фигурами на Google Maps с помощью JavaScript?

Я использую API Карт Google в своем приложении (ASP.NET с MVC).

У меня есть массив координат (каждый из которых состоит из широты и долготы), позвольте нам называть его «исходной точкой» (это может быть многоугольник, полилиния или маркер) и еще один массив координат, позвольте нам называть это «пунктом назначения» (может быть полигон, полилиния или маркер).

Я хочу рассчитать кратчайшее расстояние между пунктами отправления и назначения. Как я могу это сделать?


person user1799982    schedule 01.03.2013    source источник
comment
stackoverflow.com/questions/3838493/   -  person user15    schedule 01.03.2013
comment
@ user15 Ваша ссылка касается только отдельных координат (исходная и конечная точки являются маркерами), а не фигур.   -  person Matmarbon    schedule 04.08.2014


Ответы (4)


Что ж, если посмотреть с математической точки зрения:

ваша задача - найти кратчайшее расстояние между точкой в ​​пространстве и векторной линией или плоскостью.

Итак, если у вас есть координаты в массивах, таких как [a1,a2,a3] и [b1,b2,b3], расстояние между этими двумя точками в трехмерном пространстве похоже на теорему Пифагора с тремя элементами: 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) по кривизне земли.

person Nils    schedule 11.08.2014

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

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

*/

Это кажется более простым подходом, чем попытка использовать API Карт для расчета расстояния. Приведенная выше формула была взята из http://www.movable-type.co.uk/scripts/latlong.html. Вы также можете использовать формулу гаверсинуса, если вам нужны более точные расчеты; это подробно описано на странице, на которую я указал.

person aecend    schedule 04.08.2014
comment
В вашем решении есть логическая ошибка. Взгляните на эту графическую демонстрацию проблемы - person Matmarbon; 06.08.2014
comment
@Matmarbon: Да, мое решение, реализованное как есть, не решит эту ситуацию, но, сравнивая каждую из вершин многоугольников, мое решение все еще может быть эффективным. Чтобы пойти дальше, потребовалось бы вычислить близость к точкам вдоль каждого сегмента в каждом многоугольнике, что является сложной задачей NP-Complete в вычислительном отношении. - person aecend; 06.08.2014
comment
Итак, короче: забудьте об этом, это слишком сложно? Слушай, если быть точным, вопрос о производительности ничего не говорит, но требует решения этой проблемы. В любом случае, я ценю вашу помощь до сих пор :) - person Matmarbon; 07.08.2014

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

Код может выглядеть так (непроверенный):

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

Вероятно, это можно было бы оптимизировать, если производительность является проблемой. Для получения дополнительной информации я бы посмотрел на этот вопрос и ответы на него, которые заниматься тем же вопросом, но с чисто математической точки зрения.

person Kade Keith    schedule 04.08.2014
comment
То же, что и с решением aecend. Взгляните на этот рисунок. - person Matmarbon; 06.08.2014

person    schedule
comment
Что такое polyline_des? - person Matmarbon; 08.08.2014
comment
Это режим маршрута карты Google, его путь рисования прямо между latlng игнорирует его, если вы не используете его, используйте свою точку маршрута - person ; 11.08.2014