Блог API Яндекс.Карт

декабрь 2013
Эволюция API Яндекс.Карт от версии 1.x до 2.1-beta
2 декабря 2013, 14:41

От разработчика для разработчиков. Вся история API Яндекс.Карт в одном докладе. 7-8 декабря в Омске на Базе отдыха им. Стрельникова пройдет конференция HappyDev’13, посвященная вопросам разработки, на которой выступит разработчик интерфейсов API Яндекс.Карт Антон Корзунов.

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

Кто хочет послушать доклад Антона, приходите 8 декабря в Малый зал конференции. Именно там в секции Frontend с 13:35 по 14:05 Антон расскажет все секреты эволюции API и ответит на вопросы посетителей.

Подробная программа мероприятия.

Нет комментариев
конференции,анонсы
API Яндекс.Карт версия 2.0.36
3 декабря 2013, 16:53

Сегодня опубликована новая версия API Яндекс.Карт — 2.0.36 с исправленным инвертированием scroll zoom в Chrome. Она доступна по адресу api-maps.yandex.ru/2.0.36. В четверг, 5 декабря, мы переключим на нее api-maps.yandex.ru/2.0. Если вы хотите продолжить использование предыдущей версии, указывайте api-maps.yandex.ru/2.0.35. Наряду с этим в четверг, 5 декабря, мы планируем переключить api-maps.yandex.ru/2.0-stable на версию API 2.0.35.

Пожалуйста, прочтите статью о системе версионирования API.

Добавлено:

— Параметр options в ymaps.GeoQueryResult.applyBoundsToMap.

— Параметр context в метод ymaps.GeoQueryResult.each.

Исправлено:

— Инвертированный scroll zoom в Chrome.

— Срабатывание изменений масштаба карты по длительному нажатию в IE10 и IE11.

— Срабатывание mapStateAutoApply и zoomMargin даже если ответ маршрутизатора отклоняется.

— Ошибки в CanvasTile в случаях, когда изображение не загружено.

— Утечка памяти при удалении подписчиков события на лету.

— Баг верстки контрола пробок в новых версиях Safari.

— Обработка правого клика в браузерах, поддерживающих pointer-события.

— В некоторых случаях линия моргала, если при наведении увеличивать strokeWidth.

— Некорректная обработка visible у геообъекта, который находится внутри кластера

— Генерация лишнего события click перед contextmenu в pointer-событиях.

— Ошибки при клике на кластер в режиме groupByCoordinates.

Команда разработчиков API Яндекс.Карт

5 комментариев
обновление,API 2.0
Переключение 2.0 и 2.0-stable
5 декабря 2013, 13:51

Мы переключили api-maps.yandex.ru/2.0 на версию API 2.0.36. Если вы хотите продолжить использование предыдущей версии, указывайте api-maps.yandex.ru/2.0.35. Также мы переключили api-maps.yandex.ru/2.0-stable на версию API 2.0.35.

Пожалуйста, прочтите статью о системе версионирования API.

Команда разработчиков API Яндекс.Карт.

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

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

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

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

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

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

Нет комментариев
метки,статьи,API 2.0,YMapsML,статьи пользователей
Яндекс обновил свои карты
7 декабря 2013, 13:56

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

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

Существенно улучшили маршрутизацию в Минске, Нижнем Новгороде, Ростове-на-Дону и Казани. Теперь качество маршрутизации в этих городах стало лучше примерно на 20%.

Кроме того, поработали над ошибками и неточностями — учли замечания и комментарии пользователей, а также внесли порядка 10 тысяч исправлений на картах России, Беларуси, Казахстана и Украины. Мы не собираемся останавливаться на достигнутом, ведь совершенству нет предела.

Продолжайте присылать нам свои замечания и пожелания к исправлению через специальную форму — maps.yandex.ru/feedback и вместе мы сделаем Яндекс.Карты еще лучше.

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

4 комментария
обновления карт
Адаптивность в неизвестности. Доклад про редизайн API Яндекс.Карт
9 декабря 2013, 12:14

Рады пригласить вас на Design Camp в Москве, мероприятие организованное Microsoft и Британской высшей школой дизайна. Именно там 12 декабря, дизайнер интерфейсов Яндекс.Карт, Александр Кудымов расскажет про рейдизайн API и про адаптивность. Из доклада вы узнаете почему адаптивный дизайн был наилучшим решением, как работать над таким дизайном, а также о том, какие есть тонкости и нюансы в работе, например, с прототипированием и многое другое. 

Приглашаем послушать доклад Александра с 15:15 до 16:00 в секции «Приложения, Игры, Сайты». Готовьте свои вопросы и приходите!

