Клуб API Карт

Найдено на тему «статьи»:
Районы-кварталы
tech.yandex.ru
24 марта 2015, 16:14

Как многие знают, в составе API Карт для России, Украины, Беларуси и Казахстана есть модуль «Регионы», который позволяет выделить район, черту города или область. Но для ряда специальных задач вы можете применять альтернативные решения. Разработчик интерфейсов API Карт Антон Корзунов в свободное от работы время создал для своего сайта esosedi.ru модуль OSMeRegions. Это библиотека и сервис, который позволяет отображать на карте данные OpenStreetMap об административном делении. Рассказ Антона про OSMeRegions опубликован на Хабрахабре, код модуля доступен на GitHub, так что вы можете задействовать его с нашим API.


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

регионы,API 2.1,статьи,новости,модули
Вредные советы
D.Abramov8
31 января 2015, 01:29

Доброй ночи!
Тут читаю вредные советы на хабре...и что-то запутался...
Совет:
"Идеальный вариант – это печатать конструкции JavaScript с помощью PHP"
полезный или вредный?

С уважением,
Дмитрий

2 комментария
PHP,Javascript,статьи
ObjectManager в API Яндекс.Карт
a.chebotareov
19 ноября 2014, 19:31

Как быстро отрисовать 10000 меток на карте и не затормозить всё вокруг. Как и зачем мы делали ObjectManager — читайте в новой статье на Хабрахабре. Автор статьи — создатель модуля и руководитель группы разработки визуальных компонент API Карт, Марина Степанова.

Перед разработчикам, которые используют API Яндекс.Карт, довольно часто встаёт задача отобразить много объектов на карте. Действительно много — порядка 10 000. Причем эта задача актуальна и для нас самих — попробуйте поискать аптеки на Яндексе. На первый взгляд кажется: «А в чем собственно проблема? Бери да показывай». Но пока не начнешь этим заниматься, не поймешь, что проблем на самом деле целый вагон.

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

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

03c40157090c4d039fe324e23a684591.png

Также от большого количества данных страдают ресурсы, посвященные недвижимости. Яркий пример – Cian.ru.

Мы сами внутри Яндекса до недавнего времени советовали смежным командам различные «хаки» и приемы для показа множества точек через API. Яркие примеры – Яндекс.Недвижимость и Яндекс.Такси.

Пункт 1. В чем собственно проблема?

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

33e83ec6f56341a79c0adb1de12f9b1a.png

Клиент (например, Safari на iPhone) запрашивает с сервера страницу index.html. Страница представляет собой документ вот с таким кодом:

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <script src="//api-maps.yandex.ru/2.1/?lang=ru_RU" type="text/javascript"></script>
    <script type="text/javascript">
        ymaps.ready(init);

        function init () {
            var myMap = new ymaps.Map('map', {
                center: [55.76, 37.64],
                zoom: 10
            });
        }
    </script>
</head>
<body>
    <div id="map"></div>
</body>

Теперь усложняем задачу. У нас есть база данных, в которой хранятся адреса болельщиков «Зенита». И мы хотим показать на карте адреса этих болельщиков.


Решение задачи «в лоб»:

  • Делаем выборку из базы данных, получаем 1 млрд адресов.
    • Дописываем в файл index.html массив, содержащий весь миллиард адресов.
    • Передаем этот файл на клиент.
  • На киенте перебираем данные массива и рисуем для каждого элемента метку на карте.

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

    • Вес файла index.html увеличится до нескольких Мб и у пользователя страница будет открываться по несколько секунд.
    • Зачем передавать на клиент ВСЮ базу, если нужно показать только метки для Москвы?
    • Зачем рисовать на карте ВСЕ метки, если человек увидит только десятую их часть?
    • Если на карте нарисовать около 100-200 меток обычным способом, карта будет тормозить.
  • Можно загружать метки постепенно, пачками, чтобы канал не забивался и браузер успевал эти метки отрисовывать?

Мысль получает два направления:

      1. Нужно уметь определять, какие данные видит пользователь и запрашивать только нужное.
      2. Когда это нужное пришло, его надо оптимально отрисовать.

В API Яндекс.Карт сто лет назад был сделан инструмент для решения этих задач – технология активных областей. Кому интересно подробно, почитайте руководство разработчика. 

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

С помощью хотспотов, например, рисуются пробки на maps.yandex.ru. На этой же технологии сделан сайт bankomator.ru.

У этой технологии есть несколько существенных минусов

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

fba4da37164742cdbf44a645228ee962.png

2. Абсолютная негибкость. Невозможно «приподнять» метку при наведении на нее курсора. Невозможно быстро поменять на клиенте внешний вид меток. Короче – на любой чих надо просить сервер перегенерировать картинку.

Поэтому пользователи крутились, как могли, без хотспотов – передавали наборы единичных объектов на клиент пачками, через таймаут. При этом на клиенте их снова ждали проблемы. Если вы передали на клиент 1000 точек, как их отрисовать?

Из каждой точки нужно было сгенерировать объект ymaps.Placemark и добавить его на карту. Можно было добавить метки в кластеризатор (ymaps.Clusterer) и добавить откластеризованные метки на карту. Тут надо обратить внимание, что при кластеризации 10 000 точек нужно сначала эти 10 000 точек инстанцировать, а потом передать в кластеризатор. То есть метка может не показаться на карте, так как войдет в кластер, но мы все равно потратим время на ее инициализацию.

Подытожив все эти дела, мы решили написать модуль, который бы позволил:

    1. Быстро и легко отрисовать на клиенте большое количество точек.
    2. Избежать лишних инициализаций при работе с точками на клиенте.
    3. Загружать данные на клиент строго по требованию.

И мы это сделали. Мы котики.

Пункт 2. Рисуем метки быстро

Чтобы научиться рисовать метки быстро, надо было понять, какие проблемы кроются в текущем, уже существующем решении. Давайте посмотрим, что может делать объект ymaps.Placemark:

    1. Он умеет рисоваться на карте.
    2. У него есть свой менеджер балуна placemark.balloon.
    3. У него есть свой менеджер хинта placemark.hint.
    4. У него есть редактор, который позволяет перетаскивать метку и фиксировать ее координаты placemark.editor.

Кроме того, метка динамически реагирует на любое изменение внешней среды – изменение опций, данных, проекции карты, смена масштаба карты, смена центра карты и многое, многое другое. Такие вот у нас могучие плейсмарки.

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

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

Второе озарение пришло, когда мы думали над проблемой лишних программных инициализаций. Вспоминаем рассказ выше, где-то в районе вот такой картинки.

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

 

Мы решили, что будем хранить пользовательские данные об объектах (по факту в JSON), а программные сущности для объектов будут создаваться только тогда, когда какой-либо объект нужно будет отрисовать на карте.

После комбинации этих идей и некоторой разработки родился новый модуль API для отображения большого количества точечных объектов – ymaps.ObjectManager.

На вход этого менеджера скармливается JSON-описание объектов.

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

Для отрисовки меток и кластеров на карте мы взяли только часть объектаymaps.Placemark (а именно ymaps.overlay.*), которая отвечала только за отображение метки на карте. Всю инфраструктуру типа балунов и хинтов мы вынесли в единый общий компонент.

Эти приемы позволили нам неплохо продвинуться в вопросе отрисовки большого числа меток на клиенте. Вот какие мы получили приросты по скорости:

1d8d3157f4324a66b46c2381296a6be7.png

График 1. Скорость создания и добавления объектов на карту с последующей асинхронной отрисовкой их видимой части

    1. Создание 1000 меток и добавление их на карту, все метки видны.
    2. Создание 1000 меток и добавление их на карту с кластеризацией, все метки видны.
    3. Создание 10000 меток и добавление их на карту с кластеризацией, все метки видны.
    4. Создание 50 000 меток и добавление их на карту с кластеризацией, все метки видны.
    5. Создание 50 000 меток и добавление их на карту с кластеризацией, видны 500 объектов.
    6. Создание 50 000 меток и добавление их на карту без кластеризации, видны 10 000.

 1b06d3c0650c43949bb45a2ee88dbec0.png

График 2. Скорость создания и добавления объектов на карту с последующей синхронной отрисовкой их видимой части

  1. Создание 1000 меток и добавление их на карту, все метки видны.
  2. Создание 1000 меток и добавление их на карту с кластеризацией, все метки видны.
  3. Создание 10000 меток и добавление их на карту с кластеризацией, все метки видны.
  4. Создание 50 000 меток и добавление их на карту с кластеризацией, все метки видны.
  5. Создание 50 000 меток и добавление их на карту с кластеризацией, видны 500 объектов.
  6. Создание 10 000 меток и добавление их на карту без кластеризации, видны 2000.
  7. Создание 5000 меток и добавление их на карту без кластеризации, видны 1000.

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

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

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

Итак, мы научились быстро-быстро рисовать и кластеризовать точки на клиенте. Что дальше?

Пункт 3. Оптимально подгружаем данные

