Карты в Вашем проекте

    Рост аудитории интернет-пользователей и интернет-проектов выводит геосервисы на новый уровень.
    Если раньше большинство проектов с использованием «карт» оперировали с десятками и сотнями точек, то сейчас уже речь идет о сотнях тысяч точек.
    В статье будут рассмотрены несколько юзкейсов для геосервисов и способы их реализации для 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) на один регион/город. О нем я расскажу в следующей статье.
    • +13
    • 5.9k
    • 8
    Share post
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 8

      0
      Еще можно кластеризовать точки на сервере, отдвая клиенту информацию о кластере, а не обо всех точках. И пользователь не страдает и агрегировать точки можно хитрыми способами. С Растровыми слоями сильно интерактивность страдает.
        +1
        Можно, согласен. Именно так я и делал в одном проекте. Можно даже сделать серверную+клиентскую кластеризацию.
        То есть сами тайлы кластеризовать на сервере, а на клиенте из прореживать, чтобы маркеры на границах тайлов не «слипались».
        Но затраты на серверную кластеризацию все-таки большие, хотя и ее можно кэшировать.
        Дайте ссылку на Ваш проект с серверной кластеризацией.
          0
          Это не публичный проект, да и алгоритм кластеризации там несколько дубовый. Просто если данные уже лежат в postgis к примеру, можно использовать его расширения и кластеризовать точки самим postgis'ом.
            0
            У РосЯмы, если не ошибаюсь, серверная кластеризация: github.com/RosYama/RosYama.2/blob/master/protected/controllers/HolesController.php#L867
          +1
          А где собственно само функциональное сравнение и примеры Google Maps v3 и Я.Карты v2 заявленные в заголовке этой статьи?

          Признаться тока ради этого под кат и глянул ибо актуально стоит ли переходить с Я.Карт v1.1 на новое API 2.0 или Гугл 3.
            0
            По поводу второй версии, то она чуток быстрее и не требует ключа (для плагинов к CMS, например, это важно). Но с документацией напряженка пока, особенно с событиями.
              0
              В следующей статье — 10 опробованных подходов вывода 10000 точек на карту с картинками и работающими примерами для google api 3 и яндекс api 2.
              через пару дней. сейчас надо побороть все-таки яндекс апи
              0
              Я пытаюсь реализовать Ваш способ #2. У меня возникло несколько вопросов:
              1. Для связки tirex+ngunx вы использовали lua модуль nginx-lua-osm от японского разработчика Hiroshi Miura?
              2. Под какую ось это сооружалось?
              3. Apache при этом не нужен?
              4. Правильно ли я понимаю, что tirex нужен для организации метакэша, а mod_tile для управления очередью рендеринга и самого рендеринга с помощью mapnik'а?
              4. Подскажите хороший мануал по настройке Вашего способа #2.

              Only users with full accounts can post comments. Log in, please.