Tổng quan
Hướng dẫn này cho bạn biết cách sử dụng các cụm điểm đánh dấu để hiển thị một số lượng lớn các điểm đánh dấu trên bản đồ. Bạn có thể sử dụng thư viện @googlemaps/markerclusterer cùng với API JavaScript của Maps để kết hợp các điểm đánh dấu vùng lân cận thành cụm và đơn giản hóa việc hiển thị điểm đánh dấu trên bản đồ.
Để xem cách tính năng phân nhóm điểm đánh dấu hoạt động, hãy xem bản đồ bên dưới.
Số trên một cụm cho biết số lượng điểm đánh dấu của cụm đó. Lưu ý rằng khi bạn phóng to vào bất kỳ vị trí nào trong cụm, số lượng trên cụm sẽ giảm và bạn bắt đầu nhìn thấy các điểm đánh dấu riêng lẻ trên bản đồ. Thu nhỏ bản đồ sẽ củng cố lại các điểm đánh dấu thành cụm.
Mẫu dưới đây cho thấy toàn bộ mã bạn cần để tạo bản đồ này.
TypeScript
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
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> <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script> <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>
Dùng thử mẫu
Như một minh họa đơn giản, hướng dẫn này sẽ thêm một tập hợp các điểm đánh dấu vào bản đồ bằng cách sử dụng mảng locations
. Bạn có thể sử dụng các nguồn khác để lấy điểm đánh dấu cho bản đồ của mình.
Để biết thêm thông tin, hãy đọc hướng dẫn về cách tạo điểm đánh dấu.
Thêm bộ đồng bộ điểm đánh dấu
Hãy làm theo các bước dưới đây để thêm trình tạo điểm đánh dấu:
- Thêm thư viện nhóm điểm đánh dấu vào trang hoặc ứng dụng của bạn. Thư viện này được cung cấp trên NPM tại @googlemaps/markerclusterer và trong kho lưu trữ trên GitHub.
Hàm NPM
Cài đặt phiên bản mới nhất của thư viện @googlemaps/markerclusterer bằng NPM.
npm install @googlemaps/markerclusterer
CDN (Mạng phân phối nội dung)
Tập lệnh bên dưới tải phiên bản 1.x.x mới nhất của thư viện từ unpkg.com CDN.
<script src="https://unpkg.com/@googlemaps/markerclusterer/dist/index.min.js"></script>
- Thêm một cụm điểm đánh dấu trong ứng dụng của bạn.
Mã bên dưới thêm một cụm đánh dấu vào bản đồ.
Hàm NPM
import { MarkerClusterer } from "@googlemaps/markerclusterer"; const markerCluster = new MarkerClusterer({ map, markers });
CDN (Mạng phân phối nội dung)
Khi được truy cập bằng CDN, thư viện có sẵn trong
markerClusterer
toàn cục.const markerCluster = new markerClusterer.MarkerClusterer({ map, markers });
Mẫu này sẽ chuyển mảng
markers
đếnMarkerClusterer
. - Tùy chỉnh cụm điểm đánh dấu.
- Tùy chỉnh biểu tượng cụm thông qua giao diện trình kết xuất.
- Sửa đổi thuật toán để tạo cụm.
Tìm hiểu thêm
Bạn có thể xem các ví dụ phức tạp hơn về việc nhóm điểm đánh dấu trong kho lưu trữ trên GitHub và đọc tài liệu tham khảo của thư viện.