在 Google Maps API V3 MarkerClusterer 类中,如何根据缩放级别为 MarkerClusters 创建多种样式?

问题描述 投票:0回答:1

在旧的

@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 google-maps markerclusterer
1个回答
0
投票
渲染器中可以有任何逻辑。由于您想根据缩放级别更改群集图标,因此您可以简单地添加这段逻辑并相应地更改标记图标。

我还建议使用 SVG 作为标记(这里有一些示例:

https://googlemaps.github.io/js-markerclusterer/public/renderers/)或 HTML 与高级标记结合使用。

以下示例将高级标记与 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", }); 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 }) => { // 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;
  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>

© www.soinside.com 2019 - 2024. All rights reserved.