只要將標記叢集化,就算在地圖上放置大量標記,畫面也不會雜亂而難以瀏覽。
簡介
這部影片說明當資料需要用到地圖上的大量資料點時,如何運用標記叢集。
標記叢集公用程式可協助您管理多個縮放等級不同的標記。準確地說,「標記」在這個時候其實是「項目」,要等到算繪後才會變成「標記」。但為了方便說明,本文件會將這些項目都稱為「標記」。
當使用者以高縮放等級查看時,地圖上會顯示個別標記;而縮小地圖時,標記會聚類為多個叢集,方便使用者查看地圖。標記叢集公用程式包含在 Maps SDK for Android 公用程式庫。如果您尚未設定程式庫,請先按照設定指南的步驟完成設定,再閱讀本頁面的其他內容。

若要使用標記叢集公用程式,您必須將標記以 ClusterItem
物件的格式新增至 ClusterManager
。ClusterManager
會將標記傳遞至 Algorithm
,後者會將標記轉換為一組叢集。ClusterRenderer
會新增及移除叢集和個別標記,以完成算繪作業。ClusterRenderer
和 Algorithm
均可抽換及自訂。
公用程式庫隨附的試用版應用程式提供標記叢集公用程式的實作範例。如需執行試用版應用程式的相關說明,請參閱設定指南。試用版應用程式包含下列標記叢集範例:
ClusteringDemoActivity
:示範標記叢集的簡易活動。BigClusteringDemoActivity
:將 2,000 個標記聚類為叢集。CustomMarkerClusteringDemoActivity
:為叢集標記建立自訂設計。
新增簡易標記叢集
請按照下列步驟建立含 10 個標記的簡易叢集。成果看起來會像這樣,不過顯示的標記/叢集標記數量會隨縮放等級而變動:

以下摘要說明必要步驟:
- 導入
ClusterItem
來代表地圖上的標記。叢集項目會以 LatLng 物件形式傳回標記的位置,以及選用的標題或文字片段。 - 新增
ClusterManager
,根據縮放等級將叢集項目 (標記) 分組。 - 將地圖的
OnCameraIdleListener()
設為ClusterManager
,因為ClusterManager
會導入事件監聽器。 - 如要根據標記點擊事件新增特定功能,請將地圖的
OnMarkerClickListener()
設為ClusterManager
,因為ClusterManager
會導入事件監聽器。 - 為
ClusterManager
提供標記。
詳細步驟說明:如要建立含有 10 個標記的簡易叢集,請先建立會導入 ClusterItem
的 MyItem
類別。
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
}
}
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
類型。
// 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)
}
}
// 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()
,如下所示:
clusterManager.setAnimation(false)
clusterManager.setAnimation(false);
為個別叢集標記新增資訊視窗
如要新增特定叢集標記的資訊視窗,請在導入 ClusterItem
的建構函式中加入標題和文字片段字串。
下例顯示如何藉由設定標題和文字片段,在 addItems()
方法中新增包含資訊視窗的標記:
// 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)
// 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
建構函式會建立 DefaultClusterRenderer
和 NonHierarchicalDistanceBasedAlgorithm
。您可以使用 ClusterManager
的 setAlgorithm(Algorithm<T> algorithm)
和 setRenderer(ClusterRenderer<T> view)
方法來變更 ClusterRenderer
和 Algorithm
。
您可以導入 ClusterRenderer
來自訂叢集算繪。建議從 DefaultClusterRenderer
開始著手,將 DefaultClusterRenderer
設為子類別,就能覆寫預設值。
如想深入瞭解自訂範例,請查看隨附在公用程式庫試用版應用程式中的 CustomMarkerClusteringDemoActivity
。

CustomMarkerClusteringDemoActivity
可定義專屬的叢集項目 (Person
),並將 DefaultClusterRenderer
擴充為 PersonRenderer
以算繪該叢集項目。
此試用版也示範如何導入 ClusterManager.OnClusterClickListener<Person>
介面,以便在使用者點擊叢集時顯示相關的個人詳細資訊。此外,您也能透過類似的方式導入 ClusterManager.OnClusterItemClickListener<Person>
。
如需執行試用版應用程式的相關說明,請參閱設定指南。