Подробная программа мероприятия.

Нет комментариев
дизайн,конференции,анонсы
Как создать картографический сайт на WordPress с помощью API Яндекс.Карт
10 декабря 2013, 16:10

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

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

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

Нет комментариев
статьи,API 2.0,wordpress,статьи пользователей
Плагин API Яндекс.Карт для CKEditor 4
11 декабря 2013, 14:13

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

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

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

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

2 комментария
статьи,API 2.0,плагины,статьи пользователей
Добавление пользовательских меток на карту через форму
12 декабря 2013, 17:00

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

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

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

Нет комментариев
статьи,API 2.0,метки,статьи пользователей
Три примера геокодирования
13 декабря 2013, 16:42

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

В примере прямого геокодирования подробно описаны все данные, которые содержит ответ геокодера. Один пример обратного геокодирования показывает, как можно использовать параметр kind для поиска объектов определенного типа. Другой — показывает как выполнить обратное геокодирование передвигаемой метки и актуален для случаев, когда метки на карту добавляют пользователи.

Весь код будет доступен в Песочнице.

Пользуйтесь и присылайте свои примеры в комментариях, в клубе или на нашей страничке в Facebook.

Нет комментариев
примеры,геокодирование,API 2.0
Интерактивная инфографика с помощью API Яндекс.Карт
17 декабря 2013, 14:53

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

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

Карту можно приближать и отдалять. На максимальном уровне приближения показаны 1000 самых популярных исполнителей, а также музыкальные направления от детских песен и шансона до тяжелого металла. На следующих трёх уровнях — исполнители, которых за год слушали не менее 1, 3 и 5 млн пользователей соответственно.

Посмотреть карту в новом окне.

Пользуйтесь и присылайте свои примеры в комментариях, в клубе или на нашей страничке в Facebook.

Нет комментариев
примеры,API 2.0
Новый модуль для CMS
18 декабря 2013, 14:51

Мы добавили новый модуль Planograph для 1С-Битрикс в раздел модули для CMS на сайте API Яндекс.Карт. С его помощью можно создать интерактивную карту супермаркета, разместить планы этажей бизнес-центра или жилого комплекса, а также наглядно отобразить статистическую, аналитическую и другую информацию с помощью API. 

Кроме этого, на странице с модулями можно найти готовые решения для NetCat, Wordpress, OpenCart, Drupal, Joomla и других CMS. Обращаем ваше внимание, что все перечисленные модули разработаны сторонними компаниями или людьми.

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

Нет комментариев
плагины,cms,API 2.0
API Яндекс.Карт версия 2.1.4
20 декабря 2013, 11:22

Опубликована новая версия API Яндекс.Карт 2.1-beta — 2.1.4. Она доступна по адресу api-maps.yandex.ru/2.1.4 и api-maps.yandex.ru/2.1-dev.

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

Добавлено:

— Возможность отображения всплывающей подсказки в кластеризаторе.

— В geometry.LineString добавлен метод getDistance.

— Поле currentTarget при распространении событий геообъектов.

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

— Значение опции clusterIconContentLayout можно выставить в null для отображения метки кластера без содержимого.

— Возможность задавать shape в описании меток кластеров.

— Параметр context в методе GeoQueryResult.each.

— Опция балуна panelMaxMapSize.

— Опция interactiveZIndex, которая отключает автозадание zIndex в зависимости от состояния геообъекта.

— Добавлен пейн overlaps.

— Опция iconOpacity для меток.

— Кнопка «показать ещё результаты» для элемента управления «Поиск по карте».

— Опция viewportMargin кластеризатора.

Изменено:

— Методы кластеризатора get, each, getIterator заменены на getGeoObjects и getClusters.

— Объект Cluster переименован в ClusterPlacemark.

— Улучшена логика проваливания в Народную карту.

— Метод работы с балуном кластера placemark.balloon.open и cluster.balloon.open.

— Теперь метки в кластеризатор всегда добавляются синхронно.

Исправлено:

— Ошибки работы API в Windows Phone 8.

— Ошибки с видимостью текста в поисковой строке.

— Ошибки с отображением копирайтов.

— Ошибки при позиционировании элементов списка при отрицательных индексах.

— Некорректное поведение кластеризатора при значении опции gridSize не равном степени двойки.

— На карте генерировались лишние события mouseleave в IE8 и IE9.

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

— Ошибки в удалении набора элементов управления с карты.

— Ошибки после включения режима рисования метки.

— Ошибки загрузки API без указания параметра load.

— Утечки памяти при удалении событий налету в domEvent.manager.

— Ошибки при клике правой кнопкой мыши в браузер с pointer-событиями.

