Клуб API Карт

objectManager.setFilter() на большом количестве меток

patrikfoldes
30 декабря 2014, 17:33

Здравствуйте!

 

У нас есть карта, реализованная с использованием API Яндекс.Карт 2.1, есть база данных меток (25.000+).

Сейчас карта работает таким образом - при перетаскивании или изменении зума отсылает на сервер данные видимой области + несколько фильтров по свойствам, сервер возвращает метки для видимой области, но после длительной работы с картой когда подгружены уже почти все метки это начинало ощутимо тормозить + нагрузка на сервер постоянная.

Прочитал про objectManager, понял, что это как раз то, что мне нужно в данной ситуации. Сделал json-файл с базовыми свойствами меток (все остальное подгружается при клике на балун, ничего лишнего), для 25.000 меток сжатый файл весит всего 200кб. Загрузил его через objectManager на карту, все отработало моментально, радости нет предела, и тут я решил попробовать фильтр.

 

objectManager.setFilter('properties.t == 44');

 

При небольшом зуме, когда видно пару сотен меток, это заняло 4-5 секунд.

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

Я очень расстроился, ведь этот функционал преподносится вами как решение для большого количества меток.

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

UPD:

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

Например такой код работает очень быстро:

objectManager = new ymaps.ObjectManager();
objectManager.add(json); // 25000 меток
objectManager.setFilter('properties.t == 44');
myDragMap.add(objectManager);

Особенность в том, что фильтрация происходит до добавления меток на карту, при таком раскладе все отрабатывает очень быстро. Однако, если пытаться фильтровать метки когда они уже добавлены, все начинает тормозить. Я попробовал перед фильтрацией уже добавленных меток просто удалять эти метки и добавлять заново с применением фильтра, пробовал удалять вообще 
objectManager с карты и добавлять заново, и в каждом случае получаю задержку такую же как при применении фильтра на уже существующих на карте метках, например все эти три способа тормозят одинаково:

myDragMap.remove(objectManager);
objectManager.removeAll();
objectManager.remove(json);

Отсюда я могу сделать вывод, что тормозит применение фильтра на уже размещенное на карте большое количество меток из-за самого механизма удаления меток с карты. Т.е. как добавлять метки на карту очень быстро вы сделали - а вот как удалять их так же быстро - такого решения нету. 

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

Здравствуйте, да, это не круто, что фильтр так долго работает, надо поправить. Но выяснить, почему так и починить, мы сможем уже в следующем году)

Хорошо, если от меня требуются какие-то дополнительные сведения готов предоставить в любой момент. Жду с нетерпением информации по этому вопросу, спасибо, с наступающим!

Вопрос все еще очень актуален

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

Например такой код работает очень быстро:

objectManager = new ymaps.ObjectManager();
objectManager.add(json); // 25000 меток
objectManager.setFilter('properties.t == 44');
myDragMap.add(objectManager);

Особенность в том, что фильтрация происходит до добавления меток на карту, при таком раскладе все отрабатывает очень быстро. Однако, если пытаться фильтровать метки когда они уже добавлены, все начинает тормозить. Я попробовал перед фильтрацией уже добавленных меток просто удалять эти метки и добавлять заново с применением фильтра, пробовал удалять вообще objectManager с карты и добавлять заново, и в каждом случае получаю задержку такую же как при применении фильтра на уже существующих на карте метках, например все эти три способа тормозят одинаково:

myDragMap.remove(objectManager);
objectManager.removeAll();
objectManager.remove(json);

Отсюда я могу сделать вывод, что тормозит применение фильтра на уже размещенное на карте большое количество меток из-за самого механизма удаления меток с карты. Т.е. как добавлять метки на карту очень быстро вы сделали - а вот как удалять их так же быстро - такого решения нету. 

Да, все так как вы написали - тормозит удаление меток с карты. Оптимизируем этот момент в одном из будущих релизов.

Такая же ситауция.На карте около 6500 точек. При objectManager.removeAll() браузер подвисает на 5-6 секунд. Причем, на хроме это менее заметно, ФФ же виснет намертво.

Да, спасибо за сообщение, будем оптимизировать в ближайших релизах.

К вам у меня тоже вопрос)

А браузер нормально себя чувствуется при добавленных 6500 точек? Вообще он уже должен начинать сильно подтупливать.

Как ни странно прекрасно себя чуствует - кластеры спасают :)

Ага, я что-то совсем не подумала, что и в том и другом кейсе используется кластеризация. Действительно все так, как вы пишете. Баг поправили, выедет наверное через релиз.

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

Но у меня остался вопрос.

И до рефакторинга добавление меток работало медленнее, чем удаление меток. Как так вышло, что у вас добавленные 25000 меток работали хорошо?

Здравствуйте, не знаю, как так вышло, могу вам скинуть ссылку на json-файл с данными которые добавляются, только если есть возможность дайте контакт, не хотелось бы в публичку его светить. Ощутимой задержки при их добавлении я не видел в Хроме последней версии.

Я могу уже получить доступ к новой версии API с этими исправлениями?

У нас есть очередь, в которой фичи тестируются и идут в публичный релиз. Этот рефакторинг свежий, поэтому ему еще придется отлежаться и пройти через тестировщиков. Так что он выйдет скорее всего через релиз, пока в публичном доступе его нет.

Если несложно, пришлите мне ссылку на страницу, где можно посмотреть добавление объектов или просто пришлите код. Адрес соответственно mari-na-bzzz@yandex.ru

Отправил, еще один вопрос - где можно тречить появление новых версий API с чейнджлогом? Как не пытался, найти такую страницу не смог.

Мы пишем про обновления в клубе, спрошу еще у ребят, нет ли какого-то отдельного канала для отслеживания версий

Добрый день. Вы можете следить за обновлениями через RSS-поток — http://clubs.ya.ru/mapsapi/rss/posts.xml?tag=150003107 В этот поток попадают новости только про обновления API. 

Спасибо! С нетерпением ждем эти правки в релизе!