Создание кластеризатора
Для объединения близко расположенных меток в группу (кластер) используется кластеризатор.
Кластеризатор реализуется классом Clusterer. В качестве параметров конструктору можно передать опции кластеризатора: стиль отображения значка кластера, размер его ячейки и т. д. Список доступных опций можно посмотреть в соответствующем разделе справочника.
Для добавления геообъектов в кластеризатор используется метод add. В качестве параметра может быть передан как отдельный геообъект, так и массив геообъектов.
index.html
clusterer_create.js
<!DOCTYPE html>
<html>
<head>
<title>Примеры. Добавление на карту кластеризатора меток</title>
<meta
http-equiv="Content-Type"
content="text/html; charset=utf-8"
/>
<link
href="https://yandex.st/bootstrap/3.0.0/css/bootstrap.min.css"
rel="stylesheet"
/>
<!--
Укажите свой API-ключ. Тестовый ключ НЕ БУДЕТ работать на других сайтах.
Получить ключ можно в Кабинете разработчика: https://developer.tech.yandex.ru/keys/
-->
<script
src="https://api-maps.yandex.ru/2.0/?lang=ru-RU&load=package.standard,package.clusters&apikey=<ваш API-ключ>"
type="text/javascript"
></script>
<script src="clusterer_create.js" type="text/javascript"></script>
</head>
<style type="text/css">
html,
body,
#YMapsID {
width: 100%;
height: 100%;
}
</style>
<body>
<div id="YMapsID"></div>
</body>
</html>
ymaps.ready(function () {
var myMap = (window.map = new ymaps.Map("YMapsID", {
center: [55.751574, 37.573856],
zoom: 9,
behaviors: ["default", "scrollZoom"],
})),
/**
* Создадим кластеризатор, вызвав функцию-конструктор.
* Список всех опций доступен в документации.
* @see http://api.yandex.ru/maps/doc/jsapi/2.x/ref/reference/Clusterer.xml#constructor-summary
*/
clusterer = new ymaps.Clusterer({
/**
* Через кластеризатор можно указать только стили кластеров,
* стили для меток нужно назначать каждой метке отдельно.
* @see http://api.yandex.ru/maps/doc/jsapi/2.x/ref/reference/option.presetStorage.xml
*/
preset: "twirl#invertedVioletClusterIcons",
/**
* Ставим true, если хотим кластеризовать только точки с одинаковыми координатами.
*/
groupByCoordinates: false,
/**
* Опции кластеров указываем в кластеризаторе с префиксом "cluster".
* @see http://api.yandex.ru/maps/doc/jsapi/2.x/ref/reference/Cluster.xml
*/
clusterDisableClickZoom: true,
}),
/**
* Функция возвращает объект-данных для метки.
* Поле данных clusterCaption будет отображено в списке геообъектов в балуне кластера.
* Поле balloonContentBody - источник данных для контента балуна.
* Оба поля поддерживают HTML-разметку.
* Список полей данных, которые используют стандартные макеты содержимого иконки метки
* и балуна геообъектов, можно посмотреть в документации.
* @see http://api.yandex.ru/maps/doc/jsapi/2.x/ref/reference/GeoObject.xml
*/
getPointData = function (index) {
return {
balloonContentBody:
"балун <strong>метки " + index + "</strong>",
clusterCaption: "метка <strong>" + index + "</strong>",
};
},
/**
* Функция возвращает объект-опций для метки.
* Все опции, которые поддерживают геообъекты можно посмотреть в документации.
* @see http://api.yandex.ru/maps/doc/jsapi/2.x/ref/reference/GeoObject.xml
*/
getPointOptions = function () {
return {
preset: "twirl#violetIcon",
};
},
points = [
[55.831903, 37.411961],
[55.763338, 37.565466],
[55.763338, 37.565466],
[55.744522, 37.616378],
[55.780898, 37.642889],
[55.793559, 37.435983],
[55.800584, 37.675638],
[55.716733, 37.589988],
[55.775724, 37.56084],
[55.822144, 37.433781],
[55.87417, 37.669838],
[55.71677, 37.482338],
[55.78085, 37.75021],
[55.810906, 37.654142],
[55.865386, 37.713329],
[55.847121, 37.525797],
[55.778655, 37.710743],
[55.623415, 37.717934],
[55.863193, 37.737],
[55.86677, 37.760113],
[55.698261, 37.730838],
[55.6338, 37.564769],
[55.639996, 37.5394],
[55.69023, 37.405853],
[55.77597, 37.5129],
[55.775777, 37.44218],
[55.811814, 37.440448],
[55.751841, 37.404853],
[55.627303, 37.728976],
[55.816515, 37.597163],
[55.664352, 37.689397],
[55.679195, 37.600961],
[55.673873, 37.658425],
[55.681006, 37.605126],
[55.876327, 37.431744],
[55.843363, 37.778445],
[55.875445, 37.549348],
[55.662903, 37.702087],
[55.746099, 37.434113],
[55.83866, 37.712326],
[55.774838, 37.415725],
[55.871539, 37.630223],
[55.657037, 37.571271],
[55.691046, 37.711026],
[55.803972, 37.65961],
[55.616448, 37.452759],
[55.781329, 37.442781],
[55.844708, 37.74887],
[55.723123, 37.406067],
[55.858585, 37.48498],
],
geoObjects = [];
/**
* Данные передаются вторым параметром в конструктор метки, опции третьим.
* @see http://api.yandex.ru/maps/doc/jsapi/2.x/ref/reference/Placemark.xml#constructor-summary
*/
for (var i = 0, len = points.length; i < len; i++) {
geoObjects[i] = new ymaps.Placemark(
points[i],
getPointData(i),
getPointOptions()
);
/**
* Так же их можно добавлять/менять динамически после создания меток.
* geoObjects[i].properties.set(getPointData(i));
* geoObjects[i].options.set(getPointOptions());
*/
}
/**
* Так же можно менять опции кластеризатора.
*/
clusterer.options.set({
gridSize: 80,
clusterDisableClickZoom: true,
});
/**
* В кластеризатор можно добавить javascript-массив меток (не геоколлекцию) или одну метку.
* @see http://api.yandex.ru/maps/doc/jsapi/2.x/ref/reference/Clusterer.xml#add
*/
clusterer.add(geoObjects);
/**
* Поскольку кластеры добавляются асинхронно,
* дождемся их добавления, чтобы выставить карте область, которую они занимают.
* Используем метод once чтобы сделать это один раз.
*/
clusterer.events.once("objectsaddtomap", function () {
myMap.setBounds(clusterer.getBounds());
});
/**
* Кластеризатор, расширяет коллекцию, что позволяет использовать один обработчик
* для обработки событий всех геообъектов.
* Выведем текущий геообъект, на который навели курсор, поверх остальных.
*/
clusterer.events
// Можно слушать сразу несколько событий, указывая их имена в массиве.
.add(["mouseenter", "mouseleave"], function (e) {
var target = e.get("target"), // Геообъект - источник события.
eType = e.get("type"), // Тип события.
zIndex = Number(eType === "mouseenter") * 1000; // 1000 или 0 в зависимости от типа события.
target.options.set("zIndex", zIndex);
});
/**
* После добавления массива геообъектов в кластеризатор,
* работать с геообъектами можно, имея ссылку на этот массив.
*/
clusterer.events.add("objectsaddtomap", function () {
for (var i = 0, len = geoObjects.length; i < len; i++) {
var geoObject = geoObjects[i],
/**
* Информацию о текущем состоянии геообъекта, добавленного в кластеризатор,
* а также ссылку на кластер, в который добавлен геообъект, можно получить с помощью метода getObjectState.
* @see http://api.yandex.ru/maps/doc/jsapi/2.x/ref/reference/Clusterer.xml#getObjectState
*/
geoObjectState = clusterer.getObjectState(geoObject),
// признак, указывающий, находится ли объект в видимой области карты
isShown = geoObjectState.isShown,
// признак, указывающий, попал ли объект в состав кластера
isClustered = geoObjectState.isClustered,
// ссылка на кластер, в который добавлен объект
cluster = geoObjectState.cluster;
if (window.console) {
console.log(
"Геообъект: %s, находится в видимой области карты: %s, в составе кластера: %s",
i,
isShown,
isClustered
);
}
}
});
myMap.geoObjects.add(clusterer);
});