Google 地圖 Android 標記叢集公用程式

選取平台: Android iOS JavaScript

只要將標記叢集化,就算在地圖上放置大量標記,畫面也不會雜亂而難以瀏覽。

簡介

這部影片說明當資料需要用到地圖上的大量資料點時,如何運用標記叢集。

標記叢集公用程式可協助您管理多個縮放等級不同的標記。準確地說,「標記」在這個時候其實是「項目」,要等到算繪後才會變成「標記」。但為了方便說明,本文件會將這些項目都稱為「標記」。

當使用者以高縮放等級查看時,地圖上會顯示個別標記;而縮小地圖時,標記會聚類為多個叢集,方便使用者查看地圖。標記叢集公用程式包含在 Maps SDK for Android 公用程式庫。如果您尚未設定程式庫,請先按照設定指南的步驟完成設定,再閱讀本頁面的其他內容。

含叢集標記的地圖
叢集標記

若要使用標記叢集公用程式,您必須將標記以 ClusterItem 物件的格式新增至 ClusterManagerClusterManager 會將標記傳遞至 Algorithm,後者會將標記轉換為一組叢集。ClusterRenderer 會新增及移除叢集和個別標記,以完成算繪作業。ClusterRendererAlgorithm 均可抽換及自訂。

公用程式庫隨附的試用版應用程式提供標記叢集公用程式的實作範例。如需執行試用版應用程式的相關說明,請參閱設定指南。試用版應用程式包含下列標記叢集範例:

  • ClusteringDemoActivity:示範標記叢集的簡易活動。
  • BigClusteringDemoActivity:將 2,000 個標記聚類為叢集。
  • CustomMarkerClusteringDemoActivity:為叢集標記建立自訂設計。

新增簡易標記叢集

請按照下列步驟建立含 10 個標記的簡易叢集。成果看起來會像這樣,不過顯示的標記/叢集標記數量會隨縮放等級而變動:

含 10 個叢集標記的地圖
10 個叢集標記

以下摘要說明必要步驟:

  1. 導入 ClusterItem 來代表地圖上的標記。叢集項目會以 LatLng 物件形式傳回標記的位置,以及選用的標題或文字片段。
  2. 新增 ClusterManager,根據縮放等級將叢集項目 (標記) 分組。
  3. 將地圖的 OnCameraIdleListener() 設為 ClusterManager,因為 ClusterManager 會導入事件監聽器。
  4. 如要根據標記點擊事件新增特定功能,請將地圖的 OnMarkerClickListener() 設為 ClusterManager,因為 ClusterManager 會導入事件監聽器。
  5. ClusterManager 提供標記。

詳細步驟說明:如要建立含有 10 個標記的簡易叢集,請先建立會導入 ClusterItemMyItem 類別。

Kotlin



inner class MyItem(
    lat: Double,
    lng: Double,
    title: String,
    snippet: String
) : ClusterItem {

    private val position: LatLng
    private val title: String
    private val snippet: String

    override fun getPosition(): LatLng {
        return position
    }

    override fun getTitle(): String {
        return title
    }

    override fun getSnippet(): String {
        return snippet
    }

    override fun getZIndex(): Float {
        return 0f
    }

    init {
        position = LatLng(lat, lng)
        this.title = title
        this.snippet = snippet
    }
}

      

Java


public class MyItem implements ClusterItem {
    private final LatLng position;
    private final String title;
    private final String snippet;

    public MyItem(double lat, double lng, String title, String snippet) {
        position = new LatLng(lat, lng);
        this.title = title;
        this.snippet = snippet;
    }

    @Override
    public LatLng getPosition() {
        return position;
    }

    @Override
    public String getTitle() {
        return title;
    }

    @Override
    public String getSnippet() {
        return snippet;
    }

    @Nullable
    @Override
    public Float getZIndex() {
        return 0f;
    }
}

      

在地圖活動中,新增 ClusterManager 並提供叢集項目。請注意,類型引數 <MyItem> 會將 ClusterManager 宣告為 MyItem 類型。

Kotlin



// Declare a variable for the cluster manager.
private lateinit var clusterManager: ClusterManager<MyItem>

private fun setUpClusterer() {
    // Position the map.
    map.moveCamera(CameraUpdateFactory.newLatLngZoom(LatLng(51.503186, -0.126446), 10f))

    // Initialize the manager with the context and the map.
    // (Activity extends context, so we can pass 'this' in the constructor.)
    clusterManager = ClusterManager(context, map)

    // Point the map's listeners at the listeners implemented by the cluster
    // manager.
    map.setOnCameraIdleListener(clusterManager)
    map.setOnMarkerClickListener(clusterManager)

    // Add cluster items (markers) to the cluster manager.
    addItems()
}