Помните пример про болельщиков «Зенита»? Мы решили проблему отрисовки данных на клиенте, но никак не решили проблему, связанную с оптимальной подгрузкой этих данных. Мы начали собирать типовые задачи пользователей API. По итогам исследований мы получили два типовых кейса:

  • У человека на сервере много данных, он хочет показывать их на клиенте, но подгружать данные по мере надобности.
  • Разработчик подготавливает данные на сервере (например, реализует серверную кластеризацию) и хочет показывать на клиенте результаты этой обработки.

Для решения этих кейсов были написаны модули LoadingObjectManager и RemoteObjectManager соответственно.Оба модуля основаны по сути на реализации ObjectManager, но имеют ряд различий в алгоритме загрузки и кеширования загруженных данных.

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

Данные хранятся на клиенте в pr-дереве, поэтому выборки даже для большого количества данных делаются довольно шустро.

Теперь обсудим вариант номер два – отображение на клиенте результатов серверной кластеризации. Допустим, вы написали серверную кластеризацию меток. Также вы написали скрипт, который по запросу от клиента умеет отдавать кластеры и единичные метки, не вошедшие в состав кластера.

Вам остается только создать инстанцию RemoteObjectManager и прописать в нем путь до этого чудо-скрипта. RemoteObjectManager будет работать почти так же, как и LoadingObjectManager. Разница будет только в том, что мы будем перезапрашивать данные с сервера при каждой смене зума.

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

Если с сервера передается описание метки-кластера, то на клиенте эти метки подцепят всю инфраструктуру из API – для кластеров нарисуются специальные значки, для них будут работать все стандартные поведения и так далее и тому подобное.

Пункт 4. Размышления на тему серверной реализации

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

1. Хранение информации об объектах на сервере в статических файлах

Клиентский код оперирует данными исключительно потайлово. Тайл – это некоторая нумерованная область на карте. Подробнее про нумерацию тайлов можно прочитать в нашей документации.

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

У клиентского модуля есть настройки, которые заставляют отправлять запросы за каждым новым тайлом по отдельности. Чем это ценно? Да тем, что мы получаем конечное число вариантов запроса клиента на сервер.

zoom=0, tile=[0, 0]
zoom=1, tile=[0, 0]
zoom=1, tile=[0, 1]
zoom=1, tile=[1, 0]
zoom=1, tile=[1, 1]
zoom=2, tile=[0, 0]
…

Поскольку запросы известны заранее, ответы на запросы тоже можно сгенерировать заранее. Организуем на сервере какую-то такую файловую структуру.

В файлах будет храниться примерно такой код:

myCallback_x_1_y_2_z_5({
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "id": 0,
      "geometry": {
        "type": "Point",
        "coordinates": [55.831903, 37.411961]
      },
      "properties": {
        "balloonContent": "Содержимое балуна",
        "clusterCaption": "Метка 1",
        "hintContent": "Текст подсказки"
      }
    },
    ...
  ]
}

При загрузке такого файла на клиенте будет вызван JSONP-callback, прописанный в файле. Данные попадут в недры LoadingObjectManager, закешируются и отрисуются в нужном виде.

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

2. Динамическое формирование ответа из статических файлов

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

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

3. Динамическое формирование ответа с использованием базы данных

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

Вообще хранение геопривязанных данных на сервере и их кластеризация – тема отдельной беседы. Так что обсудим в другой раз.

В этом репозитории живет пример реализации серверной части с серверной grid-кластеризацией, написанный на node.js + mongo.db. может кому-то пригодится (Демо).

Заключение

Сравнительная таблица новых модулей. 

МодульПреимуществаНедостатки
ObjectManagerПозволяет кластеризовать объекты на клиенте.

Отрисовка производится только тех объектов, которые попадают в видимую область карты.

Позволяет фильтровать объекты при их отображении.

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

Данные загружаются для всех объектов сразу (даже для тех, которые не попадают в видимую область карты).

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

Сохраняет загруженные данные. Для каждого объекта данные загружаются только один раз.

Позволяет фильтровать объекты при их отображении.
Поддерживает работу только с метками.

Кластеризация объектов производится на стороне клиента.

Необходимо реализовать серверную часть.
RemoteObjectManagerИспользует серверную кластеризацию данных.

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

При изменении коэффициента масштабирования данные загружаются заново (даже для тех объектов, для которых данные уже были загружены).

Необходимо реализовывать собственную кластеризацию.

Необходимо реализовать серверную часть.


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

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

Полезные ссылки:

    1. Подробнейшее руководство разработчика с картинками –tech.yandex.ru/maps/doc/jsapi/2.1/dg/concepts/many-objects-docpage/.
    2. Примеры в песочнице – tech.yandex.ru/maps/jsbox/2.1/object_manager
    3. Проект на гитхабе с примером реализации серверной части для RemoteObjectManager – github.com/dimik/geohosting-server.
    4. Клуб разработчиков API Яндекс.Карт, куда нужно приходить с вопросами –clubs.ya.ru/mapsapi.

1 комментарий
API 2.1,новости,LoadingObjectManager,ObjectManager,статьи,RemoteObjectManager
Как правильно разрабатывать API с поддержкой обратной совместимости
a.chebotareov
23 сентября 2014, 08:26

Интересно, как мы делаем API? В статье на Хабре и в докладе руководитель службы разработки API Яндекс.Карт Сергей Константинов рассказывает о том, как мы разрабатываем API и что мы делаем, если нужно что-то рефакторить и не сломать по дороге обратную совместимость.

Видеозаписи других докладов доступны по тегу «видео».

видео,статьи,новости
Генеральный план посёлка на основе API Яндекс.Карт с геопривязкой
a.chebotareov
21 июля 2014, 16:46
Генеральный план посёлка на основе API Яндекс.Карт с геопривязкой

Как создать собственную карту с геопривязкой на базе API Яндекс.Карт? В свой статье на Хабрахабре автор Даниил Коноплицкий подробно рассказал о том как он сделал карту посёлка на основе генерального плана, а специально для тех, кто пойдёт его дорогой, предоставил файл со скриптом и ссылку на репозиторий.

Если вы написали статью или хотите рассказать о своей реализации, пишите нам в Клуб, Facebook, ВКонтакте или на почту ymapsapi@ya.ru.

статьи пользователей,статьи
Адаптивные элементы управления
a.chebotareov
9 июля 2014, 15:13

Одна из особенностей API Яндекс.Карт версии 2.1 — адаптивные элементы управления, которые подстраиваются под размер контейнера карты и размер экрана пользователя. Мы подготовили статью в разделе Элементы управления про адаптивность. В ней также рассказывается, как сделать собственный адаптивный элемент управления. 

 Читать статью.

Адаптивные элементы управления

Одна из особенностей API Яндекс.Карт версии 2.1 — адаптивные элементы управления, которые подстраиваются под размер контейнера карты и размер экрана пользователя. Мы подготовили статью в разделе Элементы управления про адаптивность. В ней также рассказывается, как сделать собственный адаптивный элемент управления. 

Эта статья поможет разобраться с принципами работы адаптивных элементов управления. Например, элемент управления масштабом изменяет свой внешний вид в зависимости от высоты карты, а остальные элементы — в зависимости от ее ширины.

 Читать статью полностью. 

Кроме этого, для тех, кто переходит на новую версию API с версии 2.0 доступно руководство по переходу на API Яндекс.Карт версии 2.1.

элементы управления,статьи,API 2.1
Руководство по переходу на API Яндекс.Карт версии 2.1
a.chebotareov
28 мая 2014, 19:19

Мы написали подробное руководство по переходу с API Яндекс.Карт версии 2.0 на версию 2.1. Руководство содержит два десятка примеров от подключения API до геообъектов и поведения карты. Примеры представлены в удобной сравнительной таблице, а разница в коде объясняется.

Руководство по переходу на API Яндекс.Карт версии 2.1

Мы написали подробное руководство по переходу с API Яндекс.Карт версии 2.0 на версию 2.1. Руководство содержит два десятка примеров от подключения API до геообъектов и поведения карты. Примеры представлены в удобной сравнительной таблице, а разница в коде объясняется.

Кроме этого также доступно руководство по переходу на API Яндекс.Карт 2.1 с версии 1.х.

API 2.0,документация,API 2.1,статьи,API 1.x
Изучаем API Яндекс.Карт версии 2.1
a.chebotareov
27 мая 2014, 15:31
Изучаем API Яндекс.Карт версии 2.1

Что из себя представляет новая версия API Яндекс.Карт, как на нее перейти, в чем ее преимущества и про многое другое читайте в новой статье про API Яндекс.Карт 2.1 в блоге «Занимательная веб-картография».

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

Если вы написали статью или хотите рассказать о своей реализации, пишите нам в Клуб, Facebook, ВКонтакте или на почту ymapsapi@ya.ru.

статьи пользователей,API 2.1,статьи
Вредные советы от создателей API Яндекс.Карт. Как сделать так, чтобы всё было плохо
a.chebotareov
29 апреля 2014, 15:58

