Клуб API Карт

Проблемы с GeoObjectCollection

Евгений Эрман
17 октября 2013, 12:01

Добрый день.

 

Пытаюсь вывести на карту набор объектов с определенными свойствами. Для их хранения использую GeoObjectCollection. (http://2d-3d.ersystems.ru/index-2.html)

Возникла непонятная проблема в куске кода:

 

coder.geocode(coords)
    .then(function (res) {
            // Сервер вернул нам результат для всех запрошенных адресов.
            for(var i = 0; i < res.geoObjects
                .getLength(); i++) {
                var colls = doulist[i];
                // Создаём текст для показа
                $('#menu').append(
                    '<li>' +
                    '<a href="#" onClick="return go_point(' +
                    i + ");" + '\">' +
                    i + '. ' + colls[0] +
                    '|' + colls[1] +
                    '</a></li>');
                // Геообъект - уже готовый маркер, полученный от сервера.
                var geo = res.geoObjects
                    .get(i);
                // Сохраняем объект маркера для простого поиска позже.
                doulist[i].geo = geo;
                // Заменяем стандартный текст в окошке при клике.
                geo.properties.set(
                    'iden', i);
                geo.properties.set(
                    'iconContent', i);
                geo.properties.set(
                    'balloonContentBody',
                    '<div style="font-size:12px;"><strong>Адрес:</strong> ' +
                    colls[1] +
                    '<br /><strong>Количество заявлений в очереди по возрастам, чел.</strong><ul>' +
                    '<li><strong>до 1 года:</strong> ' +
                    colls[3] +
                    '<li><strong>от 1 года до 2 лет:</strong> ' +
                    colls[4] +
                    '<li><strong>от 2 лет до 3 лет:</strong> ' +
                    colls[5] +
                    '<li><strong>от 3 лет до 4 лет:</strong> ' +
                    colls[6] +
                    '<li><strong>от 4 лет до 5 лет:</strong> ' +
                    colls[7] +
                    '<li><strong>от 5 лет до 6 лет:</strong> ' +
                    colls[8] +
                    '<li><strong>от 6 лет до 7 лет:</strong> ' +
                    colls[9] +
                    '<li><strong>Итого:</strong> ' +
                    colls[2] +
                    '</ul></div>');
                geo.properties.set(
                    'balloonContentHeader',
                    '<div style="color:#ff0303;font-weight:bold">' +
                    colls[0] + '</div>'
                );
                if(colls[2] < 100) {
                    geo.options.set(
                        'preset',
                        'twirl#greenIcon'
                    );
                } else if(colls[2] <
                    200) {
                    geo.options.set(
                        'preset',
                        'twirl#lightblueIcon'
                    );
                } else if(colls[2] <
                    300) {
                    geo.options.set(
                        'preset',
                        'twirl#greyIcon'
                    );
                } else {
                    geo.options.set(
                        'preset',
                        'twirl#redIcon'
                    );
                }
                myCollection.add(geo);
            }
            // Ставим все маркеры на нашей карте.
            myMap.geoObjects.add(
                myCollection);
        },
        function (err) {
            alert(err)
        }
)

 

всего объектов - 103, но после добавления в коллекцию 52 объекта цикл завершает работу. Причем, если комментирую строчку

myMap.geoObjects.add(myCollection);

цикл нормально выполняется все 103 раза. Мистика какая-то....

4 комментария
Подписаться на комментарии к посту

Никакой мистики

Просто геообъекты и коллекции в АПИ реализуют интерфейсы IChildOnMap и IParentOnMap, т.е. могут иметь только одного родителя.

В практическом смысле это означает что при добавлении геообъекта или коллекции в другую коллекцию, она удаляется из текущей коллекции.

Таким образом когда вы делаете 

myCollection.add(geo);

В следующий раз Вы будете работать уже с +1 индексом, т.к. коллекция "схлопнет" индекс удаленного элемента.

 

Решается 2-мя способами

1. созданием своих меток по координатам тех что вернул геокодер.

2. другим способом перебора, например с помощью while

 

while(geo = res.geoObjects.get(0)) {
   ....
    myCollection.add(geo);
}
Евгений Эрман
17 октября 2013, 12:58

Спасибо огромное - помогло!

P.S.: Я правильно понимаю, что можно было еще цикл for дикриментный сделать, т.е. перебирать объекты с конца к началу?

Наверное можно, но декриментальный перебор я обычно тоже через while делаю. For для этого очень "многобукв" ...

 

var len = res.geoObjects.getLength();

 

while(len--) {

    ...

}

 

Можно еще для перебора использовать geoQueryResult (неизменяемый объект выборки).
http://api.yandex.ru/maps/doc/jsapi/2.x/ref/reference/GeoQueryResult.xml#each