Разработка клиентской части

Создание менеджера

Менеджер создается с помощью класса LoadingObjectManager. Его конструктору необходимо передать параметры:
Параметр Тип Описание
urlTemplate * String

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

В шаблоне могут использоваться следующие подстановки:

  • %b – заменяется на массив географических координат углов области. Указываются координаты левого нижнего и правого верхнего углов области.
  • %t – заменяется на номера левого верхнего и правого нижнего тайлов запрашиваемой области. Номера перечисляются через запятую. Например, '1,1,2,3'.
  • %c – заменяется на строку вида: 'x={номер тайла по X}&y={номер тайла по Y}&z={уровень масштабирования}'. Например: 'x=1&y=2&z=10'. Подстановка доступна только при splitRequests=true.
  • %x – номер тайла по X. Подстановка доступна только при splitRequests=true.
  • %y – номер тайла по Y. Подстановка доступна только при splitRequests=true.
  • %z – уровень масштабирования.

Например, пусть шаблон URL данных имеет следующий вид:

https://server.ru/?tileNumber=%t&z=%z

Тогда для области с угловыми тайлами [1,1] и [5,5], и z=10 менеджер выполнит подстановку:

https://server.ru/?tileNumber=1,1,5,5&z=10.

options Object

Опции менеджера. Список доступных опций.

* Обязательный параметр.

Пример создания менеджера:

var loadingObjectManager = new ymaps.LoadingObjectManager('//server.com/tile?bbox=%b', {   
    // Включаем кластеризацию.
    clusterize: true,
    // Зададим опции кластерам.
    // Опции кластеров задаются с префиксом cluster.
    clusterHasBalloon: false,
    // Опции объектов задаются с префиксом geoObject.
    geoObjectOpenBalloonOnClick: false
});
Чтобы менеджер начал загружать объекты с сервера, необходимо добавить менеджер на карту.
myMap.geoObjects.add(loadingObjectManager);

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

Настройка взаимодействия менеджера с сервером

Ниже перечислены опции, с помощью которых можно настраивать взаимодействие менеджера с сервером:

  • paddingParamName — имя GET-параметра, который содержит название callback-функции. По умолчанию принимает значение 'callback'.
  • paddingTemplate — шаблон названия callback-функции, в которую сервер должен обернуть ответ. Если параметр не указан, менеджер будет автоматически генерировать новые названия callback-функций каждый раз перед отправкой запроса: '{URL данных}?callback=id_1234567'.
  • splitRequests — режим, в котором менеджер будет загружать данные с сервера. Параметр может принимать два значения: false — менеджер будет загружать данные для всей видимой области сразу, и true — данные будут загружаться отдельно по тайлам. По умолчанию splitRequests=false. Подробнее о режимах загрузки данных.

Получение доступа к объектам менеджера

Загруженные объекты сохраняются в коллекции objectManager.ObjectCollection. Ссылка на эту коллекцию содержится в поле LoadingObjectManager.objects.

Для работы с объектами менеджера доступны методы:

  • each() – проход по объектам менеджера;
  • getAll() – возвращает массив объектов менеджера;
  • getById() – возвращает объект по его идентификатору;
  • getLength() – возвращает количество объектов в менеджере;
  • setObjectOptions – позволяет задать опции объектам.

Список всех методов приведен в справочнике.

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

function onObjectClick (e) {
   // objectId – идентификатор объекта, на котором произошло событие.
   var objectId = e.get('objectId');  
   var object = objectManager.objects.getById(objectId);
   // Выведем информацию об объекте.
   console.log('Тип объекта: ' + object.geometry.type);
   console.log('Координаты объекта: ' + object.geometry.coordinates);
}

// Подписываемся на событие клика по объекту.
loadingObjectManager.objects.events.add(['click'], onObjectClick);

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

LoadingObjectManager позволяет кластеризовать метки. Чтобы включить кластеризацию, конструктору менеджера следует передать опцию clusterize: true.

Объекты-кластеры менеджер размещает в коллекции objectManager.ClusterCollection. Ссылка на коллекцию содержится в поле LoadingObjectManager.clusters.