Мы решили собрать все «Вредные советы», они же частосовершаемые ошибки при работе с API Яндекс.Карт в одну статью. Разработчик интерфейсов API Яндекс.Карт Марина Степанова написала статью для Хабра в которой рассказала, что нужно делать, чтобы получилась получилась медленная и не функциональная карта.

Вредные советы от создателей API Яндекс.Карт. Как сделать так, чтобы всё было плохо

Мы решили собрать все «Вредные советы», они же часто совершаемые ошибки при работе с API Яндекс.Карт в одну статью. Разработчик интерфейсов API Яндекс.Карт Марина Степанова написала статью для Хабра в которой рассказала, что нужно делать, чтобы получилась медленная и не функциональная карта.

Если гонится за вами
Слишком много человек,
Расспросите их подробно
Чем они огорчены?
Постарайтесь всех утешить.
Дайте каждому совет,
Но снижать при этом скорость
Совершенно ни к чему.
Г. Остер

Разработка API – очень специфичная область программирования. На любую задумку дизайнера и разработчика накладываются потребности и умения пользователей API. Основной фидбек, который мы получаем – это сообщения пользователей в нашем клубе. Туда присылают примеры сайтов с Яндекс.Картами, багрепорты и рекомендации по улучшению нашего продукта. Мы видим, как API смотрится в боевых условиях, и мотаем на ус.

Некоторые вещи часто делают неправильно. Сегодня я хочу о них рассказать. Все советы, которые вы прочтете — вредные. Если вы поймете, что соблюдаете некоторые из рекомендаций этой статьи, ничего страшного – никогда не поздно сделать ваш проект немного лучше. Итак, Irony mode ON.

Ни в коем случае не читайте пользовательское соглашение

Многовековой опыт использования Windows кое-чему нас научил. Мы даже не пытаемся читать пользовательские соглашения. Мы смело говорим: «Я со всем согласен» — и думаем, что кармическое возмездие никогда нас не настигнет, — «Дураки они, что ли? Ехать из своей силиконовой долины в Гусь Хрустальный, чтобы запретить мне пользоваться моей пиратской виндой?»

В случае использования API Яндекс.Карт стоит придерживаться той же стратегии.

Потому что если вы прочитаете пользовательское соглашение, то сможете понять, что вашу клевую идею воплощать на API незаконно. Например, вы не сможете сделать мониторинг транспорта или использовать API в админке к 1С. Или еще чего похуже.

Поэтому перед самым началом работы дайте себе установку – если вы не читали соглашение, вы в принципе не в курсе ограничений и мир картографии для вас безграничен. Есть конечно в этом всем минус — API могут забанить на вашем сайте, если засекут нарушение. Но, как известно, проблемы нужно решать по мере поступления, поэтому спокойно движемся дальше.

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

Избегайте чтения документации в любом виде

Как известно, хороший код в комментариях не нуждается. Точно так же хорошее API не нуждается в документации. Вообще любая библиотека или модуль должны быть понятны интуитивно, а идеальный API не должен требовать навыков программирования. Поэтому если вы хотите посмотреть примеры у нас в песочнице, или почитать что-то про возможности API в руководстве, или тем более заглянуть в справочник (!) – боритесь с порывом. Верная стратегия — случайным образом выбрать один пример (желательно наименее подробный) и послушать зов сердца – оно подскажет, как писать.

Итак, куда не надо смотреть перед началом разработки приложения:

Не стоит задумываться о знании JavaScript

Как известно, программист на JavaScript – это не программист, а так – верстальщик. Вас ни в коем случае не должно сбивать с этой мысли то, что API, который вы хотите использовать, написан на JavaScript. Изучая конструкции этого языка (если так вообще можно сказать), вы рискуете забыть что-то важное из другого языка, запутаться и все пойдет прахом.

Идеальный вариант – это печатать конструкции JavaScript с помощью PHP. Приведу пример:

<?php foreach($maps as $map): ?>
myPlacemark = new ymaps.Placemark(["<?php echo $map['lantitude']; ?>" ,"<?php echo $map['longitude']; ?>" ]);
myMap.geoObjects.add(myPlacemark);
<?php endforeach;?>

Видите, как изящно мы обошлись без JavaScript!

Этот подход позволит вам избежать многих неприятных последствий

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

Печально, что многие программисты все-таки пытаются идти против системы. Они пишут код на чистом, хорошо структурированном JavaScript. Загружают данные пачками по одним и тем же URL, засоряя кеш браузера. В результате их приложения работают быстро, пользователи воспринимают это как должное и даже не смотрят на другие сайты. Подумайте о подрастающем поколении – хватит делать сайты, на которых школьники проводят свою молодость, освободим человечество от интернет-зависимости!

Книга, которую не стоит читать, если вы решите разработать приложение на JavaScript:

Избегайте структурирования кода 

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

Этого не стоит делать по нескольким причинам:

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

Вещи, которых стоит избегать при разработке приложения, использующего карты:

    • Не надо разбивать код на классы или функции.
    • Не стоит использовать модульные системы, никакие RequireJS вам не нужны.
    • Не надо разделять код и данные по разным файлам – если файлов много, в них легко запутаться

К сожалению, у нас есть примеры, которые вопреки всему используют эти подходы. Посмотреть и оценить их нелепость можно в песочнице.

// Задание собственного модуля.
ymaps.modules.define('CustomModule', function (provide) {
    var CustomModule = function (defValue) {
        this.field = defValue;
    };
    provide(CustomModule);
});

// Запрос модулей.
ymaps.modules.require(['CustomModule'])
.spread(
function (CustomModule) {
    // ...
},
this
);

В версии 2.1 разработчики API буквально расставили ловушки, открыв модульную систему, которая используется в API. Теперь слабый духом разработчик может не выдержать и разбить свой код на модули. Мужайтесь.

Книги, которые могут помешать вам писать идеальный код, писали коварные люди. У них система ценностей перевернута с ног на голову. Врага надо знать в лицо, вот некоторые из потенциально опасных изданий:

Готовьте все заранее

Если вы планируете показать на карте большое количество объектов, нужно решить, в какой момент загружать данные с сервера на клиент. Единственно правильный путь – загрузить данные сразу и желательно до загрузки контента страницы, на которой показана карта. Подумайте сами – если не сейчас, то когда? У человека может отключиться интернет и тогда плакали наши меточки. Не все программисты поняли эту простую истину и все еще пытаются загружать данные по требованию.

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

Загружайте с запасом

API – это много кода, разбитого на модули и пакеты. После разработки вашего сайта нужно решить еще один важный вопрос: какой код API подключать на свой сайт?

Тут будет не лишним вспомнить о случаях, когда вы посылали друга за баночкой колы, а он одну и приносил. Ровно то же правило работает и для загрузки кода. Лучше загрузить весь код API целиком – никогда не знаешь, что тебе пригодится. В версии 2.0 разработчики насоздавали пакеты, которые пользователь может случайно начать использовать, если скопирует пример из песочницы не задумываясь.

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

В версии 2.1 разработчики, к сожалению, просекли, что люди не поддаются на провокации и грузят API целиком. Поэтому в версии 2.1 вообще отменили пакеты, а package.full теперь разбит на части, которые подгружаются асинхронно по мере надобности.

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

Программировать хорошо становится все сложнее.

Добавляйте элементы управления 

Пользователь всегда рад, когда на карте есть кнопки. Кто не любит кнопки? Кнопки любят все! Вы можете скопировать пример из песочницы для версии 2.0, демонстрирующий работу всех имеющихся элементов управления, и добавить код на свой сайт как есть.

Опытный пользователь может заметить, что на этой карте представлены не все элементы управления. Нерадивые программисты забыли добавить на карту второй элемент управления масштабом и контрол поиска. Кстати, раньше этот пример содержал сразу два элемента управления масштабом. Поэтому мы периодически находим сайты, на которых все работает как надо – на карте есть все, что нужно: и большой контрол, и маленький. Зачем понадобилось делать пример хуже, остается загадкой и по сей день.

Версия 2.1 опять поставила нам подножку. В ней стало меньше элементов управления (злодеи выпилили мини-карту), они установлены на карту по умолчанию и на маленькой карте схлопываются до небольших размеров.

Убедитесь сами – кнопок мало, сами они маленькие. Карта вообще как голая! В общем 2.1 вообще лучше не использовать.

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

Если вам надо показать сотни или даже тысячи объектов на карте, смело идите в бой. Создавайте метки и мужественно наносите их на карту в полном объеме. При достаточном количестве меток вы сразу покажете пользователю, кто в мире хозяин – человек или браузер. Потому что при большом количестве меток (100 для IE, 500 для всех остальных) браузер крякнет и зависнет на неопределенный срок. Так ему и надо.

Разработчики, пытающиеся скрыть несовершенство браузеров, маскируют их недостатки весьма изощренными способами:

    • Используют кластеризацию объектов. Этому хитроумному приему у нас посвящено немало примеров и даже целая статья.
    • Используют технологию активных областей. Несмотря на сложность разработки, она снимает любые ограничения на количество отображаемых объектов. Оценить коварство замысла можно, прочитав руководство разработчика или посмотрев примерв песочнице.

