YMapClusterer
Использование класса YMapClusterer помогает отобразить на карте большое количество маркеров.
При увеличении масштаба карты отдельные маркеры объединяются в кластер, при уменьшении масштаба карты кластер распадается на отдельные маркеры.
Совет
Использование кластера позволяет значительно увеличить производительность при отображении большого количества маркеров на карте.
Примечание
Данный класс является компонентом пакета @yandex/ymaps3-clusterer и предоставляет дополнительную функциональность в JS API, которая не входит в основное API.
Для подключения пакета воспользуйтесь инструкцией.
Пример использования
Создание карты и добавление кластера на карту
Объявляем переменную для map, загружаем библиотеку ymaps3, извлекаем необходимые классы.
window.map = null;
async function main() {
await ymaps3.ready;
const {YMap, YMapDefaultSchemeLayer, YMapMarker, YMapLayer, YMapFeatureDataSource} = ymaps3;
//...
}
Загружаем пакет с кластером, извлекаем классы для создания кластеризованных объектов и метод кластеризации.
const {YMapClusterer, clusterByGrid} = await ymaps3.import('@yandex/ymaps3-clusterer');
Создаем и добавляем на карту слой со схемой по умолчанию, источниками данных, слоем маркеров.
map = new YMap(document.getElementById('app'), {location: {center: [37.62, 55.62], zoom: 10}});
map
.addChild(new YMapDefaultSchemeLayer())
.addChild(new YMapFeatureDataSource({id: 'my-source'}))
.addChild(new YMapLayer({source: 'my-source', type: 'markers', zIndex: 1800}));
Можете задать любую разметку для маркера и для кластера.
const contentPin = document.createElement('div');
contentPin.innerHTML = '<img src="./pin.svg" />';
Объявляем функцию для рендеринга обычных маркеров, отправим ее в настройки кластера.
Обратите внимание, что функция должна возвращать любой элемент Entity. В примере это ymaps3. Map marker.
const marker = (feature) =>
new ymaps3.YMapMarker(
{
coordinates: feature.geometry.coordinates,
source: 'my-source'
},
contentPin.cloneNode(true)
);
Что касается обычных маркеров, объявляем функцию рендеринга кластера, которая также возвращает элемент сущности.
const cluster = (coordinates, features) =>
new ymaps3.YMapMarker(
{
coordinates,
source: 'my-source'
},
circle(features.length).cloneNode(true)
);
function circle(count) {
const circle = document.createElement('div');
circle.classList.add('circle');
circle.innerHTML = `
<div class="circle-content">
<span class="circle-text">${count}</span>
</div>
`;
return circle;
}
Давайте объявим массив с координатами маркеров, затем создадим массив объектов с соответствующим интерфейсом. Мы передадим его в настройки кластера.
const coordinates = [
[37.64, 55.76],
[37.63, 55.7],
[37.43, 55.69],
[37.47, 55.68],
[38.53, 58.6],
[37.59, 55.71],
[37.5, 55.63],
[37.52, 55.57],
[37.52, 58.57],
[40.52, 58.57]
];
const points = coordinates.map((lnglat, i) => ({
type: 'Feature',
id: i,
geometry: {coordinates: lnglat},
properties: {name: 'Point of issue of orders'}
}));
Cоздаем объект cluster и добавляем его в объект map.
В качестве параметров мы передаем метод кластеризации, массив объектов, функции для рендеринга маркеров и кластеров.
Для метода кластеризации мы передадим размер деления сетки в пикселях.
const clusterer = new YMapClusterer({
method: clusterByGrid({gridSize: 64}),
features: points,
marker,
cluster
});
map.addChild(clusterer);
}
Использование кластера с React JS
Объявляем переменную для map, загружаем библиотеку ymaps3, извлекаем необходимые классы.
window.map = null;
main();
async function main() {
await ymaps3.ready;
const ymaps3React = await ymaps3.import('@yandex/ymaps3-reactify');
const reactify = ymaps3React.reactify.bindTo(React, ReactDOM);
const {
YMap,
YMapDefaultSchemeLayer,
YMapLayer,
YMapFeatureDataSource,
YMapMarker
} = reactify.module(ymaps3);
Соединяем пакет с кластером, извлекаем классы для создания кластеризованных объектов и метод кластеризации.
const {YMapClusterer, clusterByGrid} = reactify.module(await ymaps3.import('@yandex/ymaps3-clusterer@0.0.1'));
Извлекаем необходимые хуки. Давайте объявим массив с координатами маркеров, затем создадим массив объектов с соответствующим интерфейсом.
Передаем его в настройки кластера.
const {useCallback, useMemo} = React;
const coordinates = [
[37.64, 55.76],
[37.63, 55.7],
[37.43, 55.69],
[37.47, 55.68],
[38.53, 58.6],
[37.59, 55.71],
[37.5, 55.63],
[37.52, 55.57],
[37.52, 58.57],
[40.52, 58.57]
];
const points = coordinates.map((lnglat, i) => ({
type: 'Feature',
id: i,
geometry: {coordinates: lnglat},
properties: {name: 'Point of issue of orders'}
}));
Объявляем функцию рендеринга. Для метода кластеризации мы передаем и сохраняем размер одного деления сетки в пикселях.
function App() {
const gridSizedMethod = useMemo(() => clusterByGrid({ gridSize: 64 }), []);
// ...
}
Объявляем функцию для отображения обычных маркеров. Обратите внимание, что функция должна возвращать любой элемент Entity. В примере это ymaps3.Map marker.
const marker = useCallback(
(feature) => (
<YMapMarker coordinates={feature.geometry.coordinates} source={'my-source'}>
<img src={'./pin.svg'} />
</YMapMarker>
),
[]
);
Объявляем функцию рендеринга кластера, которая также возвращает элемент сущности. Мы перенесем функции рендеринга маркера и кластера в настройки кластера.
const cluster = useCallback(
(coordinates, features) => (
<YMapMarker coordinates={coordinates} source={'my-source'}>
<div className="circle">
<div className="circle-content">
<span className="circle-text">{features.length}</span>
</div>
</div>
</YMapMarker>
),
[]
);
Возвращаем JSX, в котором мы визуализируем компоненты карты, слой по умолчанию, источники данных, слой для маркеров и кластеризатор.
В cluster props мы передаем ранее объявленные функции для рендеринга маркеров и кластеров, метод кластеризации и массив объектов.
return <React.Fragment>
<YMap location={LOCATION} ref={x => map = x}>
<YMapDefaultSchemeLayer />
<YMapFeatureDataSource id="my-source"/>
<YMapLayer source="my-source" type="markers" zIndex={1800}/>
<YMapClusterer
marker={marker}
cluster={cluster}
method={gridSizedMethod}
features={points}
/>
</YMap>
</React.Fragment>;
// ...
ReactDOM.render(<App />, document.getElementById("app"));
}
window.map = null;
main();
async function main() {
const [ymaps3Vue] = await Promise.all([ymaps3.import('@yandex/ymaps3-vuefy'), ymaps3.ready]);
const vuefy = ymaps3Vue.vuefy.bindTo(Vue);
const {YMap, YMapDefaultSchemeLayer, YMapLayer, YMapFeatureDataSource, YMapMarker} =
vuefy.module(ymaps3);
const {YMapClusterer, clusterByGrid} = vuefy.module(await ymaps3.import('@yandex/ymaps3-clusterer'));
const initialPoints = getRandomPoints(100, BOUNDS);
const gridSizedMethod = clusterByGrid({gridSize: 64});
const app = Vue.createApp({
components: {
YMap,
YMapDefaultSchemeLayer,
YMapFeatureDataSource,
YMapLayer,
YMapMarker,
YMapClusterer
},
setup() {
const clusterer = Vue.ref(true);
const points = Vue.ref(initialPoints);
const updatePoints = () => {
points.value = getRandomPoints(pointsCount.value || rndNum(), map.bounds);
};
const toggleClusterer = () => {
clusterer.value = !clusterer.value;
};
const refMap = (ref) => {
window.map = ref?.entity;
};
return {LOCATION, clusterer, points, gridSizedMethod, updatePoints, toggleClusterer, refMap};
},
template: `
<div className="toolbar">
<input id="pointsCount" defaultValue="100" placeholder="Count" />
<button type="button" @click="updatePoints">Update points</button>
<button type="button" @click="toggleClusterer">Delete/Add Clusterer</button>
</div>
<YMap :location="LOCATION" :ref="refMap">
<YMapDefaultSchemeLayer />
<YMapFeatureDataSource id="clusterer-source"/>
<YMapLayer source="clusterer-source" type="markers" :zIndex="1800"/>
<YMapClusterer v-if="clusterer" :method="gridSizedMethod" :features="points">
<template #marker="{feature}">
<YMapMarker :key="feature.id" :coordinates="feature.geometry.coordinates" source="clusterer-source">
<img src="./pin.svg" className="pin"/>
</YMapMarker>
</template>
<template #cluster="{coordinates, features}">
<YMapMarker
:key="features[0].id + features.length"
:coordinates="coordinates"
source="clusterer-source">
<div className="circle">
<div className="circle-content">
<span className="circle-text">{{features.length}}</span>
</div>
</div>
</YMapMarker>
</template>
</YMapClusterer>
</YMap>`
});
app.mount('#app');
}
Конструктор
new YMapClusterer(props)
Параметры конструктора
|
Параметр |
Тип |
|
|
Переопределяет
Props
YMapClustererProps: Object
Объявление типа
|
Параметр |
Тип |
Описание |
|
|
( |
Функция для создания маркера для кластера. |
|
|
|
Объект для кластеризации на карте. |
|
|
( |
Функция для создания маркера для точки. |
|
|
|
Максимальное увеличение для кластеризации. Если увеличить масштаб карты, маркеры будут отображаться как есть. |
|
|
Метод кластеризации. |
|
|
|
( |
Возвращается значение |
|
|
|
Количество времени, которое может пройти до повторного вызова метода рендеринга. |
Методы
update
update(changedProps): void
Параметры
|
Параметр |
Тип |
Описание |
|
|
Новые значения |
Возвращается
void