Внимание. Коллекция кластеров доступна только на чтение. Менеджер не позволяет самостоятельно добавлять или удалять кластеры из коллекции.

Структура объекта-кластера

Объект-кластер представляет собой JSON-структуру с полями:

  • id – идентификатор кластера. Генерируется менеджером.
  • number – количество меток в кластере.
  • geometry – геометрия. Представляет собой объект с полями: type и coordinates.
  • properties – данные кластера. Представляет собой объект, содержащий поле geoObjects – массив меток, входящих в кластер. Кроме того, объект properties может содержать другие поля, заданные разработчиком (например, balloonContent).
  • options – опции кластера. Необязательное поле.

Операции с коллекцией кластеров

Для работы с коллекцией кластеров доступны методы:

  • each() – проход по объектам-кластерам;
  • getAll() – возвращает список всех объектов-кластеров в коллекции;
  • getById() – возвращает объект-кластер по идентификатору (идентификаторы кластеров генерирует менеджер);
  • getLength() – количество объектов-кластеров в коллекции;
  • setClusterOptions() – задать опцию для объекта-кластера.

Список всех методов см. в справочнике.

Объекты-кластера создаются в асинхронном режиме. Это означает, что на момент вызова указанных методов объекты-кластеры могут быть еще не добавлены в коллекцию. Для избежания ошибок рекомендуется отслеживать события на коллекции кластеров и производить операции с кластерами только в обработчиках событий. Например:
var loadingObjectManager = new ymaps.LoadingObjectManager('http://server.com/tile?bbox=%b',
      {   
        // Включаем кластеризацию.
        clusterize: true,
        // Опции кластеров задаются с префиксом cluster.
        clusterHasBalloon: false,
        // Опции объектов задаются с префиксом geoObject.
        geoObjectOpenBalloonOnClick: false
      });

// Добавим менеджер на карту.
myMap.geoObjects.add(loadingObjectManager);

// Выведем количество кластеров в коллекции.
console.log(loadingObjectManager.clusters.getLength()); // --> 0, так как объекты-кластеры
                                                        // еще не были созданы.

function onAddCluster (e) {
    // Выведем количество кластеров в коллекции. 
    console.log(loadingObjectManager.clusters.getLength()); // --> 1, 2, 3..
}

// Подписываемся на событие добавления кластера в коллекцию.
loadingObjectManager.clusters.events.add(['add'], onAddCluster);

Поиск объектов

Пример демонстрирует поиск объектов менеджера, для которых не задано содержимое балуна (поле properties.balloonContent):

function onObjectCollectionAdd (e) {
    // object – объект, который был добавлен в коллекцию.
    var object = e.get('child');
    if ((!object.properties) || (!object.properties.balloonContent)) {
        console.log("Для объекта с идентификатором " + object.id + " не задано содержимое балуна.");
    }
}

// Подписываемся на событие добавления объекта в менеджер.
loadingbjectManager.objects.events.add(['add'], onObjectCollectionAdd);

Фильтрация объектов

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

Для фильтрации объектов предназначен метод setFilter(). В качестве параметра ему необходимо передать строку, содержащую условие отбора объектов, либо функцию-фильтр, которая должна возвращать true или false.

// Пропустить объекты, id которых меньше 100.
loadingObjectManager.setFilter('id > 100');

// На карте будут отображаться только объекты с заданными типами.
loadingObjectManager.setFilter('properties.type === "кафе" || properties.type === "аптека"');

// Можно задавать функцию-фильтр.
loadingObjectManager.setFilter(function (object) {
  return object.properties.name !== 'Тот, кого нельзя показывать.';
});

Задание опций объектам

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

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

Задание опций для одиночного объекта

Чтобы задать опцию для объекта менеджера, нужно использовать метод setObjectOptions(). Методу нужно передать два аргумента: идентификатор объекта, для которого нужно задать опцию, и объект, содержащий новые значения опций. Список опций, которые можно задавать для объектов менеджера, приведены в классе GeoObject.