Не пытайтесь экономить запросы к геокодеру

Очень часто пользователи сталкиваются вот с какой задачей. У них есть список адресов магазинов, аптек, достопримечательностей и многого другого. Все эти адреса нужно показать на карте. Задача решается просто – нужно взять все адреса, отправить их на клиентскую сторону, и просто-напросто геокодировать адреса в координаты меток на клиенте.

Неподготовленный читатель может спросить «Правильно ли то, что набор меток у нас один и тот же, а геокодируется он каждый раз при каждом вызове моего приложения у каждого пользователя заново?». Мы отвечаем на этот вопрос прямо: «Не волнуйтесь». Сервера Яндекса достаточно отказоустойчивы и выдержат все. Единственная загвоздка – при большом количестве запросов с вашего сайта, вы можете превысить лимит в 25 000 запросов не геокодирование и ваш сайт забанят. Но эту проблему мы уже освещали выше, поэтому не будем засорять голову по пустякам.

Разработчики, которые не читали эту статью и не верят в силу серверов Яндекса, придумали геокодировать данные на сервере. А один наш сотрудник даже написал модуль для серверного геокодирования на node.js. Этому посвящен раздел в руководстве разработчика.

И не лень же было…

Не отбирайте хлеб у службы техподдержки

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

Постарайтесь не грузить службу техподдержки лишними подробностями. Идеальный багрепорт состоит из пяти слов – «все сломалось, ничего не работает». Вообще, наша служба техподдержки уже давно сократила эти пять ключевых слов в одно – «всесломалосьничегонеработает». И теперь у нас появился термин, по которому и поддержка, и разработчики мгновенно понимают суть вещей.

Вот хороший пример обращения в клубе:

Разработчик при виде этого сообщения мгновенно понимает, что вся его работа – тлен. Вселенная появилась из большого взрыва, расширяется и вот-вот схлопнется. Все пропало. Ничего не работает.

Вещи, которых стоит избегать при обращении в техподдержку или клуб:

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

Если вы хотите написать о проблеме в клуб разработчиков, не стоит пользоваться поиском, читать ответ на FAQ и пытаться каким-то другим образом найти решение своей проблемы. Подумайте – если все будут находить ответы на вопросы сами, чем тогда заниматься работникам техподдержки? 

Заключение

Вот и все вредные советы, о которых мы хотели рассказать. Вообще типовые ошибки для вас – это задачи для нас. Если разработчики наступают на одни и те же грабли при использовании API, то это в какой-то мере и наша вина. Возможно мы не предусмотрели кейс, написали мало примеров, плохо сделали документацию и т.д и т.п. В частности, в версии 2.1 мы постарались сделать так, чтобы человеку было сложнее ошибиться, чем в версии 2.0. И работы в этом направлении еще выше крыши.

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

5 комментариев
API 2.0,API 2.1,статьи
Почему мы сломали обратную совместимость в кластеризаторе
a.chebotareov
24 декабря 2013, 18:50
Почему мы сломали обратную совместимость в кластеризаторе

Сегодня мы опубликовали пост на Хабре, в котором разработчик интерфейсов API Яндекс.Карт Марина Степанова рассказала, почему мы сломали обратную совместимость в кластеризаторе. Вы можете прочитать его также в этом блоге.

С версии 2.0 наш API умеет кластеризовать метки на клиенте. Вот как выглядят метки до и после кластеризации:

На днях состоялся очередной релиз нашей бета-версии 2.1.4. Этот релиз примечателен тем, что в нем случилось то, чего так боялись большевики. Как мы и предупреждали, нам пришлось сломать обратную совместимость в кластеризаторе меток.

В этой статье я хочу не просто перечислить новшества в работе с кластеризатором в версии 2.1.4, но и объяснить, зачем нам понадобилось эти новшества плодить. А то вам придется переписывать код, а переписывать код грустно, если не понимаешь, зачем это приходится делать.

Содержание статьи:

1. Отмена асинхронного добавления меток (этот пункт стоит прочитать тем, кто хоть как-то использовал метод objectsaddtomap).

2. Изменение публичных методов кластеризатора.

3. Изменение способа разбиения карты на тайлы (может никто и не заметит).

4. Переименование сущности Cluster в ClusterPlacemark (скорее всего никто не заметит).

5. Изменения в clusterer.balloon и clusterer.hint (стоит прочесть, если вы использовали балуны кластера или хотели добавить кластерам хинты).

6. Задание произвольных иконок кластеров – что нового (стоит читать, если… а ну тут и так понятно).

7. Небольшая доработка опции preset или как изменить цвет кластера при наведении.

8. Префиксирование опций для кластеров и меток в составе кластера.

9. Сводная таблица различий в коде.

10. Сравнение скорости работы версий (для убедительности статьи).

Отмена асинхронного добавления меток

В версии 2.0 геообъекты создавались, добавлялись на карту и отрисовывались сразу, в одном потоке. Чем слабее браузер, чем больше объектов вы добавляли на карту, тем больше была вероятность увидеть сообщение.

image

Такую ситуацию наш разработчик Антон называет научным термином «залипон».

Кластеризатор начинают использовать, когда количество меток на карте много. Когда объектов много, появляется проблема этих самых залипонов. Нужно было что-то решать, и в кластеризаторе было решено по умолчанию сделать асинхронное добавление объектов на карту. Понять, что объекты добавились на карту, можно было по событию objectsaddtomap. Вот так выглядит один из примеров для версии 2.0.

// Открытие балуна кластера с выбранным объектом.

// Поскольку по умолчанию объекты добавляются асинхронно,
// обработку данных можно делать только после события, сигнализирующего об
// окончании добавления объектов на карту.
cluster.events.add('objectsaddtomap', function () {
   
    // Получим данные о состоянии объекта внутри кластера.
    var geoObjectState = cluster.getObjectState(myGeoObjects[1]);
    // Проверяем, находится ли объект находится в видимой области карты.
    if (geoObjectState.isShown) {
       
        // Если объект попадает в кластер, открываем балун кластера с нужным выбранным объектом.
        if (geoObjectState.isClustered) {
            geoObjectState.cluster.state.set('activeObject', myGeoObjects[1]);
            geoObjectState.cluster.balloon.open();
           
            } else {
            // Если объект не попал в кластер, открываем его собственный балун.
            myGeoObjects[1].balloon.open();
        }
    }
   
});

Не могу сказать, что работать с этим было очень удобно. Но лучше неудобно, чем никак – висящий браузер более веский аргумент, чем красота кода.В версии 2.1 мы шагнули в сторону разделения объектов и их отображения на карте. Кто-то мог заметить, что методы getOverlay стали асинхронными и неудобными – вот это как раз оно. В действительности асинхронная отрисовка макетов – это отличный способ оптимизировать процесс добавления объектов на карту.Чтобы лучше понимать суть вещей, посмотрим на путь метки от ее создания до появления на карте. Процесс можно разбить на три этапа:

    • Создание инстанции класса
    • Добавление объекта на карту
    • Отрисовка макета метки в HTML

По первому пункту, думаю, пояснения не нужны. Не очень понятно, чем отличаются этапы два и три. Добавление объекта на карту – это процесс, при котором метка прикрепляется к родительской коллекции (чаще всего к map.geoObjects). Метка получает от этой коллеции некоторые опции, в том числе проекцию карты. После того, как объект метки узнает, в какой проекции отрисована карта, он может спроецировать свою геометрию на плоскость (что и делает). После проецирования координат метки на плоскость становится понятно, в какой пиксельной точке экрана надо нарисовать значок метки. В этот момент этап два завершается.

Третий этап является как раз процессом рисования метки на карте в определенной пиксельной координате. В версии 2.1 мы выполняем первые два этапа синхронно, в одном потоке. А вот отрисовку объекта делаем по таймауту.

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

Другими словами, для перехода на версию 2.1.4 нужно будет убрать из кода подписку на событие objectsaddtomap. Весь код внутри обработчика этого события теперь можно выполнять сразу синхронно после добавления объектов в кластеризатор. (В конце статьи я приведу таблицу с примерами в формате “стало-было”, кому неинтересно читать дальше – можете сразу переходить к ней.)

Изменение публичных методов кластеризатора

В версии 2.0 кластеризатор являлся наследником объекта ymaps.Collection. Он наследовал от коллекции методы add, remove, setParent и прочие нужные, а также each, getIterator и прочие ненужные (я поясню, почему эти методы были ненужными). Казалось, что кластеризатор вполне себе коллекция – в него можно добавлять объекты и удалять объекты обратно. Но кластеризатор мало того что содержит в себе какие-то элементы, он эти элементы может показывать или не показывать на карте, а также сам генерирует дополнительные объекты-кластеры.

