Nhóm điểm đánh dấu

Chọn nền tảng: Android iOS JavaScript

Tổng quan

Hướng dẫn này trình bày cách sử dụng phân cụm điểm đánh dấu để hiển thị một số lượng lớn điểm đánh dấu trên bản đồ. Bạn có thể sử dụng thư viện @googlemaps/markerclusterer kết hợp với API JavaScript của Maps để kết hợp các điểm đánh dấu ở gần nhau thành các cụm và đơn giản hoá việc hiển thị các điểm đánh dấu trên bản đồ.

Để xem cách hoạt động của tính năng phân cụm điểm đánh dấu, 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 trong cụm đó. Lưu ý rằng khi bạn phóng to bất kỳ vị trí cụm nào, số trên cụm sẽ giảm và bạn bắt đầu thấy từng điểm đánh dấu trên bản đồ. Khi bạn thu nhỏ bản đồ, các điểm đánh dấu sẽ hợp nhất thành các cụm.

Mã mẫu dưới đây cho thấy toàn bộ mã bạn cần để tạo bản đồ này.

TypeScript

import { MarkerClusterer } from '@googlemaps/markerclusterer';

async function init() {
    // Request needed libraries.
    const [{ InfoWindow }, { AdvancedMarkerElement, PinElement }] =
        await Promise.all([
            google.maps.importLibrary('maps'),
            google.maps.importLibrary('marker'),
        ]);

    const mapElement =
        document.querySelector<google.maps.MapElement>('gmp-map')!;
    const innerMap = mapElement.innerMap;

    const infoWindow = new 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 PinElement({
            glyphText: label,
            glyphColor: 'white',
        });

        const marker = new AdvancedMarkerElement({
            position,
            content: pinGlyph,
            gmpClickable: true,
        });

        // markers can only be keyboard focusable when they have click listeners
        // open info window when marker is clicked
        marker.addEventListener('gmp-click', () => {
            const content = document.createElement('div');
            content.textContent = `${String(position.lat)}, ${String(position.lng)}`;
            infoWindow.setContent(content);

            infoWindow.open({
                anchor: marker,
                map: innerMap,
            });
        });
        return marker;
    });

    // Add a marker clusterer to manage the markers.
    new MarkerClusterer({ markers, map: innerMap });
}

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 },
];

void init();

JavaScript

import { MarkerClusterer } from '@googlemaps/markerclusterer';

async function init() {
    // Request needed libraries.
    const [{ InfoWindow }, { AdvancedMarkerElement, PinElement }] =
        await Promise.all([
            google.maps.importLibrary('maps'),
            google.maps.importLibrary('marker'),
        ]);

    const mapElement = document.querySelector('gmp-map');
    const innerMap = mapElement.innerMap;

    const infoWindow = new 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 PinElement({
            glyphText: label,
            glyphColor: 'white',
        });

        const marker = new AdvancedMarkerElement({
            position,
            content: pinGlyph,
            gmpClickable: true,
        });

        // markers can only be keyboard focusable when they have click listeners
        // open info window when marker is clicked
        marker.addEventListener('gmp-click', () => {
            const content = document.createElement('div');
            content.textContent = `${String(position.lat)}, ${String(position.lng)}`;
            infoWindow.setContent(content);

            infoWindow.open({
                anchor: marker,
                map: innerMap,
            });
        });
        return marker;
    });

    // Add a marker clusterer to manage the markers.
    new MarkerClusterer({ markers, map: innerMap });
}

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 },
];

void init();

CSS

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>
        <script>
            // prettier-ignore
            (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: "GOOGLE_MAPS_API_KEY",
            });
        </script>
    </head>
    <body>
        <gmp-map
            center="-28.024,140.887"
            zoom="3"
            map-id="DEMO_MAP_ID"></gmp-map>
    </body>
</html>

Để minh hoạ, hướng dẫn này sẽ thêm một nhóm đ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 một phân cụm điểm đánh dấu

Làm theo các bước dưới đây để thêm trình phân cụm điểm đánh dấu:

  1. Thêm thư viện phân cụm điểm đánh dấu vào trang hoặc ứng dụng của bạn. Thư viện này có trên NPM tại @googlemaps/markerclusterer và trong kho lưu trữ trên GitHub.

    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

    Tập lệnh bên dưới tải phiên bản 2.x.x mới nhất của thư viện từ CDN unpkg.com.

    <script src="https://unpkg.com/@googlemaps/markerclusterer/dist/index.min.js"></script>
  2. Thêm một trình phân cụm điểm đánh dấu vào ứng dụng của bạn.

    Đoạn mã dưới đây thêm một trình phân cụm điểm đánh dấu vào bản đồ.

    NPM

    import { MarkerClusterer } from "@googlemaps/markerclusterer";
    
    const markerCluster = new MarkerClusterer({ markers, map });

    CDN

    Khi được truy cập bằng CDN, thư viện sẽ có sẵn trong markerClusterer toàn cầu.

    const markerCluster = new markerClusterer.MarkerClusterer({ markers, map });

    Mẫu này truyền mảng markers đến MarkerClusterer.

  3. Tuỳ chỉnh trình phân cụm điểm đánh dấu.

Tìm hiểu thêm

Bạn có thể xem các ví dụ phức tạp hơn về tính năng nhóm điểm đánh dấu trong kho lưu trữ trên GitHub và đọc tài liệu tham khảo cho thư viện.