// Задаем стиль для объекта с идентификатором 4 (это метка).
loadingObjectManager.objects.setObjectOptions(4, {
    preset: 'islands#greenDotIcon'
});
Внимание. Менеджер объектов не учитывает опцию геообъектов visible. При задании этой опции она будет проигнорирована.

Если нужно задать опцию для объекта-кластера, используется метод setClusterOptions(). Методу также нужно передать идентификатор кластера и нужные опции. Обратите внимание, что идентификаторы кластеров генерируются менеджером. Узнать идентификатор нужного кластера можно из объекта-события, подписавшись на события коллекции кластеров.

function onClusterCollectionAdd (e) {
   var cluster = e.get('child');
   // Для кластеров, в состав которых входит больше 10 меток,
   // зададим значок красного цвета.
   if (cluster.number > 10) {
       loadingObjectManager.clusters.setClusterOptions(cluster.id, {
           preset: 'islands#redClusterIcons'
       });
   }
}
// Подписываемся на событие добавления кластера в коллекцию.
loadingObjectManager.clusters.events.add(['add'], onClusterCollectionAdd);

Подробнее о событиях менеджера

Задание опций всей коллекции объектов

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

Для задания опций коллекции используется метод set(). В качестве параметров методу нужно передать объект, содержащий значения опций:

// Задаем опции для коллекции одиночных объектов (опция применится для меток).
loadingObjectManager.objects.options.set({ preset: 'islands#yellowIcon' });

// Задаем опции для объектов-кластеров.
loadingObjectManager.clusters.options.set({ preset: 'islands#yellowClusterIcons' });
Внимание. Менеджер объектов не учитывает опцию visible. При задании этой опции она будет проигнорирована.

Обработка событий на объектах

События на объектах менеджера распространяются на родительские коллекции. Это означает, что если необходимо отслеживать события на всех объектах менеджера, то обработчик события достаточно назначить для коллекции объектов.

События можно отслеживать как на коллекции одиночных объектов менеджера, так и на коллекции объектов-кластеров.

Пример 1. Отслеживание событий на одиночных объектах:

// При клике на метке изменяем цвет ее иконки на желтый.
function onObjectEvent (e) {
  var objectId = e.get('objectId'),
      objectGeometry = loadingObjectManager.objects.getById(objectId).geometry.type;
  // Если событие произошло на метке, изменяем цвет ее иконки.
  if (objectGeometry === 'Point') {
    loadingObjectManager.objects.setObjectOptions(objectId, {
      preset: 'islands#yellowIcon'
    });
  }
}

// Назначаем обработчик событий на коллекцию объектов менеджера.   
loadingObjectManager.objects.events.add(['click'], onObjectEvent);

Пример 2. Отслеживание событий на объектах-кластерах:

// При наведении указателя мыши на метки их иконки окрашиваются в желтый.
// При покидании указателя цвет иконок окрашивается в голубой.
function onClusterEvent (e) {
  var objectId = e.get('objectId');
  if (e.get('type') === 'mouseenter') {
    loadingObjectManager.clusters.setObjectOptions(objectId, {
      preset: 'islands#yellowIcon'
    });
  } else if (e.get('type') === 'mouseleave') {
    loadingObjectManager.clusters.setObjectOptions(objectId, {
      preset: 'islands#blueIcon'
    });
  }  
}

// Назначаем обработчик событий для коллекции объектов-кластеров менеджера.
loadingObjectManager.clusters.events.add(['mouseenter', 'mouseleave'], onClusterEvent);

Удаление обработчиков события

Для удаления обработчиков событий используется метод remove(). Первым аргументом необходимо передать тип события (или список типов), вторым аргументом — ссылку на функцию-обработчик, которую необходимо удалить.

// Подпишемся на несколько событий объектов-кластеров.
loadingObjectManager.clusters.events.add(['mouseenter', 'click', 'mouseleave'], onClusterEvent);
// Удалим две подписки.
loadingObjectManager.clusters.events.remove(['click', 'mouseleave'], onClusterEvent);