Клуб API Карт

Грамотное использование функции route() в цикле

Пост в архиве.

Вопрос о том, как наиболее грамотно реализовать следующую задачу.

Есть координаты нескольких точек, и нужно узнать расстояние до каждой из них.

 var point = {
  name: "Some place",
  coordinates: [55.75399400, 37.62209300],
  distance: -1
};

 

И есть массив таких точек (points).

for (var pointIndex in points) {
  ymaps.route([myCoordinates, points[pointIndex].coordinates]).then(function(route) {
    var distance = route.getLength()   
    /* points[pointIndex].distance = distance; */
  });
}

 

Но воспользоваться конструкцией "points[pointIndex].distance = distance;" из-за асинхронности мы не можем.

Как же тогда занести информацию о расстоянии в каждый из объектов точки?

4 комментария

для чего так делать? Что за проект у вас?

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

Дело в том, что маршрутизатор в АПИ предназначен для построения и вывода маршрута на карту. Долбить в него в цикле, а каждый вызов ymaps.route это отдельный http-запрос, ради получения расстояний, не выводя эти маршруты, как минимум нарушение условий использования, не говоря про траффик пользователей и скорость подобного решения. Для сортировки вполне достаточно расстояний по прямой.

в geoQuery есть готовый хелпер

https://tech.yandex.ru/maps/doc/jsapi/2.1/ref/reference/GeoQueryResult-docpage/#sortByDistance

Впрочем, эту задачу даже проще решать на уровне БД. Практически все базы имеют spatial-расширения с поддержкой сортировки по расстоянию

Большое Вам спасибо!