Поэтому какую реализацию метода each ни делай, все равно получится не очень логично. То ли надо перебрать все добавленные объекты. То ли надо пройтись по объектам и кластерам. Но кластеры все время перестраиваются. Пришло осознание, что кластеризатор не совсем коллекция. То есть совсем не коллекция.

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

    • Clusterer.getGeoObjects — возвращает массив элементов, добавленных в кластеризатор
    • Clusterer.getClusters — возвращает массив кластеров, в данный момент добавленных на карту. Обратите внимание, что это не все кластера, а только видимые в данный момент времени.

Примеры работы с этими методами ищите в нашей документации.

Изменение способа разбиения карты на тайлы

Как известно, мы используем алгоритм грид-кластеризации (кому интересно подробно – вот ссылка на мой древний спич про кластеризатор). Алгоритм прост и поэтому прекрасен (когда кластеризуешь объекты на клиенте, в первую очередь приходится думать о скорости исполнения кода).

Карта разбивалась на квадратные ячейки. Метки, попадающие в одну ячейку, образовывали кластер. Для того чтобы не вызывать вычисления при каждом маленьком драге карты, ячейки объединялись в более крупные квадраты, которые мы называли «кластерные тайлы». Обрабатывались все кластерные тайлы, в которые полностью или частично попадала видимая область карты.

image

В этой версии мы решили не вводить путаницу в понятие слова «тайл». Теперь кластерные тайлы находятся точно там же, где и обычные карточные тайлы и всегда имеют размер 256х256 пикселей. Из этого следует ограничение – размер ячейки кластеризации должен быть а) не больше 256 и б) в тайл должно умещаться целое количество ячеек кластеризации. То есть допустимые значения для размеров ячейки кластеризации 2, 4, 8, 16, 32, 64, 128 и 256.

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

Поскольку тайлы имеют небольшой размер и, вообще говоря, граница карты может совпадать с границей тайла, мы ввели дополнительный отступ для видимой области карты – mapViewport (по умолчанию 128 пикселей). То есть всегда обрабатывается немного больше, чем нужно. Зато пользователь скорее всего не заметит перестроений при перемещении карты.

Переименование Cluster в ClusterPlacemark

Я всегда подозревала, что никто, кроме пары человек (я и наш документатор Олеся), не может слету сказать, чем отличается Cluster от Clusterer (если вы понимаете разницу, вы большой молодец).

    • Clusterer — кластеризатор объектов, что-то вроде коллекции.
    • Cluster – группа объектов, сгенерированная кластеризатором. На карте смотрится как метка.

Мы изучили количество переходов на разные страницы документации – страницы Clusterer и Cluster пользуется большой популярностью. И я подозреваю, что люди, кликающие на Cluster – жертвы жестокости и непонимания. Именно поэтому было решено переименовать сущность Cluster в ClusterPlacemark. Когда смотришь на Clusterer и ClusterPlacemark вроде бы становится понятнее, что к чему.

Поскольку в клубе API Карт не проявлялись люди, пользующиеся кластерами отдельно от кластеризатора (следите за суффиксами), это изменение должно пройти абсолютно незамеченным. А ошибочные клики в документации на Cluster вместо Clusterer должны уйти в далекое прошлое. Тем не менее, если вам нравилось читать документацию к объекту Cluster и ее потерю воспримете, как потерю близкого друга, читайте документацию к ClusterPlacemark.

Изменения в clusterer.balloon и clusterer.hint

Начну с приятного – мы наконец добавили возможность показывать всплывающую подсказу к метке кластера. Делать это можно вот таким кодом:

var clusterer = new ymaps.Clusterer();
clusterer.createCluster = function (center, geoObjects) {
    // Создаем метку-кластер с помощью стандартной реализации метода.
    var clusterPlacemark = ymaps.Clusterer.prototype.createCluster.call(this, center, geoObjects),
    geoObjectsLength = clusterPlacemark.getGeoObjects().length,
    hintContent;
    if (geoObjectsLength < 10) {
        hintContent = 'Мало меток';
        } else if (geoObjectsLength < 100) {
        hintContent = 'Нормально так меток';
        } else {
        hintContent = 'Меток навалом';
    }
    clusterPlacemark.properties.set('hintContent', hintContent);
    return clusterPlacemark;
};

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

Теперь про изменение хинтов и балунов в целом. Для работы с балунами в версии 2.0 у каждого кластера создавалось поле .balloon. Открытие балуна выглядело как cluster.balloon.open();

Недостатком этого решения являлась низкая скорость исполнения кода. Ведь если у вас 100 кластеров, у каждого из них может быть балун, а значит каждому кластеру нужно создать и приписать менеджер балуна в поле cluster.balloon. Поэтому в рамках работ по скорости было решено сделать один менеджер балунов и хинтов на кластеризатор. Теперь балун на кластере можно открыть так:

// Открыть балун на конкретной метке-кластере.
clusterer.balloon.open(clusterPlacemark);

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

Задание произвольных иконок кластеров – что нового

В версии 2.0 все геообъекты были равны. Но некоторые были равнее. Метки, отрисованные на canvas, обретали интерактивность с помощью активных областей. Метки, отрисованные с помощью DOM, были интерактивными сами по себе. Это рождало различия в поведении и массу неудобств.

Поэтому в версии 2.1 было решено все объекты унести под горизонт событий (что бы это ни значило). Теперь все метки становятся интерактивными за счет активных областей, наложенных поверх карты. Из-за этого для меток теперь нужно указывать, какой формы и размера должна быть активная область над меткой (при наведении на какую часть картинки курсор должен меняться, метка должна кликаться и ховериться).

Стандартные метки-кластеры имеют 3 вида картинок – большие, средние и маленькие. Эти картинки круглые. Если вы попробуете поводить мышкой над меткой кластера, вы увидите, что активная область метки совпадает с картинкой и является тоже кругом.

imageimageimage

Некоторые пользователи уже столкнулись с тем, что в версии 2.1.3 при замене изображений для иконки кластера активная область все равно остается круглой (а метка вообще говоря квадратная или более того, треугольная).
image

— кастомная метка, а кликабельным был все равно круг.

Мы это поправили и теперь вы можете самостоятельно определять форму активной области для метки. Делать это можно так (пример для круглых меток).

clusterer.options.set({
    clusterIcons: [
    {
        href: ‘images/small.png’,
        size: [20, 20],
        offset: [-10, -10],
        shape: new ymaps.shape.Circle(new ymaps.geometry.pixel.Circle([0, 0], 10))
    },
    {
        href: ‘images/medium.png’,
        size: [30, 30],
        offset: [-15, -15],
        shape: new ymaps.shape.Circle(new ymaps.geometry.pixel.Circle([0, 0], 15))
    },
    {
        href: ‘images/big.png’,
        size: [40, 40],
        offset: [-20, -20],
        shape: new ymaps.shape.Circle(new ymaps.geometry.pixel.Circle([0, 0], 20))
    }
    ]
});

Код получился не очень простой, поэтому есть альтернативный подход – попроще, но погрубее. Если вы не задаете параметр shape при описании иконок, активной станет прямоугольная область над иконкой, которая сформируется на основе параметров size и offset. То есть вот такой код тоже будет работать нормально, просто кликабельной будет прямоугольная область вокруг иконки.
image

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

clusterer.options.set({
    clusterIcons: [
    {
        href: ‘images/small.png’,
        size: [20, 20],
        offset: [-10, -10]
    },
    {
        href: ‘images/medium.png’,
        size: [30, 30],
        offset: [-15, -15]
    },
    {
        href: ‘images/big.png’,
        size: [40, 40],
        offset: [-20, -20]
    }
    ]
});

Еще одно небольшое дополнение. Если вы не хотите показывать содержимое внутри метки кластера, можно выставить опцию clusterIconContentLayout в null и метка будет показываться без цифр внутри clusterer.options.set(‘clusterIconContentLayout’, null);

Небольшая доработка preset для кластера

В клубе API Карт попадались вопросы на тему «как задать стиль для конкретного кластера». На этот вопрос не было хорошего ответа, так как указанные в описании option.presetStorage ключи работали только если их задавать кластеризатору целиком. А для одиночных меток эти ключи не подходили. В этой версии ключи стали универсальными – подходят как для кластеризатора целиком, так и для меток-кластеров в частности.

Изменить цвет кластера при наведении можно вот так.

