Клуб API Карт

Перегнать массив адресов в метки

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

Здравствуйте, вопрос состоит в следующем: Как правильно перегнать массив адресов в массив меток на карте? Сейчас использую следующий способ:

function ymap(msg) {
    var arAdress = eval(msg);

        // Создание обработчика для события window.onLoad
        YMaps.jQuery(function () {
            // Создание экземпляра карты и его привязка к созданному контейнеру
            var map = new YMaps.Map(YMaps.jQuery("#map")[0]);

            // Создание объекта геокодера

            map.addControl(new YMaps.TypeControl());
            map.addControl(new YMaps.ToolBar());
            map.addControl(new YMaps.Zoom());
            map.addControl(new YMaps.MiniMap());
            map.addControl(new YMaps.ScaleLine());
            map.addControl(new YMaps.SearchControl());

            for(var Element in arAdress){

                    var street = arAdress[Element];
                    var geocoder = new YMaps.Geocoder(street);

                    // По завершению геокодирования инициализируем карту первым результатом
                    YMaps.Events.observe(geocoder, geocoder.Events.Load, function (geocoder) {
                            if (geocoder.length())
                            {
                                map.setBounds(geocoder.get(0).getBounds());

                                var geoResult = geocoder.get(0);

                                var point = geoResult.getCoordPoint();
                                // Создает метку и добавляет ее на карту
                                var placemark = new YMaps.Placemark(point, {style:'default#redPoint'});

                                placemark.setBalloonContent(street);
                                map.addOverlay(placemark);
                                //Открыает балун
                                placemark.openBalloon();

                            }
                         });
            }

      });
}

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

6 комментариев
решение 1.
for(var Element in arAdress){
замените на
YMaps.jQuery.each(arAdress,function(Element){

это стандарный прикол замыканий и области дейсвия переменых..

решение 2(правильное)
сделайте например так..
var geocoder = new YMaps.Geocoder(street);
geocoder.holdedElement=street;

YMaps.Events.observe(geocoder, geocoder.Events.Load, function (geocoder) {
                            if (geocoder.length())

в geocoder.holdElement - будет именно тот елемент что вам нужен. и без разных заворотов цикла в функцию..
не дописал..
далее сделайте просто
geocoder.holdElement.coordinated=geoResult.getCoordPoint();

дождитесь отрабоки геокодера любым способом( счетников, таймаутом на 10 минут и тд)
после чего - сохраните массив arAdress в файл( document.write(JSON.stringify(arAdress))) или ajax запрос на сервер

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


итог - вариант 1 и часть 2 решают проблемы области и действия переменых.

вариант 2 решает проблему геокодинга и старта карты только после него. Так как больше не требуется.
Можно и автоматизировать - собираете файл адресов. Открываете одно окошко - оно геокодирует и сохраняет результат.
Сделал, как Вы описывали в перврм сообщении:
geocoder.holdedElement=street;

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

Далее можете сформировать YMapsML-файл и добавлять его на карту. В этом случае метки будут добавляться на карту следующим образом:

var ml = new YMaps.YMapsML("путь до файла");
map.addOverlay(ml);
Шерстить огромную и очень тяжелую БД я не имею возможности, при том что запрос по обычно содержит до десятка адресов, удобнее все это геокодировать на месте. Однако спасибо за еще один вариант!
Есть еще пример множественного геокодирования:
http://api.yandex.ru/maps/jsapi/examples/multiplygeocoding.html

Возможно, что он вам тоже будет интересен.