Клуб API Карт

Ожидание конца работы Geocoder

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

Всем привет!

Моя форма принимает в GET-запросе адреса точек маршрута такси, которые тут же с помощью геокодера находит и отметчает на Яндекс-карте. Далее я хочу сразу построить маршрут поездки и вывести его на карте, рассчитать и время пути с учетом пробок. Но столкунулся с тем, что Router не работает с переданным ему массивом точек. Я начал отлаживать, с помощью алертов мониторить эти точки, оказалось, что массив еще не проинициализирован. Правильно ли я понял, что Geocoder работает асинхронно? Как тогда дождаться конца геокодирования всех точек, чтобы сразу после этого передать в Rоuter массив точек? Или я что-то тут капитально не понимаю?

P.S. Вот такой код:

var router = new YMaps.Router(point, [],  { viewAutoApply: true } ) ;
        map.addOverlay(router);
        YMaps.Events.observe(router, router.Events.RouteError, function (link, number) {
               alert('Не удается проложить маршрут до точки № ' + number);
        }) ;
        YMaps.Events.observe(router, router.Events.Success, function ()
        {
            alert('Wow!');
        }) ;

Ни RouteError, ни Success не сигнализируется, так как никакого сообщения мне не выводится.

P.P.S. point - это массив класса YMaps.Placemark.

14 комментариев

да, геокодер работает асинхронно нужно обрабатывать событие Load.

Кстати, роутер умеет сам геокодировать текстовые адреса,

так что можно обойтись и без геокодирования

Но мне нужно точки маршрута промаркировать на карте метками с цифрами. Роутер это сможет сделать?

Далее, как бы не очень удобно код для Роутера помещать в Load() для Геокодера - точек-то несколько. Может, есть какой-то метод определить, что все заданные колбэки уже отработали, в противном случае дождаться их завершения? Хотя над Load(), может быть, подумаю, тогда надо точно в нем определять, последняя ли текущая точка в списке или нет.

P.S. Ну вообще проблемы такой, с определением, последняя ли точка или нет, на самом деле нет. Так как геокодирование у меня выполняется в отдельной функции, вызываемой отдельно для каждой точки. Для последней точки можно просто передавать специальный параметр, типа значения 1, по которому и будет запускаться прокладка маршрута.

Но вот такой еще вопрос: геокодинг отрабатывается яндекс-картами последовательно? Или это может делаться и параллельно, и есть вероятность, что какая-то точка может отработаться раньше какой-нибудь предыдущей? Тогда этот метод не пройдет!

 

Сделал так, все равно Router не работает - ни успеха, ни ошибки! В чем может быть причина?

Массив Placemark'ов он вообще принимает?

 

там по ссылке есть примеры и с массивом GeoPoint-ов

и с массивом адресов

 

Но мне нужно точки маршрута промаркировать на карте метками с цифрами. Роутер это сможет сделать?

Аналогично по ссылке есть пример с маркировкой точек

Так, с геопойнтами я разобрался, я формирую их массив до этого, потом роутеру его передаю.

Маркировку в примере увидел с помощью SetIconContent. Но значки ставятся по умолчанию. Можно ли их не показывать? Такой опции не нашел. Как это сделать?

Дело в том, что при геокодировании у меня уже делаются метки на карте, метки роутера мне уже лишние.

"Но вот такой еще вопрос: геокодинг отрабатывается яндекс-картами последовательно? Или это может делаться и параллельно, и есть вероятность, что какая-то точка может отработаться раньше какой-нибудь предыдущей? Тогда этот метод не пройдет!"

У меня такое ощущение, что так и есть: жму на F5, данные одни и те же должны быть. То срабатывает маршрутизатор, то нет, тогда мне файрбаг выдает сообщение об ошибке где-то в недрах Яндекс-карты API, что какой-то s не определен. Я подозреваю, что просто какая-то точка не отработалась геокодером. Как быть?

я вам пытаюсь объяснить что геокодирование не нужно

для построения маршрута,

передавайте в роутер не точки, а адрес

Я Вас понял. Может быть, Вы правы. Но просто же хочется иметь код, работающий с маркировкой точек в одном месте, а не дублировать его. Просто это код для маркировки уже есть в геокидоровании, он нужен, чтобы можно было задавать точки в форме, и они сразу бы отображались на карте, когда маршрут еще не построен. Кроме того, если пользователь захочет изменить какие-то точки маршрута, когда он уже проложен (допустим, ошибку допустил в адресе или вдруг решил добавить какую-то промежуточную точку в поездку), хотелось бы все неизмененные точки сохранить, они не должны убираться с карты, а маршрут при этом надо сбросить. Придется что ли выдирать эти точки обратно из результатов маршрутизации, чтобы повторно не геокодировать? А ведь куда проще бы было просто убрать оверлэй маршрута, а один измененный адрес просто обновить

"Но вот такой еще вопрос: геокодинг отрабатывается яндекс-картами последовательно? Или это может делаться и параллельно, и есть вероятность, что какая-то точка может отработаться раньше какой-нибудь предыдущей? Тогда этот метод не пройдет!"

именно параллельно, вам будет нужно реализовать построение маршрута только после того как оба адреса прогеокодируются,

а синхронизация этих событий не такая простая задача.

поищите в клубе "множественное геокодирование"

там был пример подобного решения

 

 

Хорошо, спасибо. Фишка ведь еще и в том, что адреса может быть не обязательно два, а до девяти включительно!

Гм, нашел хороший пример среди примеров в документации, спасибо за наводку. Там использовался счетчик вызовов геокодера, который наращивался от нуля при каждом вызове гелкодера, а Load() каждого уменьшался на 1. Когда он достигал 0, делалось требуемое действие - ведь точно известно, что все отработали. Совсем и не сложно!

Ну вообще, это даже пример написания собственного класса для множественного геокодирования, но я уж такое делать не буду.

Метод сработал, он универсальный, при том что очень простой (я мог бы и сам догадаться). Теперь только осталось как-то убрать отрисовку значков маршрутизатором.

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