Клуб API Карт

LoadingObjectManager событие окончания загрузки объектов с сервера

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

Тривиальная задача отобрать на карте результаты выборки - отлично, 10-ки тысяч объектов за секунды.

Добавляем вторую часть, вывести первые 10 из видимой области карты в соседний div и сталкиваемся с проблемой:

Оказывает нету события которое бы говорило что метки на карте обновлены.

-------------------------

Собственно вопросы:

1. Как узнать когда objectManager начал или завершил свою работу по загрузке объектов на карту. Событие overlaychange не работает.

2. Ка получить getBounds() у этого результата выборки чтобы отпозиционировать карту?

 

ПС

---------------

Решения через другие события все перепробывал, это:
1. событие boundschage у самой карты - решение рабочее, но вызывает цикличность, когда активный элемент вызывает изменение положения карты (открытие балуна)

2. свой эвент невозможно встроить в нужную точку событий. Событие после: (объекты загрузились и карта сменила положение относительно загруженных)

 

Единственное решение которое я вижу это узнать когда загрузились объекты через менеджер, получить их видимую область и вывести первые 10 в список, проблему с окрытием балуна решает опция viewportMargin, которое предотвратит повторную загрузку списка объектов при открытии балуна и смещении карты.

 

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

И еще вопрос: Как создать индикатор загрузки меток через менеджер.

Непонятно, как это событие поможет.

LOM не загружает данные повторно, при смене масштаба, если он уже их загрузил, поэтому ваш список не будет перестраиваться.

Используйте "boundschange" карты

а как отделить в событии boundschange событие открытие балуна и сдвига карты?

Дело в чем:
1. Загружаем данные (карта сдвигается относительно загруженных данных)
2. Первые 10 видимых выводим в блок
3. Открываем балун -> карта сдвигается что приводит к запуску п.1

 

У меня сделано так что каждое событие отчищает LOM

yMap.geoObjects.removeAll();
yMap.geoObjects.add(objectManager);

Понимаю что так не правильно, но в действия существует ограницение по показу маркеров, которое через filter не реализовать.

т.е. LOM соединен с поисковой строкой фильтрации, который каждый раз запрашивает разные данные у Apache Solr:


objectManager = new ymaps.LoadingObjectManager('.../map_search_wrap/'+searchstring+'?bbox=%b'+'&place='+place

searchstring - данные формы поиска,
place - значение введенное в элемент управления поиском

оба значения динамически меняются, что приводи к необходимости уничтожать маркеры.

 

 

Отделять не нужно, это будет архитектурная ошибка.

Не важно, кто и как сдвинул карту – открывшийся балун, пользователь, или ваш код.

Если карта сдвинулась (любым способом) надо обновлять ваш список объектов.

Другое дело что делать это при каждом вызове события конечно не надо. Надо использовать чтото типа debouncing decorator для вызова обновления списка

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

 А при изменении условий фильтрации уже обновлять сразу оба элемента.

И еще вопрос: Как создать индикатор загрузки меток через менеджер.

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

Вам точно нужен LOM?

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

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

Геоколлекция точно нет, так как количество объектов на карте будет превышать миллионы, и ОМ отмели тоже по тем же причинам.

 

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

 

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

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

При таких объемах надо кластеризовать на сервере. Тогда я бы смотрел в сторону RemoteObjectManager-a

Тут и с фильтрацией будет проще, т.к. данные каждый раз запрашиваются

Тогда в это ветке последний вопрос, если есть под рукой инфа про написание своего кластеризатора тыкните плиз носом в нее )))

Серверный кластеризатор я делал, правда под NodeJS.

Другой вопрос что на объемах данных 100 000+ надо уже на уровне запроса к БД выбирать сгруппированные в кластеры точки.

Вариант вытаскивать миллион точек и передавать их в кластеризатор это нежизнеспособно. Вы быстро упретесь в ограничение объемов данных.

Я так и думал изначально, по эмпирическим ощущениям мне надо знать только текущий bbox и масштаб карты чтобы во время запроса к БД сформировать сборную солянку из кластеров и одиночных объектов.

Спсибо за ответы, очень информативно.