private fun addItems() {

    // Set some lat/lng coordinates to start with.
    var lat = 51.5145160
    var lng = -0.1270060

    // Add ten cluster items in close proximity, for purposes of this example.
    for (i in 0..9) {
        val offset = i / 60.0
        lat += offset
        lng += offset
        val offsetItem =
            MyItem(lat, lng, "Title $i", "Snippet $i")
        clusterManager.addItem(offsetItem)
    }
}

      

Java


// Declare a variable for the cluster manager.
private ClusterManager<MyItem> clusterManager;

private void setUpClusterer() {
    // Position the map.
    map.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(51.503186, -0.126446), 10));

    // Initialize the manager with the context and the map.
    // (Activity extends context, so we can pass 'this' in the constructor.)
    clusterManager = new ClusterManager<MyItem>(context, map);

    // Point the map's listeners at the listeners implemented by the cluster
    // manager.
    map.setOnCameraIdleListener(clusterManager);
    map.setOnMarkerClickListener(clusterManager);

    // Add cluster items (markers) to the cluster manager.
    addItems();
}

private void addItems() {

    // Set some lat/lng coordinates to start with.
    double lat = 51.5145160;
    double lng = -0.1270060;

    // Add ten cluster items in close proximity, for purposes of this example.
    for (int i = 0; i < 10; i++) {
        double offset = i / 60d;
        lat = lat + offset;
        lng = lng + offset;
        MyItem offsetItem = new MyItem(lat, lng, "Title " + i, "Snippet " + i);
        clusterManager.addItem(offsetItem);
    }
}

      

您也可以選擇停用放大及縮小時的叢集動畫。如果關閉動畫,標記會貼齊固定位置,而不會移入或移出叢集。如要停用動畫,請在 ClusterManager 中使用 setAnimation(),如下所示:

Kotlin



clusterManager.setAnimation(false)

      

Java


clusterManager.setAnimation(false);

      

為個別叢集標記新增資訊視窗

如要新增特定叢集標記的資訊視窗,請在導入 ClusterItem 的建構函式中加入標題和文字片段字串。

下例顯示如何藉由設定標題和文字片段,在 addItems() 方法中新增包含資訊視窗的標記:

Kotlin



// Set the lat/long coordinates for the marker.
val lat = 51.5009
val lng = -0.122

// Set the title and snippet strings.
val title = "This is the title"
val snippet = "and this is the snippet."

// Create a cluster item for the marker and set the title and snippet using the constructor.
val infoWindowItem = MyItem(lat, lng, title, snippet)

// Add the cluster item (marker) to the cluster manager.
clusterManager.addItem(infoWindowItem)

      

Java


// Set the lat/long coordinates for the marker.
double lat = 51.5009;
double lng = -0.122;

// Set the title and snippet strings.
String title = "This is the title";
String snippet = "and this is the snippet.";

// Create a cluster item for the marker and set the title and snippet using the constructor.
MyItem infoWindowItem = new MyItem(lat, lng, title, snippet);

// Add the cluster item (marker) to the cluster manager.
clusterManager.addItem(infoWindowItem);

      

自訂標記叢集

ClusterManager 建構函式會建立 DefaultClusterRendererNonHierarchicalDistanceBasedAlgorithm。您可以使用 ClusterManagersetAlgorithm(Algorithm<T> algorithm)setRenderer(ClusterRenderer<T> view) 方法來變更 ClusterRendererAlgorithm

您可以導入 ClusterRenderer 來自訂叢集算繪。建議從 DefaultClusterRenderer 開始著手,將 DefaultClusterRenderer 設為子類別,就能覆寫預設值。

如想深入瞭解自訂範例,請查看隨附在公用程式庫試用版應用程式中的 CustomMarkerClusteringDemoActivity

含自訂叢集標記的地圖
自訂叢集標記

CustomMarkerClusteringDemoActivity 可定義專屬的叢集項目 (Person),並將 DefaultClusterRenderer 擴充為 PersonRenderer 以算繪該叢集項目。

此試用版也示範如何導入 ClusterManager.OnClusterClickListener<Person> 介面,以便在使用者點擊叢集時顯示相關的個人詳細資訊。此外,您也能透過類似的方式導入 ClusterManager.OnClusterItemClickListener<Person>

如需執行試用版應用程式的相關說明,請參閱設定指南