В старом классе @google/markercluster вы могли передать переменную styles, которая могла содержать несколько стилей кластера, которые затем можно было передать в конструктор markerCluster, как показано ниже.
var clusterStyles = [
{
textColor: 'white',
url: '../Images/MapIcons/m1.png',
height: 53,
width: 53,
},
{
textColor: 'white',
url: '../Images/MapIcons/m2.png',
height: 57,
width: 57,
},
{
textColor: 'white',
url: '../Images/MapIcons/m3.png',
height: 66,
width: 66,
},
{
textColor: 'white',
url: '../Images/MapIcons/m4.png',
height: 78,
width: 78,
},
{
textColor: 'white',
url: '../Images/MapIcons/m5.png',
height: 89,
width: 89,
}
markerCluster = new MarkerClusterer(map, markers,mcOptions);
Затем кластер будет обрабатывать уровни масштабирования, изменяя используемый значок, а также размер соответствующего значка. Значок уменьшался при дальнейшем увеличении, чтобы они не перекрывались.
Однако новая реализация MarkerClusterer заменяет это объектом Renderer, который, насколько я могу судить, допускает только одно определение, а не несколько, поэтому не поддерживает масштабирование.
let renderer = {
render: ({ count, position }) =>
new google.maps.Marker({
label: {
text: String(count),
color: "white",
},
position,
icon: {
url: '../Images/MapIcons/m5.png',
height: 89,
width: 89,
},
zIndex: Number(google.maps.Marker.MAX_ZINDEX) + count,
}
),
};
let algorithm = new markerClusterer.SuperClusterAlgorithm({ maxZoom: 15 });
map.setOptions({ minZoom: 5, maxZoom: 20 });
markerCluster = new markerClusterer.MarkerClusterer({
map: map,
markers: markers,
renderer: renderer,
algorithm: algorithm });
Есть ли способ обрабатывать несколько стилей, чтобы значок, высота и ширина менялись по мере увеличения масштаба?
Как вы можете видеть, я попробовал преобразовать один стиль, и это работает хорошо, но значки остаются того же размера относительно экрана, чем больше вы увеличиваете масштаб, пока вы не приблизитесь достаточно близко, и это просто беспорядок перекрывающихся кластеров. При необходимости я всегда могу уменьшить его размер, но если размер текста становится достаточно большим, он выходит за пределы кластера, и мне все равно хотелось бы иметь в виду что-то более элегантное, ближе к тому, что было в старой версии библиотеки markerClusterer. было раньше.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


В рендерере может быть любая логика. Поскольку вы хотите изменить значок кластера в зависимости от уровня масштабирования, вы можете просто добавить этот фрагмент логики и соответствующим образом изменить значок маркера.
Я бы также предложил использовать SVG для ваших маркеров (некоторые примеры здесь: https://googlemaps.github.io/js-markerclusterer/public/renderers/ ) или HTML в сочетании с Advanced Markers.
В приведенном ниже примере используются расширенные маркеры с элементами HTML. Увеличьте масштаб, чтобы увидеть изменение значка кластера.
async function initMap() {
// Request needed libraries.
const { Map } = await google.maps.importLibrary("maps");
const { AdvancedMarkerElement } = await google.maps.importLibrary("marker");
const center = {
lat: 0,
lng: 0
};
const map = new Map(document.getElementById("map"), {
center: center,
zoom: 2,
mapId: "4504f8b37365c3d0",
zoomControl: true
});
const markers = [];
// Define the max latitude on a mercator projection
var maxLat = Math.atan(Math.sinh(Math.PI)) * 180 / Math.PI;
// Loop and create many markers
for (let i = 0; i < 2000; i++) {
// Calculate a random lat and lng
const lat = Math.floor(Math.random() * (maxLat * 2)) - maxLat;
const lng = Math.floor(Math.random() * 360) - 180;
const marker = new AdvancedMarkerElement({
map: map,
position: new google.maps.LatLng(lat, lng),
title: "AdvancedMarkerElement"
});
markers.push(marker);
}
let algorithm = new markerClusterer.SuperClusterAlgorithm({
maxZoom: 15
});
// Marker clusterer
const cluster = new markerClusterer.MarkerClusterer({
map: map,
markers: markers,
algorithm: algorithm,
renderer: {
render: ({
count,
position
}, stats, map) => {
// Create a custom cluster HTML element to be used with an AdvancedMarker
const el = document.createElement("div");
// Change appearance based on current zoom
el.className = map.getZoom() > 2 ? 'cluster red' : 'cluster';
// Set content
el.textContent = String(count);
// Return AdvancedMarkerElement
return new AdvancedMarkerElement({
position: position,
content: el,
title: "AdvancedMarkerElement Cluster"
});
}
}
});
}
initMap();#map {
height: 180px;
}
.cluster {
font-size: 1.5em;
background-color: yellow;
padding: .25em .5em;
transform: rotate(5deg);
}
.red {
color: white;
font-size: 2em;
font-weight: bold;
background-color: red;
transform: rotate(-5deg);
}<div id = "map"></div>
<script src = "https://unpkg.com/@googlemaps/markerclusterer/dist/index.min.js"></script>
<!-- prettier-ignore -->
<script>(g=>{var h,a,k,p = "The Google Maps JavaScript API",c = "google",l = "importLibrary",q = "__ib__",m=document,b=window;b=b[c]||(b[c] = {});var d=b.maps||(b.maps = {}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement("script"));e.set("libraries",[...r]+"");for(k in g)e.set(k.replace(/[A-Z]/g,t=>"_"+t[0].toLowerCase()),g[k]);e.set("callback",c+".maps."+q);a.src=`https://maps.${c}apis.com/maps/api/js?`+e;d[q]=f;a.onerror=()=>h=n(Error(p+" could not load."));a.nonce=m.querySelector("script[nonce]")?.nonce||"";m.head.append(a)}));d[l]?console.warn(p+" only loads once. Ignoring:",g):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))})
({key: "AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk", v: "beta"});</script>Почему нет? Вы не пробовали?
Работаю над этим сейчас (но не после полудня, до вторника из-за Eclipse Vacay). По какой-то причине обновленный кластеризатор маркеров не хочет взаимодействовать с расширенным элементом маркера. AME появятся в моей программе вместе с альтернативными значками и всем остальным, как задумано. Но ничего не кластеризуется. Вероятно, где-то ошибка в моей логике, или, может быть, мне нужно быть очень конкретным в отношении значений, которые я передаю. В конце концов я это получу, но пока не могу сказать наверняка.
Код в моем ответе использует расширенные маркеры как для маркеров, так и для маркеров кластера.
Хорошо, поздний ответ, теперь, когда я вернулся к этому. Так что да, я заставил их работать. Я знал, что это проблема с моей реализацией, но пытался понять, в чем именно, и наконец понял. Однако стиль кластера маркеров работает не совсем так, как хотелось бы. Я добавил некоторую логику в свой рендерер на основе вашего кода, и он не пересчитывает масштаб и, следовательно, не кластеризует класс CSS всякий раз, когда я увеличиваю или уменьшаю масштаб. Но я могу поработать над этим завтра. Я просто рад, что продвинутые маркеры и кластеры наконец-то начали работать вместе.
Откройте новый вопрос, если у вас есть проблемы с реализацией. Пожалуйста, отметьте этот ответ как принятый, если он отвечает на ваш первоначальный вопрос.
Да, у меня это работает. Так что да, вопрос завершен. Спасибо за помощь.
Итак, могу ли я просто определить пять разных стилей, соответствующих пяти «mcOptions» выше, и использовать ваш класс, чтобы просто указать класс на правильный в зависимости от уровня масштабирования?