Рост аудитории интернет-пользователей и интернет-проектов выводит геосервисы на новый уровень.
Если раньше большинство проектов с использованием «карт» оперировали с десятками и сотнями точек, то сейчас уже речь идет о сотнях тысяч точек.
В статье будут рассмотрены несколько юзкейсов для геосервисов и способы их реализации для google API 3 и нового yandex API 2.

Показываем до 100 точек.

Самый распространенный юзкейс – показать на карте адреса офисов компании. Обычно — до пары десятков.
Реализация – самая простая, «коробочная». На ней не будем останавливаться. И yandex и google отлично справляются с этой задачей, не перегружая ни разработчика, ни пользователя.

От нескольких сотен до одной-двух тысяч точек.

Способ реализации зависит от плотности точек.

Юзкейс 1: справочники по узкой тематике (например, «все банки Москвы») и т.д.

Например, если взять «все банки Москвы» с 2000 точками (условно), то плотность будет довольно большой. В один вьюпорт среднего зума будет выводиться почти все 2000 точек. В этом случае поможет кластеризация точек. Для гугла есть несколько свободных библиотек для кластеризации (например, MarkerClusterer), а в новом API от Яндекса кластеризация интегрирована в API и может быть легко подключена несколькими строками кода. И хотя в Яндекс API дефолтный вид кластера может быть вопросом неоднозначным, почти все возможно настроить.
Основной минус (как и плюс) такого способа реализации в том, что все данные необходимо загрузить одномоментно. Отсюда, страдает пользователь, который ожидает загрузки карты, но радуется админ, глядя на нагрузку на сервер.
Фильтрация точек также легко осуществляется на клиенте.

Юзкейс 2: точки распределены по большой территории

Если точки распределены по большой территории (например, «Магазины Спортмастер в России»), то логично будет сделать меню с выбором города, либо отдельную карту (не интерактивную) с нанесенными городами. По клику на город показывать уже интерактивную карту с метками. Кластеризация при таком подходе может и не понадобиться, достаточно повесить на событие смены зума listener, который вызывает меню выбора города на достижении определенного минимального зума.
При таком количестве точек оба API справляются нормально, без больших тормозов. К плюсам гугла можно отнести менее контрастную карту, на которой лучше будут видны Ваши маркеры. К плюсам Яндекса – более точная (по слухам) карта и большее количество отрисованных городов в России.
Как Google API 3, так и Яндекс Api 2 используют canvas, то есть рисование меток непосредственно на клиенте (правда, для яндекса это надо специально включать).

Теперь про зубную боль в сердце – ie. Огромное количество dom-элементов (а для каждой точки — это 3-4 объекта). Когда число объектов достигает 2000-3000 — это убивает браузер.
Единственным возможным костылем может стать FlashCanvas. При использовании его на ie были получены очень хорошие результаты, но все равно не обошлось без «косяков».

Много, много точек

Способов реализации – несколько.

Способ 1.

Воспользоваться сервисом кластеризации, например: v2.maptimize.com/
Дорого, некрасиво, да и вообще – не наш метод.

Способ 2.

Сделать свой сервер рисования тайлов.
Используем связку PostGIS + Tirex + Mapnik2 + Mod_tile + Nginx
Все очень быстро, но есть только несколько существенных ограничений:
1. Обновление. При добавлении/удалении точек Вы придется заново рисовать очень много картинок. Обычно, это реализуется удалением из кэша устаревших картинок, а счастливый пользователь, первым решивший посмотреть этот участок карты, ждет отрисовки недостающих тайлов. Я меня получалось отрисовывать до 100 тайлов в секунду с 200 точками на каждом на Xeon Quad-Core. Поэтому, при нечастом обновлении, все хорошо.
2. Невозможность фильтрации.
Да, можно нарисовать несколько наборов тайлов. Но в любом случае, при количестве N категорий, вы:
а) должны сделать N наборов тайлов
б) не сможете показать несколько категорий сразу (теоретически – возможно сделать несколько слоев, но получается плохо из-за наложения теней друг на друга и увеличенном времени загрузки).
Вывод: этот способ годится для наборов однотипных данных без возможности фильтрации. Например – «все отделения Почты России».

Способ 3.

Рисуем тайлы на лету.
Смысл метода в том, чтобы держать часто используемые наборы тайлов (без фильтрации, с фильтрацией по основным категориям) – в кэше. А сложные фильтры (например, банкоматы «Сбера» + банкоматы «ВТБ») рисовать «на лету». В этом случае, размер метки можно сделать хоть 5х5 и рассыпать их по всей карте. Кластеризация тут становится ненужной.
Метод требует мало программирования и много железа. То есть мало багов и хорошая стабильность при высоких затратах на железо. Один «графический» сервер сможет обслужить 100-200 одновременных коннектов.

Способ 4.

Есть еще один способ — комбинированный — позволяющий отображать очень много (до 10000) на один регион/город. О нем я расскажу в следующей статье.

Комментарии