סקירה כללית
במדריך הזה תלמדו איך להשתמש באשכול סמנים כדי להציג מספר גדול של סמנים במפה. אפשר להשתמש בספרייה @googlemaps/markerclusterer בשילוב עם ממשק API של JavaScript במפות Google כדי לשלב סמנים שנמצאים בסמיכות רבה באשכול, ולפשט את הצגת הסמנים במפה.
כדי לראות איך עובד קיבוץ של סמנים, אפשר לעיין במפה שבהמשך.
המספר על אשכול מציין את מספר הסמנים שהוא מכיל. שימו לב שככל שמגדילים את התצוגה של אחד המיקומים באשכול, המספר באשכול קטן והסמנים הבודדים מתחילים להופיע במפה. כשמרחיבים את המפה, הסימנים מתקבצים שוב לאשכולות.
בדוגמה הבאה מוצג הקוד המלא שדרוש כדי ליצור את המפה הזו.
TypeScript
import { MarkerClusterer } from "@googlemaps/markerclusterer"; async function initMap() { // Request needed libraries. const { Map, InfoWindow } = await google.maps.importLibrary("maps") as google.maps.MapsLibrary; const { AdvancedMarkerElement, PinElement } = await google.maps.importLibrary("marker") as google.maps.MarkerLibrary; const map = new google.maps.Map( document.getElementById("map") as HTMLElement, { zoom: 3, center: { lat: -28.024, lng: 140.887 }, mapId: 'DEMO_MAP_ID', } ); const infoWindow = new google.maps.InfoWindow({ content: "", disableAutoPan: true, }); // Create an array of alphabetical characters used to label the markers. const labels = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; // Add some markers to the map. const markers = locations.map((position, i) => { const label = labels[i % labels.length]; const pinGlyph = new google.maps.marker.PinElement({ glyph: label, glyphColor: "white", }) const marker = new google.maps.marker.AdvancedMarkerElement({ position, content: pinGlyph.element, }); // markers can only be keyboard focusable when they have click listeners // open info window when marker is clicked marker.addListener("click", () => { infoWindow.setContent(position.lat + ", " + position.lng); infoWindow.open(map, marker); }); return marker; }); // Add a marker clusterer to manage the markers. new MarkerClusterer({ markers, map }); } const locations = [ { lat: -31.56391, lng: 147.154312 }, { lat: -33.718234, lng: 150.363181 }, { lat: -33.727111, lng: 150.371124 }, { lat: -33.848588, lng: 151.209834 }, { lat: -33.851702, lng: 151.216968 }, { lat: -34.671264, lng: 150.863657 }, { lat: -35.304724, lng: 148.662905 }, { lat: -36.817685, lng: 175.699196 }, { lat: -36.828611, lng: 175.790222 }, { lat: -37.75, lng: 145.116667 }, { lat: -37.759859, lng: 145.128708 }, { lat: -37.765015, lng: 145.133858 }, { lat: -37.770104, lng: 145.143299 }, { lat: -37.7737, lng: 145.145187 }, { lat: -37.774785, lng: 145.137978 }, { lat: -37.819616, lng: 144.968119 }, { lat: -38.330766, lng: 144.695692 }, { lat: -39.927193, lng: 175.053218 }, { lat: -41.330162, lng: 174.865694 }, { lat: -42.734358, lng: 147.439506 }, { lat: -42.734358, lng: 147.501315 }, { lat: -42.735258, lng: 147.438 }, { lat: -43.999792, lng: 170.463352 }, ]; initMap();
JavaScript
import { MarkerClusterer } from "@googlemaps/markerclusterer"; async function initMap() { // Request needed libraries. const { Map, InfoWindow } = await google.maps.importLibrary("maps"); const { AdvancedMarkerElement, PinElement } = await google.maps.importLibrary( "marker", ); const map = new google.maps.Map(document.getElementById("map"), { zoom: 3, center: { lat: -28.024, lng: 140.887 }, mapId: "DEMO_MAP_ID", }); const infoWindow = new google.maps.InfoWindow({ content: "", disableAutoPan: true, }); // Create an array of alphabetical characters used to label the markers. const labels = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; // Add some markers to the map. const markers = locations.map((position, i) => { const label = labels[i % labels.length]; const pinGlyph = new google.maps.marker.PinElement({ glyph: label, glyphColor: "white", }); const marker = new google.maps.marker.AdvancedMarkerElement({ position, content: pinGlyph.element, }); // markers can only be keyboard focusable when they have click listeners // open info window when marker is clicked marker.addListener("click", () => { infoWindow.setContent(position.lat + ", " + position.lng); infoWindow.open(map, marker); }); return marker; }); // Add a marker clusterer to manage the markers. new MarkerClusterer({ markers, map }); } const locations = [ { lat: -31.56391, lng: 147.154312 }, { lat: -33.718234, lng: 150.363181 }, { lat: -33.727111, lng: 150.371124 }, { lat: -33.848588, lng: 151.209834 }, { lat: -33.851702, lng: 151.216968 }, { lat: -34.671264, lng: 150.863657 }, { lat: -35.304724, lng: 148.662905 }, { lat: -36.817685, lng: 175.699196 }, { lat: -36.828611, lng: 175.790222 }, { lat: -37.75, lng: 145.116667 }, { lat: -37.759859, lng: 145.128708 }, { lat: -37.765015, lng: 145.133858 }, { lat: -37.770104, lng: 145.143299 }, { lat: -37.7737, lng: 145.145187 }, { lat: -37.774785, lng: 145.137978 }, { lat: -37.819616, lng: 144.968119 }, { lat: -38.330766, lng: 144.695692 }, { lat: -39.927193, lng: 175.053218 }, { lat: -41.330162, lng: 174.865694 }, { lat: -42.734358, lng: 147.439506 }, { lat: -42.734358, lng: 147.501315 }, { lat: -42.735258, lng: 147.438 }, { lat: -43.999792, lng: 170.463352 }, ]; initMap();
CSS
/* * Always set the map height explicitly to define the size of the div element * that contains the map. */ #map { height: 100%; } /* * Optional: Makes the sample page fill the window. */ html, body { height: 100%; margin: 0; padding: 0; }
HTML
<html> <head> <title>Marker Clustering</title> <link rel="stylesheet" type="text/css" href="./style.css" /> <script type="module" src="./index.js"></script> </head> <body> <div id="map"></div> <!-- 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: "AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg", v: "weekly"});</script> </body> </html>
ניסיון של דוגמה
כדי להמחיש את הנושא, במדריך הזה מוסיפה קבוצה של סמנים למפה באמצעות המערך locations
. אתם יכולים להשתמש במקורות אחרים כדי לקבל סמנים למפה.
מידע נוסף זמין במדריך בנושא יצירת סמנים.
הוספת מקבץ סמנים
כדי להוסיף אשכול של סמנים:
- מוסיפים את ספריית האשכולות של הסמנים לדף או לאפליקציה. הספרייה זמינה ב-NPM בכתובת @googlemaps/markerclusterer ובמאגר ב-GitHub.
NPM
מתקינים את הגרסה האחרונה של הספרייה @googlemaps/markerclusterer באמצעות NPM.
npm install @googlemaps/markerclusterer
CDN
הסקריפט הבא טוען את הגרסה האחרונה 1.x.x של הספרייה מ-unpkg.com CDN.
<script src="https://unpkg.com/@googlemaps/markerclusterer/dist/index.min.js"></script>
- מוסיפים לאפליקציה אשכול של סמנים.
הקוד הבא מוסיף למפה אשכול של סמנים.
NPM
import { MarkerClusterer } from "@googlemaps/markerclusterer"; const markerCluster = new MarkerClusterer({ markers, map });
CDN
כשנכנסים לספרייה דרך ה-CDN, היא זמינה ברמת
markerClusterer
הגלובלית.const markerCluster = new markerClusterer.MarkerClusterer({ markers, map });
בדוגמה הזו, מעבירים את המערך
markers
ל-MarkerClusterer
. - התאמה אישית של הכלי לצבירה של סמנים.
- התאמה אישית של סמל האשכולות דרך ממשק ה-Renderer.
- לשנות את האלגוריתם ליצירת אשכולות.
מידע נוסף
אפשר לראות דוגמאות מורכבות יותר של קיבוץ סמנים במאגר ב-GitHub ולקרוא את מסמכי העזרה של הספרייה.