Как в классе MarkerClusterer Google Maps API V3 создать несколько стилей для MarkerClusters на основе уровня масштабирования?

В старом классе @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. было раньше.

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
0
690
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В рендерере может быть любая логика. Поскольку вы хотите изменить значок кластера в зависимости от уровня масштабирования, вы можете просто добавить этот фрагмент логики и соответствующим образом изменить значок маркера.

Я бы также предложил использовать 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>

Итак, могу ли я просто определить пять разных стилей, соответствующих пяти «mcOptions» выше, и использовать ваш класс, чтобы просто указать класс на правильный в зависимости от уровня масштабирования?

Raetekusu 05.04.2024 03:09

Почему нет? Вы не пробовали?

MrUpsidown 05.04.2024 09:07

Работаю над этим сейчас (но не после полудня, до вторника из-за Eclipse Vacay). По какой-то причине обновленный кластеризатор маркеров не хочет взаимодействовать с расширенным элементом маркера. AME появятся в моей программе вместе с альтернативными значками и всем остальным, как задумано. Но ничего не кластеризуется. Вероятно, где-то ошибка в моей логике, или, может быть, мне нужно быть очень конкретным в отношении значений, которые я передаю. В конце концов я это получу, но пока не могу сказать наверняка.

Raetekusu 05.04.2024 17:23

Код в моем ответе использует расширенные маркеры как для маркеров, так и для маркеров кластера.

MrUpsidown 07.04.2024 15:45

Хорошо, поздний ответ, теперь, когда я вернулся к этому. Так что да, я заставил их работать. Я знал, что это проблема с моей реализацией, но пытался понять, в чем именно, и наконец понял. Однако стиль кластера маркеров работает не совсем так, как хотелось бы. Я добавил некоторую логику в свой рендерер на основе вашего кода, и он не пересчитывает масштаб и, следовательно, не кластеризует класс CSS всякий раз, когда я увеличиваю или уменьшаю масштаб. Но я могу поработать над этим завтра. Я просто рад, что продвинутые маркеры и кластеры наконец-то начали работать вместе.

Raetekusu 09.04.2024 23:44

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

MrUpsidown 10.04.2024 08:35

Да, у меня это работает. Так что да, вопрос завершен. Спасибо за помощь.

Raetekusu 10.04.2024 19:00

Другие вопросы по теме