clusterer.events.add(‘mouseenter’, function (e) {
    var target = e.get(‘target’);
    if (typeof target.getGeoObjects == ‘function’) {
        target.options.set(‘preset’, ‘islands#redClusterIcons’);
    }
});
clusterer.events.add(‘mouseleave’, function (e) {
    var target = e.get(‘target’);
    if (typeof target.getGeoObjects == ‘function’) {
        target.options.set(‘preset’, ‘islands#blueClusterIcons’);
    }
});

Префиксирование опций для кластеров и меток в составе кластера

В кластеризаторе можно найти два вида объектов – метки-кластеры и одиночные объекты, которые не попали ни в одну группу объектов. Иногда возникает необходимость задать опции для тех и других. Понятно, что никому не хочется перебирать все метки и кластеры, чтобы выставить каждой одни и те же опции. Чтобы задать опции на все объекты сразу, можно эти самые опции указать один раз через кластеризатор. А кластеризатор эти опции передаст своим дочерним объектам.

В частности, в версии 2.0 можно было сделать так: clusterer.options.set(‘cursor’, ‘help’); И вид курсора менялся как для одиночных объектов, так и для меток-кластеров.

Пытливый читатель спросит с прищуром: «А что если я хочу задать разные типы курсоров для меток-кластеров и одиночных меток?» Этот случай мы предусмотрели и решили, что метки-кластеры также будут понимать опции, которые имеют префикс «cluster».

сlusterer.options.set({
    // сработает для геообъектов
    Cursor: 'pointer',
    // сработает для меток-кластеров
    clusterCursor: 'help'
});

В этой системе все было прекрасно, кроме случая, когда вы хотели кастомизировать только одиночные метки, не затрагивая метки-кластеры. Если вы хотели поменять только опции для одиночных меток, вы писали clusterer.options.set(‘cursor’, ‘help’); И получали слишком массовый эффект – опции распространялись и на одиночные объекты, и на метки-кластеры. То есть если вы хотели повлиять только на одиночные метки, опции приходилось задавать все равно и для одиночных объектов, и для кластеров.

В версии 2.1 стало чуть удобнее. Теперь все опции для дочерних объектов задаются с префиксами. Для меток-кластеров c префиксом ‘cluster’, для одиночных меток – с префиксом ‘geoObject’. Теперь опции дочерних объектов не зависят друг от друга. Задавайте, какие больше нравится.

// Сработает только для одиночных меток и не тронет кластеры.
сlusterer.options.set('geoObjectCursor', 'help');
Сводная таблица изменений
Было
// Пример 1. Открытие балуна кластера c выбранным объектом.

// Поскольку по умолчанию объекты добавляются асинхронно,
// обработку данных можно делать только после события, сигнализирующего об
// окончании добавления объектов на карту.
cluster.events.add('objectsaddtomap', function () {
    // Получим данные о состоянии объекта внутри кластера.
    var geoObjectState = cluster.getObjectState(myGeoObjects[1]);
    // Проверяем, находится ли объект в видимой области карты.
    if (geoObjectState.isShown) {
        // Если объект попадает в кластер, открываем балун кластера с нужным выбранным объектом.
        if (geoObjectState.isClustered) {
            geoObjectState.cluster.state.set('activeObject', myGeoObjects[1]);
            geoObjectState.cluster.balloon.open();
            } else {
            // Если объект не попал в кластер, открываем его собственный балун.
            myGeoObjects[1].balloon.open();
        }
    }
});
//  Пример 2. Изменение цвета иконки-кластера.

var options = ymaps.option.presetStorage.get(‘islands#redClusterIcons’);
cluster.options.set({
    icons: options.clusterIcons,
    iconContentLayout: options.clusterContentLayout
});
// Пример 3. Создание меток-кластеров без содержимого.

clusterer.options.set(‘clusterIconContentLayout’, ymaps.templateLayoutFactory.createClass(‘’));
// Пример 4. Указание опций для объектов в составе кластера.
сlusterer.options.set({
    clusterBalloonLayout: myClusterBalloonLayout,
    balloonLayout: myPlacemarkBalloonLayout
});
Стало
// Пример 1. Открытие балуна кластера c выбранным объектом.

// Получим данные о состоянии объекта внутри кластера.
var geoObjectState = cluster.getObjectState(myGeoObjects[1]);
// Проверяем, находится ли объект в видимой области карты.
if (geoObjectState.isShown) {
    // Если объект попадает в кластер, открываем балун кластера с нужным выбранным объектом.
    if (geoObjectState.isClustered) {
        geoObjectState.cluster.state.set('activeObject', myGeoObjects[1]);
        clusterer.balloon.open(geoObjectState.cluster);
        } else {
        // Если объект не попал в кластер, открываем его собственный балун.
        myGeoObjects[1].balloon.open();
    }
}
//  Пример 2. Изменение цвета иконки-кластера.

cluster.options.set('preset', 'islands#redClusterIcons');
// Пример 3. Создание меток-кластеров без содержимого.

clusterer.options.set(‘clusterIconContentLayout’, ymaps.templateLayoutFactory.createClass(‘’));
// Пример 4. Указание опций для объектов в составе кластера.
сlusterer.options.set({
    clusterBalloonLayout: myClusterBalloonLayout,
    geoObjectBalloonLayout: myPlacemarkBalloonLayout
});

В остальном все осталось без изменений. Все новшества описаны в документации.

Сравнение скорости работы кластеризатора в версиях 2.0.36 и 2.1.4

Лучше один раз увидеть, чем один раз прочитать и не поверить. Как проводились измерения. За образец был взят вот такой кейс:

<!doctype html>
<html>
<head>
<title> Скорость работы кластеризатора</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script src="http://api-maps.yandex.ru/2.0.36/?load=package.full &lang=ru-RU&ns=ym" type="text/javascript"></script>
<script type="text/javascript">
ym.ready(function() {
    var map = new ym.Map('map', {
        center: [55.755381, 37.619044],
        zoom: 13
    }),
    coords = [],
    center = [55.755381, 37.619044],
    placemarks = [],
    i;
   
    for (i = 0; i < 10000; i++) {
        coords[i] = [
        center[0] + 0.5 * Math.random() * Math.random() * Math.random() * (Math.random() < 0.5 ? -1 : 1),
        center[1] + 0.7 * Math.random() * Math.random() * Math.random() * (Math.random() < 0.5 ? -1 : 1)
        ];
    }
    var startTime = +new Date();
    for (i = 0, l = coords.length; i < l; i++) {
        placemarks[i] = new ym.GeoObject({
            geometry: {
                type: "Point",
                coordinates: coords[i]
            }
        });
    }
   
    var clusterer = new ym.Clusterer();
    clusterer.add(placemarks);
    map.geoObjects.add(clusterer);
    var stopTime = +new Date();
   
    alert(stopTime - startTime);
});

</script>
</head>
<body>
<div id="map" style="height: 400px; width: 800px;"></div>
</body>
</html>

Этот кусок кода не затрагивает моментов, в которых сломана обратная совместимость, поэтому его можно запускать как в версии 2.0.36, так и в версии 2.1.4 без изменений, просто переключая ссылку на версию API. Время измерялось в миллисекундах.

image

Хочу сделать ремарку по поводу IE11. Тесты для всех браузеров запускались на моем ноутбуке, а для IE11 на другом ноутбуке с Windows (у меня macbook). Так что сравнивать скорость его работы с остальными браузерами по этому графику не стоит. А вот оценивать, насколько ускорилось апи от версии к версии, стоит.

Важно понимать – мы сократили только время инициализации карты с кластеризатором и метками. Браузер выполняет код, выдыхает, и потом может вернуться к отрисовке объектов. Общая нагрузка при этом не сильно поменялась – она лишь распределилась по времени, часть действий выполняется позже. Тем не менее, это важно для слабых браузеров – то, что они не могли сделать в одном потоке сразу и висли, теперь распределено по времени и браузеры могут такую нагрузку осилить.

Заключение

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

Сейчас мы получили немного свободы в связи с выходом новой версии 2.1. Конечно, хотелось изменить еще больше, но нас снова сдерживало то, что мы можем менять только по мелочам (это все же 2.1, а не 3.0).

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

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

кластеризатор,статьи,API 2.1
Добавление пользовательских меток на карту через форму
a.chebotareov
12 декабря 2013, 18:05
Добавление пользовательских меток на карту через форму

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

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

Если вы написали статью или хотите рассказать о своей реализации, пишите нам в Клуб, Facebook или на почту ymapsapi@ya.ru.

статьи пользователей,API 2.0,статьи
Плагин API Яндекс.Карт для CKEditor 4
a.chebotareov
11 декабря 2013, 15:44
Плагин API Яндекс.Карт для CKEditor 4

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

Один из авторов сообщества Хабрахабр, Степан Зубашев из Казахстана, написал плагин для этого редактора, который позволяет встраивать и редактировать карты, созданные с помощью API Яндекс.Карт. Используя плагин можно в несколько кликов установить карту на страницу сайта, задать точки и присвоить им названия, масштаб и размер карты, а также другие важные параметры. 

Плагин доступен на GitHub. На официальном сайте CKEditor можно больше узнать про сам редактор. 

Если вы написали статью или хотите рассказать о своей реализации, пишите нам в Клуб, Facebook или на почту ymapsapi@ya.ru.

статьи пользователей,API 2.0,плагины,статьи
Как создать картографический сайт на WordPress с помощью API Яндекс.Карт
a.chebotareov
10 декабря 2013, 18:04
Как создать картографический сайт на WordPress с помощью API Яндекс.Карт

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

Статья в блоге «Занимательная веб-картография» расскажет как создать с помощью WordPress картографический сайт на API Яндекс.Карт версии 2.0. Заметки на таком сайте будут представлять собой метки на карте, распределенные и фильтруемые по категориям. 

Если вы написали статью или хотите рассказать о своей реализации, пишите нам в Клуб, Facebook или на почту ymapsapi@ya.ru.

статьи пользователей,API 2.0,WordPress,статьи
Автоматический вывод точек на карту из файла в API Яндекс.Карт
a.chebotareov
6 декабря 2013, 14:52
Автоматический вывод точек на карту из файла в API Яндекс.Карт

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

YmapsML — это специальный XML-язык, предназначенный для описания географических данных на картах Яндекса. С его помощью можно в текстовом виде задать участок карты с нанесенными метками и другими объектами, а затем отобразить его в браузере средствами JS API Яндекс.Карт 2.0. Более подробно про YmapsML можно почитать на странице документации.

Для начала надо создать файл с данными в формате YmapsML, используя любой инструмент для администрирования базы данных MySQL – phpMyAdmin. В файле данных можно указывать целый ряд параметров метки: название, координаты, тип, категорию, адрес, номер телефона, фото, а также поле для тегов по которым будет удобно искать этот объект на карте. Более подробно о генерации файла данных в формте YmapsML.

После того, как файлы готовы их можно выводить в автоматическом режиме на карты, созданные в API. Именно этому посвящена статья в блоге «Занимательная веб-картография» о том, как можно использовать данные из файла YmapsML. Важно помнить, что файлы, которые генерируют код YmapsML должны быть доступны в интернете, то есть размещены на хостинге.

Если вы написали статью или хотите рассказать о своей реализации, пишите нам в Клуб, Facebook или на почту ymapsapi@ya.ru.

API 2.0,статьи,YMapsML
API Яндекс.Карт через директивы AngularJS
a.chebotareov
29 ноября 2013, 18:44
API Яндекс.Карт через директивы AngularJS

Почти месяц назад на Хабре была опубликована статья про то, как подружить API Яндекс.Карт с AngularJS. За это время автор достаточно успешно развил свой проект и теперь это полностью автономный модуль, который поддерживает все возможности API Яндекс.Карт 2.0 через директивы AngularJS.

Репозиторий на GitHub.

Демонстрационная страница работы модуля.

Если вы написали статью или хотите рассказать о своей реализации, пишите нам в Клуб, Facebook или на почту ymapsapi@ya.ru.

статьи пользователей,API 2.0,статьи
Добавляем новую категорию меток на существующую карту
a.chebotareov
28 ноября 2013, 14:57
Добавляем новую категорию меток на существующую карту

Хоть и с задержкой, но не можем не поделиться новой статьей в блоге «Занимательная веб-картография». Статья о том, как добавлять новую категорию меток на уже существующую карту, созданную с помощью API Яндекс.Карт 2.0. Тема добавления новых категорий родилась в результате статьи про создание меток пользователелями и вывод их по категориям и актуальна для проектов, которые собирают пользовательские метки или развивают свои карты.

Если вы написали статью или хотите рассказать о своей реализации, пишите нам в Клуб, Facebook или на почту ymapsapi@ya.ru.

статьи пользователей,API 2.0,статьи,примеры пользователей
Как это работает? Маршрутизация на Яндекс.Картах
a.chebotareov
22 ноября 2013, 13:28
Как это работает? Маршрутизация на Яндекс.Картах

Вчера мы объявили о масштабном обновлении Яндекс.Карт — на них появились подробные схемы большинства стран мира. За этим проектом стоит не просто нанесение на карту новых объектов, но прежде всего технологическая основа, которая позволяет хранить, быстро обрабатывать и обновлять эти данные. В Яндекс.Картах вообще немало интересных технологий, и сегодня мы хотим рассказать об одной из них — технологии построения маршрутов.

Десять-пятнадцать лет назад в бардачке каждого водителя лежал атлас дорог. Он и был главным помощником при планировании маршрута. Сейчас вместо атласа люди всё чаще открывают электронные карты и мобильные приложения. И умные алгоритмы сами строят для человека наилучший маршрут. Яндекс помогает людям планировать поездки на сервисе maps.yandex.ru, в мобильных приложениях Навигатор и Яндекс.Карты. Технология построения маршрута везде одна и та же, различаются только интерфейсы.

Главные составляющие маршрутизации — это дорожный граф и алгоритм, который рассчитывает маршрут.

Что такое граф

Дорожный граф — это сетка дорог. Она состоит из множества фрагментов, которые состыкованы между собой. Например, дорожный граф города Саратова (население — около 840 тысяч человек) состоит из 7592 фрагментов. Каждый из них несёт информацию о своём участке дороги: географические координаты, направление движения, средняя скорость, с которой машины обычно едут на этом участке, и другие параметры. Каждый фрагмент содержит также данные о том, как он стыкуется с соседними участками — есть ли в этом месте поворот направо или налево, можно ли там развернуться в обратную сторону или разрешается ехать только прямо.

Само собой, дорожный граф нельзя сделать раз и навсегда. Транспортная система города имеет обыкновение меняться. Появляются новые дороги и развязки, меняется направление движения. А там, где ещё недавно был поворот, может висеть «кирпич». Чтобы не отставать от жизни, Яндекс регулярно обновляет данные.

Во-первых, постоянно обрабатываются сообщения о неточностях в графе, которые пользователи присылают с помощью мобильных Яндекс.Карт, Навигатора и веб-сервиса Яндекс.Карты. С этими сообщениями работают эксперты Яндекса, которые используют также открытые источники информации о транспортной системе (например, сайты местных администраций).

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

Дорожный граф хранится на серверах Яндекса в нескольких экземплярах — если какой-то из серверов будет временно недоступен, маршрутизация все равно будет работать.
 

Как строится маршрут

Маршрут рассчитывается по алгоритму Дейкстры. С его помощью система вычисляет самый быстрый вариант проезда — исходя из длины каждого отрезка графа и скорости движения на этом участке. Если пользователь строит маршрут проезда без учёта пробок, то алгоритм использует среднюю скорость движения на участке. А если пользователь хочет знать, как быстрее всего добраться до места с учётом ситуации на дороге, то алгоритм задействует данные о текущей ситуации на дороге.

Как это происходит, можно разобрать на примере. Представим, что нужно проложить маршрут из точки А в точку B. Алгоритм начинает методично перебирать все возможные варианты. Первым делом он прокладывает маршрут на один шаг (фрагмент графа) во все стороны от точки А. И затем вычисляет, сколько времени потребуется на преодоление этих участков (тут все просто — расстояние делится на скорость). Дальше он выбирает точку, до которой удалось бы добраться быстрее всего. Это точка С.


Затем алгоритм строит маршрут ещё на один шаг — во все стороны от точки С. И снова анализирует, в какую из точек можно было бы попасть быстрее всего. На этот раз это точка D. На следующем шаге алгоритм будет строить маршрут уже от неё.


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

Особая тема — дворы. Как известно, сквозной проезд через дворы запрещён. Кроме того, на петляния по дворам зачастую уходит больше времени, чем на проезд по прямой. Чтобы сервис не строил маршруты через дворы, за них начисляются дополнительные минуты (они не влияют на время в пути, которое видит пользователь). Поэтому в большинстве случаев алгоритм выбирает другие варианты проезда — они занимают меньше времени. Однако если конечная точка маршрута находится во дворе, алгоритму в любом случае придётся туда «въехать».

Построение маршрута происходит очень быстро. Пока вы читаете эти несколько абзацев, сервис уже несколько раз успел бы оплести паутиной маршрутов всю Россию. Чтобы добиться такой скорости, всю карту автоматически поделили на множество областей, для каждой из которых можно посчитать оптимальные варианты её пересечения. Такой областью может быть, например, небольшой городок, через который проходит всего одна междугородняя трасса — въехать и выехать из города можно только по ней. Это значит, что Яндекс может заранее рассчитать оптимальный вариант проезда через этот город.

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

Всевозможные варианты проезда внутри каждой области и между ними Яндекс строит заранее — при каждом обновлении графа. Дальше, когда пользователь просит построить маршрут, сервис просто вытаскивает его из памяти. Правда, это срабатывает, только если человеку нужен маршрут без учёта пробок — заранее построенные маршруты рассчитаны на основе средней скорости движения, которая заложена в графе. Если же пользователь хочет построить маршрут с учетом ситуации на дороге и внутри области в данный момент есть пробки, Яндекс построит для него маршрут заново.

 

API 2.0,маршрутизация,статьи
JavaScript API Яндекс.Карт 2.1-beta — новый дизайн и новые возможности
tekunova
4 октября 2013, 16:22
JavaScript API Яндекс.Карт 2.1-beta — новый дизайн и новые возможности

Сегодня мы опубликовали большой пост на Хабре о бета-версии JS API 2.1. Вы можете прочитать его также в этом блоге.image

Мы выпустили бета-версию API Яндекс.Карт 2.1. Главная ее особенность — полный редизайн интерфейса карты. Причем изменения затронули не только внешний вид, но и поведение элементов управления картой. Поскольку изначально было понятно, что поломки обратной совместимости не избежать, мы также внесли архитектурные изменения, которые были необходимы для улучшения работы API (о них ближе к концу поста).

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

Для решения наших задач мы решили в новой версии реализовать адаптивный дизайн интерфейса. На Yet another Conference дизайнер madhare и разработчик zloylos выступили с докладом о том, зачем нам понадобилась адаптивность и как именно мы ее реализовали в API. В этом посте я опишу предысторию и концепцию наших решений, расскажу о том, что еще нового появилось в версии 2.1-beta, а также о том, что еще изменится к релизу 2.1.

Зачем мы думаем о дизайне?


После релиза версии 2.0 мы уже писали пост, в котором рассказывали о нашем подходе к разработке API. Суть концепции заключается в том, что мы делаем продукт не только для разработчиков, но и для тех, кто будет пользоваться результатами их работы. Если человеку будет удобно и приятно пользоваться нашими картами, и он будет требовать от любимых сервисов именно их — это будет настоящий успех. При этом разработчикам тоже должно быть легко и приятно удовлетворять желания пользователей, а значит мы должны по-максимуму упростить их работу с API. С такими мыслями мы начали работу над версией 2.0, а новая 2.1-бета стала логичным продолжением этой же концепции.

Исследование


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

  • Решают типовые задачи, не хотят тратить много времени, предпочитают готовые интерфейсы Яндекса. Таких примерно 90%.
  • Решают нестандартные задачи или предпочитают даже типовые задачи решать по-своему. Им не подходят стандартные элементы управления. Нужна серьезная кастомизация карт. Логично, что это оставшиеся 10%.


Итак, нам нужно было сделать хорошо первым, оставив пространство для маневра вторым. Т.е. подготовить набор готовых решений, которые сами контролируют внешний вид итоговой карты, т.е. «делают хорошо», но при этом при желании их можно настроить под собственные нужды. Задачей максимум стало соблюсти баланс. 

image

Определившись с аудиториями, мы начали изучать кейсы использования. Оказалось, что в нашем случае основное значение имеет, как ни странно, размер. У нас получилось 3+1 варианта: маленькая, средняя, большая карта и мобильные сайты.

Рисуем дизайн для карт разных размеров


Самый тяжелый случай — маленькие карты. Кажется, что из-за маленького размера стоит убирать все элементы управления картой, но и терять функциональность тоже не хочется. Поэтому специально для маленьких карт мы сделали новый набор контролов:
image

Также был добавлен новый элемент управления — «развернуть карту на весь экран». Он экономит место на сайте за счет размещения небольшой карты, а у конечного пользователя остается возможность посмотреть большую карту. Все нужное поведение карты запрограммировано уже на стороне API. Вообще идея этой кнопки родилась, когда мы думали о решении для мобильных устройств. Карта приемлемого размера на десктопе может стать совершенно бесполезной на мобильном. Фулскрин решает эту проблему:
image

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

Со средними картами все гораздо проще. Поскольку есть, где развернуться:
image

Как и с большими картами:
image

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

map.controls.add('default'); 


Список доступных ключей:
smallMapDefaultSet // для маленькой
mediumMapDefaultSet // для обычной
largeMapDefaultSet // для большой

Разумеется, по-прежнему можно самостоятельно указывать нужные контролы.

myMap.controls .add('trafficControl') // пробки .add('searchControl') // поиск .add('zoomControl') // зум-контрол .add('typeSelector') // слои .add('geolocationControl') // геолокация .add('fullscreenControl') // фуллскрин … 



Адаптивность


Недостаточно просто отрисовать дизайн интерфейса для разных размеров карт. Ведь страницу с картой могут открывать на разных экранах. Именно поэтому решено было реализовывать адаптивное поведение интерфейсов карты. Различные элементы интерфейса перестраиваются и меняют свой размер в зависимости от фактического размера контейнера карты.
image

Адаптивное поведение мы реализовали через control.Manager. Также его можно задавать и для тех кнопок и списков, которые вы создаете сами:
image
image

Работы по ускорению и оптимизации


Геообъект — это главная сущность на карте. За такой титул ему приходится расплачиваться довольно сложной и громоздкой структурой. Первая итерация работ над геообъектами заключалась в распределении нагрузки при их создании. Мы постарались вынести все подготовительные операции из конструктора геообъекта в места, где они действительно становятся нужны. Это дало очень хорошие результаты. Также в некоторых местах мы сделали ленивую инициализацию сущностей с помощью _defineGetter_ и defineProperty (_defineGetter_, кстати, немного быстрее). Мы сократили количество подписок на события геообъектов внутри нашей системы событий. Частично помог прием подписки сразу на группу геообъектов с последующим определением в обработчике целевого объекта. Здесь нужно признаться, что ускорение можно пощупать только на dom и canvas метках, новые svg метки нам предстоит дорабатывать (why we call it beta? Because it beta then nothing…

Во время работы у нас было время на небольшую уборку в коде, по ее результатам приведем микровыводы:
Микровывод 1. При передаче функции-обработчика намного выгоднее передавать отдельно функцию, отдельно контекст. Если у вас чешутся руки сделать bind сразу, подумайте, можете ли вы это себе позволить. 
Микровывод 2. Сокращайте количество промежуточных массивов, объектов и анонимных функций. Они не всегда хорошо чистятся garbage collector-ом.

Прочие изменения

 

  1. В версии API 2.0 для определения местоположения по IP или с помощью Geolocation API разработчикам приходится самостоятельно использовать необходимые методы и обрабатывать полученный результат. В версии 2.1 достаточно просто добавить новый стандартный элемент управления: 
    control.GeolocationControl(parameters) 
    Также был улучшен механизм определения местоположения пользователя, используемый в API. Теперь автоматически выбирается наиболее точный результат из браузерной геолокации и геолокации по IP-адресу.
  2. Стандартные метки в API были перерисованы в SVG, а это значит, что им можно задавать произвольные цвета.
  3. Система пакетов в версии 2.1 будет ликвидирована. Интерфейсы API изменены таким образом, чтобы максимально вынести загрузку компонент API по требованию, для чего большинство отображений были переведены в асинхронный режим. Работы еще ведутся.
  4. Для такого масштабного обновления нам пришлось пожертвовать обратной совместимостью с версией 2.0. Также к официальному релизу версии 2.1 может сломаться обратная совместимость для некоторых частей бета-версии:
    • Существенно изменится кластеризатор.
    • Будет переписан map.action.Manager.
    • Promises будут реализованы по спецификации DOM.
    • Часть объектов в неймспейсе ymaps будет вынесена в загрузку по требованию.
  5. После выхода из беты версии 2.1 изменится система версионирования. До официального релиза подключить последнюю версию API можно будет только по ссылке api-maps.yandex.ru/2.1-dev. 


Справочник по программному интерфейсу API 2.1-beta опубликован на сайте API. Примеры можно посмотреть в песочнице. А также на новом API уже работает бета-версия Яндекс.Карт.

обновление,API 2.1,статьи
Пример и много полезного о кластеризаторе
tekunova
6 сентября 2013, 18:12
Пример и много полезного о кластеризаторе

Несмотря на то, что кластеризатор в API Яндекс.Карт появился полтора года назад, вопросы, связанные с этой технологией постоянно появляются у нас в клубе разработчиков (вы можете найти их по метке «кластеризатор»). Прежде всего это связано с тем, что кластеризатор — это сейчас, пожалуй, самая популярная функциональность API. 

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

Прежде всего рекомендуем вам посмотреть примеры сайтов, которые уже используют кластеризацию, затем почитайте руководство разработчика. В коде примера, который мы сегодня публикуем, вы найдете подсказки, которые помогут вам сделать нужные настройки. В Песочнице на сайте API также есть полезные примеры: общий пример, макет стандартного балуна кластера, макет балуна кластера «Аккордеон», макет балуна кластера «Карусель».

Кластеризация

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

Если вы написали статью или хотите рассказать о своей реализации, пишите нам в клуб, facebook или на почту ymapsapi@ya.ru.

API 2.0,примеры,кластеризатор,статьи
Компонент Improve My City для Joomla и Яндекс.Карты
tekunova
5 сентября 2013, 16:21
Компонент Improve My City для Joomla и Яндекс.Карты

В блоге «Занимательная веб-картография» опубликована информация об адаптированном для работы с Яндекс.Картами компоненте Improve My City, позволяющем организовывать сбор геопривязанных обращений пользователей.

improve my city

Сайтов, на которых организован прием пользовательских сообщений немало. Среди них, например, ГИС «Краснодар» и StreetJournal. С помощью готового компонента сделать свою реализацию теперь намного проще.

Если вы написали статью или хотите рассказать о своей реализации, пишите нам в клуб, facebook или на почту ymapsapi@ya.ru.

статьи пользователей,CMS,API 2.0,примеры проектов,Joomla,статьи