— При открытии балуна панели копирайты не смещались вверх.

— Ошибки в верстке панели управления «Пробки» в Opera.

— Ошибки в верстке выпадающего списка.

— Неправильный учет zIndex оверлеев, которые находятся в разных пейнах.

— Инвертированный scroll zoom в Chrome.

— Ошибки в распространении событий на геообъектах не имеющих балуна.

— Неправильное перерисование балуна при изменении размеров карты или при перетаскивании метки.

— Проблемы с производительностью при использовании проекции Cartesian.

— В IE8 не появлялся балун при выходе из полноэкранного режима.

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

— Ломалась линейка после добавления новой точки из середины отрезка.

— Балун превращался в панель, если карта невысокая, но широкая.

— При открытии на метке балуна с autoPan на карте оставался курсор.

— Hintclose отображался по движению карты, даже если подсказки нет.

— Не менялся текст в элементе управления «Пробки» при перемещении в регион без данных.

— Ошибки в интерактивности меток при экспорте через YMapsML.

— Иконка не удалялась из кнопки после использования метода unset.

— Некорректно позиционировались подсказки над узлами линейки.

— Не скрывалась метка кластера при открытии балуна.

— Разные размеры точки линейки в IE и Opera.

— Съезжал балун у линии при зуме.

— Лишние mouseenter на объектах карты.

— При зуме колесом мыши вместе с картой скроллилась страница в Firefox.

— В режиме редактирования при продолжении линии пропадала часть отображающая «продолжение» при наведении.

— В некоторых случаях не изменялось значение поля GeoObject.state.get (‘hover’) при первом движении курсора.

— Правильный порядок событий click, select и press для FullscreenControl.

— Часть элементов управления не сворачивалась при mousedown на карте.

— В некоторых случаях балун не перемещалася вслед за геообъектом.

— Ошибки опции drawOver в geometryEditor.

— Ошибки при быстром завершении редактирования объектов.

— Ошибки при включении опции geodesic.

— Подсказка геообъекта открывалась при открытии балуна объекта активной области.

— Некорректная работа API при подключении библиотеки bootstrap.

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

— Ошибки при бросании balloonclose и balloonopen у хотспотов.

— Ошибки при autoPan при работе с линейкой.

— Не работала опция interactivityModel у всплывающих подсказок.

— При смене типа карты кнопки в зуме не переставали быть активными/неактивными.

— Не появлялся курсор в поисковой строке по нажатию на SearchControl.

— Ломалось перемещение геообъектов после перемещения касанием.

— В некоторых случаях перестраивался элемент управления выбора типа карты при смене опций.

— Лишнее сворачивание и разворачивание элементов управления при переходе в полноэкранный режим.

— Ошибки при удалении типов карты из control.TypeSelector.

— Ошибки рендеринга геометрий.

— Изменение размера карты по вертикали в полноэкранном режиме в IE8.

— Ошибки работы API в IE8.

Команда разработчиков API Яндекс.Карт

Нет комментариев
API 2.1,обновление
Чего ждать от W3C. Главные тренды 2014 года
23 декабря 2013, 16:06

Конец года — это хорошее время для подведения итогов и рассуждения о том, чего ждать от следующего года. На самом деле, этот пост не совсем про API. Это видео доклада нашего руководителя группы разработки API Яндекс.Карт Сергея Константинова. В 2013 году он стал участником Технической архитектурной группы Консорциума W3C, а 7 декабря в московском офисе Яндекса в рамках встречи Web Standards Days рассказал про тренды 2014 года от W3C.

По мнению Сергея, помимо новинок в HTML5, нас ждут глобальные изменения в самой веб-платформе. Promises и модули — революция в стандартах разработки стандартов. Service Workers — новый подход к решению проблемы офлайновых веб-приложений. @@create — отнаследуйся от HTMLElement!

Нет комментариев
видео,конференции
Почему мы сломали обратную совместимость в кластеризаторе
24 декабря 2013, 16:54

Сегодня мы опубликовали пост на Хабре, в котором разработчик интерфейсов 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).

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

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

3 комментария
API 2.1,статьи,кластеризатор
Карта России на английском
27 декабря 2013, 15:44

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

У тех, кто подключал API с локалью en-US, карта обновилась автоматически. Тем, кто хочет отображать через API англоязычную версию карты, нужно при подключении API в параметре lang задать локаль — en-US. Как это сделать подробно написано в документации. Локаль определяет язык, на котором отображаются надписи на карте и элементах управления, предпочтительный язык, на котором возвращаются результаты поиска по карте, и используемые по умолчанию единицы измерения.

Нет комментариев
обновления карт