Объекты на карте
- Общие сведения
- Типы геобъектов
- Визуальное редактирование
- Задание стиля метки
- Задание собственного изображения для метки
- Использование CSS-спрайтов
- Метки с пиктограммами
- Метки-диаграммы
- Как задать диаграмму для значка метки
- Как установить диаграмму для значка кластера
- Как построить диаграмму для кластера на основе произвольных данных
- Коллекции геообъектов
- Кластеры
Общие сведения
Географическим объектам реального мира ставятся в соответствие программные объекты — геообъекты. К геообъектам относятся метки, круги, ломаные, прямоугольники, многоугольники, а также их коллекции.
Каждый геообъект описывается геометрией, которая задается геометрическим типом и координатами.
Базовым классом, реализующим геообъект является GeoObject.
Экземпляр карты размещает геообъекты в собственном хранилище, реализованном в виде коллекции, ссылка на которую находится в поле geoObjects. Добавление геообъекта на карту, его изменение и удаление производится с помощью обращения к этой коллекции.
var myMap = new ymaps.Map("map", {
center: [55.76, 37.64],
zoom: 10
});
// Создание геообъекта с типом точка (метка).
var myGeoObject = new ymaps.GeoObject({
geometry: {
type: "Point", // тип геометрии - точка
coordinates: [55.8, 37.8] // координаты точки
}
});
// Размещение геообъекта на карте.
myMap.geoObjects.add(myGeoObject);
Для каждого типа геометрии определен вспомогательный класс, предоставляющий упрощенный синтаксис для создания геообъекта. Например, создать метку можно с помощью вспомогательного класса Placemark:
// Вспомогательный класс, который можно использовать
// вместо GeoObject c типом геометрии «Point» (см. предыдущий пример)
var myPlacemark = new ymaps.Placemark([55.8, 37.6]);
myMap.geoObjects.add(myPlacemark);
Список вспомогательных классов приведен ниже.
Типы геобъектов
В таблице ниже приведен список геообъектов и их геометрий, используемых в классе GeoObject. Так же приведен список соответствующих вспомогательных классов.
Геообъект |
Пример |
Метка (тип геометрии: «Point») |
Создание метки с помощью класса
Создание метки c помощью вспомогательного класса Placemark:
|
Ломаная линия (тип геометрии: «LineString») |
Создание ломаной с помощью класса
Создание ломаной c помощью вспомогательного класса Polyline:
|
Прямоугольник (тип геометрии: «Rectangle») |
Создание прямоугольника с помощью класса
Создание прямоугольника c помощью вспомогательного класса Rectangle:
|
Многоугольник (тип геометрии: «Polygon») |
Создание многоугольника с помощью класса
Создание многоугольника c помощью вспомогательного класса Polygon:
|
Круг (тип геометрии: «Circle») |
Создание круга с помощью класса
Создание круга c помощью вспомогательного класса Circle:
|
Тип геометрии присваивается геообъекту в момент его создания и не может быть изменен в дальнейшем. При этом координаты геометрии могут быть изменены как программно, так и пользователем с помощью визуального редактора.
var myPlacemark = new ymaps.Placemark([55.754952, 37.615319], {}, {
draggable: true, // Метку можно перемещать.
preset: 'islands#whiteStretchyIcon'
});
myPlacemark.events.add('dragend', function(e) {
// Получение ссылки на объект, который был передвинут.
var thisPlacemark = e.get('target');
// Определение координат метки
var coords = thisPlacemark.geometry.getCoordinates();
// и вывод их при щелчке на метке
thisPlacemark.properties.set('balloonContent', coords);
});
Если геообъект был инициализирован без указания геометрии, то он не будет отображаться на карте. Присвоить тип геометрии такому геообъекту также будет невозможно.
Визуальное редактирование
Географические свойства геообъекта могут быть изменены пользователем в визуальном режиме. Для этого API предоставляет два способа: перемещение геообъекта как целого и визуальный редактор.
За возможность перетаскивания геообъекта как целого отвечает опция draggable
, которая может принимать значения true
и false
.
Визуальный редактор доступен для геообъектов с типом геометрии точка, ломаная, круг и многоугольник. Ссылка на редактор содержится в поле editor экземпляра соответствующего класса.
|
|
Задание стиля метки
API предоставляет возможность выбрать стиль для значка метки из набора встроенных стилей. С помощью стилей задается цвет значка метки, а также его тип (например, значок без содержимого или значок, растягивающийся под контент).
Каждому стилю из набора ставится в соответствие уникальный ключ. Для того чтобы установить нужный стиль, следует указать в качестве значения опции preset
соответствующий ключ:
|
Примечание
Стилем по умолчанию является 'islands#blueIcon'
.
Задание собственного изображения для метки
В качестве иконки метки можно установить собственное изображение. Для этого необходимо задать следующие опции:
iconLayout
— значение 'default#image' или 'default#imageWithContent' для меток соответственно без текста и с текстом поверх картинки;iconImageHref
— URL графического файла значка;iconImageSize
— размер значка в пикселах;iconImageOffset
— сдвиг значка в пикселах относительно точки привязки (задается, если "ножка" значка не находится в левом верхнем углу изображения);iconContentOffset
— для меток с текстом сдвиг текста относительно точки привязки метки.
|
|
Использование CSS-спрайтов
Если на карту необходимо добавить большое число меток с разными пользовательскими значками, то целесообразно использовать технологию CSS спрайтов. Суть технологии заключается в том, что все изображения объединяются в одном графическом файле — спрайте. Посредством CSS нужное изображение извлекается из спрайта и устанавливается в качестве значка определенной метки.
Ниже приведен пример спрайта, содержащего три изображения:
Для того чтобы установить нужное изображение в качестве значка метки, необходимо данной метке задать следующие опции:
iconLayout
— макет иконки. Для опции должно быть установлено значение 'default#image';iconImageCliptRect
— позиция нужного изображения в спрайте. Определяется пиксельными координатами левого верхнего и правого нижнего углов прямоугольника, в котором размещается изображение;iconImageHref
— URL спрайта;iconImageSize
— размер значка в пикселах;iconImageOffset
— сдвиг значка в пикселах относительно точки привязки (задается, если "ножка" значка не находится в левом верхнем углу изображения).
|
|
Использование технологии спрайтов позволяет сократить число HTTP-запросов к серверу, так как вместо большого числа изображений загружается только одно.
Подробнее о задании стиля для иконок меток см. в примере.
Метки с пиктограммами
API позволяет добавлять на карту метки с пиктограммами (Glyphicons).
Внимание
Для использования пиктограмм необходимо подключить CSS-стили Bootstrap:
<link rel="stylesheet" type="text/css" href="https://yastatic.net/bootstrap/3.3.4/css/bootstrap.min.css">
Чтобы создать метку с пиктограммой, необходимо в конструкторе метки задать следующие опции:
preset
— тип метки. Указывается с префиксом 'glyph'. Например, 'islands#glyphCircleIcon' (метка в виде круга) или 'islands#glyphIcon' (метка с хвостиком). Также через данную опцию можно задать цвет метки. Например, 'islands#redGlyphIcon'.iconGlyph
— название пиктограммы. Список доступных пиктограмм приведены на странице Glyphicons. Обратите внимание, что название задается без префикса 'glyph'. Например, 'asterisk' или 'plus'.iconGlyphColor
(необязательная опция) — цвет пиктограммы. Цвет может быть задан тремя способами: с помощью ключевого слова и в форматах Hex и RGB. Если опция не задана, по умолчанию используется пиктограмма черного цвета.iconColor
(необязательная опция) — цвет метки. Цвет может быть задан тремя способами: с помощью ключевого слова и в форматах Hex и RGB. По умолчанию используется метка голубого цвета.
Ниже показан пример создания меток с пиктограммами:
|
|
Метки-диаграммы
В качестве значка метки или кластера можно установить круговую диаграмму. Это может быть полезным, когда пользователям нужно показать какую-нибудь статистику, например процент школ и поликлиник в разных районах города.
Примечание
Диаграммы рисуются с использованием технологии Canvas, поэтому они не будут отображаться в браузерах, которые не поддерживают Canvas (в частности, IE8).
Как задать диаграмму для значка метки
Чтобы установить диаграмму для значка метки, этой метке нужно задать опцию iconLayout
со значением 'default#pieChart'
. Кроме того, метке нужно задать свойство data
― на основе его содержимого будет формироваться диаграмма. Это свойство должно содержать описание секторов диаграммы. Каждый сектор описывается JSON-объектом с полями:
weight
— вес сектора диаграммы. Может принимать произвольное значение. Например, '120'.color
— цвет сектора. Цвет указывается в шестнадцатеричном коде (например, '#FFFFFF') или с помощью названия, поддерживаемого в CSS (например, 'red').
Пример:
data: [
// Вес красного сектора.
{ weight: 52, color: 'red' },
// Вес зеленого сектора.
{ weight: 42, color: '#880011' },
// Вес желтого сектора.
{ weight: 23, color: '#035201' },
// Вес синего сектора.
{ weight: 12, color: '#002f55' }
]
Сколько объектов задано в массиве data
, столько секторов будет на диаграмме. Ограничений на количество секторов нет.
Пример задания диаграммы для значка метки:
|
|
Внимание
Если для метки не указано свойство data
, то возникнет ошибка и метка не будет отображена на карте.
По умолчанию в центре диаграммы будет отображаться суммарный вес всех секторов. При необходимости можно указать любой другой текст или сделать центральную часть пустой. Кроме того, для диаграммы можно настраивать другие параметры, например подпись, радиус и др. Настройки диаграммы задаются через опции метки. Список всех настроек см. в справочнике.
|
|
При клике на диаграмме откроется балун с заданным содержимым.
Как установить диаграмму для значка кластера
Диаграмму можно установить также и для значка кластера. В этом случае диаграмма будет строиться на основе цветов меток, входящих в состав этого кластера. Такая диаграмма отображает распределение меток в кластере по цветам.
Чтобы установить диаграмму для кластера, ему нужно задать опцию clusterIconLayout
со значением 'default#pieChart'
. Обратите внимание, что свойство data
задавать не нужно. Оно будет игнорироваться.
|
|
Внимание
В центре диаграммы будет отображаться общее число меток, входящих в состав кластера. Если в центре необходимо показать другой текст или нужно задать подпись к диаграмме, следует переопределить функцию createCluster. Пример см. ниже.
При клике на диаграмме увеличится масштаб карты и кластер разобьется на одиночные метки, входящие в состав этого кластера. Чтобы отключить это поведение, следует выставить опцию clusterDisableClickZoom
в true
. В этом случае при клике на диаграмме будет открываться балун.
Если в составе кластера есть метки с собственными изображениями, то на диаграмме эти метки будут принадлежать сектору голубого цвета. Чтобы изменить цвет сектора для таких меток, им следует задать опцию iconColor
с нужным цветом.
Как построить диаграмму для кластера на основе произвольных данных
Чтобы для кластера построить диаграмму на основе произвольных данных, следует переопределить функцию createCluster. Внутри этой функции необходимо задать свойства и опции кластера, а также определить данные, на основе которых будет построена диаграмма.
Ниже показано, как создать диаграмму для кластера на основе произвольных данных:
var myMap = new ymaps.Map('map', {
center: [-10.702218, 57.527526],
zoom: 0,
controls: []
});
// Создаем кластер.
var clusterer = new ymaps.Clusterer({});
// Метки, входящие в состав кластера.
var myPlacemark1 = new ymaps.Placemark([55.85, 32.64], {
// Задаем содержимое балуна метки.
// Это содержимое будет отображаться при клике по кластеру.
balloonContentHeader: 'Метка № 1',
balloonContentBody: 'Не мысля гордый свет забавить,</br>' +
'Вниманье дружбы возлюбя,</br>' +
'Хотел бы я тебе представить</br>' +
'Залог достойнее тебя,'
});
var myPlacemark2 = new ymaps.Placemark([55.15, 32.14], {
balloonContentHeader: 'Метка № 2',
balloonContentBody: 'Достойнее души прекрасной,</br>' +
'Святой исполненной мечты,</br>' +
'Поэзии живой и ясной,</br>' +
'Высоких дум и простоты;'
});
// Переопределяем функцию создания кластера.
clusterer.createCluster = function (center, geoObjects) {
// Наследуем все поля класса.
var clusterPlacemark = ymaps.Clusterer.prototype.createCluster.call(this, center, geoObjects);
// Устанавливаем свойства кластера.
clusterPlacemark.properties.set({
// Данные для построения диаграммы.
data: [
{ weight: 4, color: '#408022' },
{ weight: 4, color: '#802240' }
],
// Подпись к диаграмме.
iconCaption: 'Диаграмма кластера',
});
// Задаем опции кластера.
clusterPlacemark.options.set('iconLayout', 'default#pieChart');
clusterPlacemark.options.set('balloonContentLayout', 'cluster#balloonTwoColumns');
clusterPlacemark.options.set('balloonPanelContentLayout', 'cluster#balloonTwoColumns');
clusterPlacemark.options.set('disableClickZoom', true);
clusterPlacemark.options.set('openBalloonOnClick', true);
clusterPlacemark.options.set('balloonLeftColumnWidth', 60);
clusterPlacemark.options.set('balloonPanelMaxMapArea', 0);
clusterPlacemark.options.set('balloonContentLayoutHeight', 200);
clusterPlacemark.options.set('balloonContentLayoutWidth', 300);
clusterPlacemark.options.set('balloonItemContentLayout', 'cluster#balloonTwoColumnsItemContent');
return clusterPlacemark;
};
clusterer.add(myPlacemark1)
.add(myPlacemark2);
myMap.geoObjects.add(clusterer);
Результат:
Обратите внимание, что в центре диаграммы отображается не суммарный вес секторов, а число меток, входящих в состав кластера. Чтобы показать суммарный вес, необходимо пройтись по всем полям weight
и сумму весов указать в опции iconContent
.
Коллекции геообъектов
Геообъекты могут объединяться в коллекции, которые позволяют определять свойства сразу всех своих членов и проводить групповые операции над ними.
Геообъект может принадлежать только одной коллекции. При добавлении геообъекта, принадлежащего одной коллекции, в другую коллекцию, он будет удален из первой.
|
|
Вы можете реализовать собственный класс коллекции, которая может быть размещена на карте; для этого необходимо реализовать интерфейс IMapObjectCollection.
Кластеры
Точечные геообъекты могут находиться настолько близко друг другу, что на каком-то масштабе их метки начинают накладываться друг на друга. В этом случае пользователю приходится тщательно «прицеливаться», чтобы попасть курсором мыши на видимый фрагмент нужной метки. Существует даже специальный термин, описывающий эффекты такого рода — pixel hunting (пиксель-хантинг).
|
|
Если метки находятся в одной точке и размеры их иконок совпадают, то наведение на перекрытые метки невозможно в принципе.
Стандартным способом решения проблемы является объединение близко расположенных объектов в группу (кластер) и использование для группы специальной кластерной иконки. Часто на иконке кластера указывается число содержащихся в нем элементов.
Для кластеризации объектов в API Яндекс Карт используется класс Clusterer.
|
|
При увеличении масштаба кластер визуально распадается на отдельные метки и/или другие кластеры.
При щелчке на иконке кластера может произойти либо увеличение коэффициента масштабирования либо открытие балуна, в котором будет отображен список геообъектов кластера. Это поведение контролируется с помощью опции clusterDisableClickZoom
(true/false).
var myGeoObjects = [];
for (var i = 0; i < coords.length; i++) {
myGeoObjects[i] = new ymaps.GeoObject({
geometry: {
type: "Point",
coordinates: coords[i]
},
properties: {
clusterCaption: 'Геообъект № '+(i+1),
balloonContentBody: 'Текст балуна № '+(i+1)
}
});
}
var myClusterer = new ymaps.Clusterer(
{clusterDisableClickZoom: true}
);
myClusterer.add(myGeoObjects);
myMap.geoObjects.add(myClusterer);
Примечание
Если при отображении кластера коэффициент масштабирования карты является максимальным, то кластер не будет распадаться на отдельные метки при щелчке на его маркере. В этом случае независимо от значения параметра clusterDisableClickZoom
всегда будет открываться балун.
Таким образом, отобразить информацию о близко расположенных геообъектах можно даже в том случае, если их метки накладываются друг на друга при максимальном коэффициенте масштабирования.
Использование кластеризатора позволяет значительно увеличить производительность при отображении большого количества геообъектов в браузере.
Отрисовка и обработка геообъекта — дорогостоящая с точки зрения потребления ресурсов операция, и чем больше объектов кластеризуется, тем больше ресурсов экономится. Сильное снижение производительности наблюдается уже при отображении нескольких сотен объектов без кластеризации.