Markierungs-Clustering-Dienstprogramm in Google Maps Android

Mithilfe von Markierungs-Clustering kannst du eine große Anzahl Markierungen auf einer Karte einfügen, ohne die Lesbarkeit der Karte zu stark zu beeinträchtigen.

Einführung

In diesem Video wird gezeigt, wie du Markierungs-Clustering einsetzen kannst, wenn für deine Daten eine große Anzahl Datenpunkte auf der Karte erforderlich ist.

Das Markierungs-Clustering-Dienstprogramm unterstützt dich beim Verwalten von Markierungen bei verschiedenen Zoomstufen. Um genau zu sein, handelt es sich bei den „Markierungen“ an dieser Stelle eigentlich um „Elemente“, die erst beim Rendern zu Markierungen werden. Aus Gründen der Verständlichkeit wird in diesem Dokument jedoch durchgängig von Markierungen gesprochen.

Wenn ein Nutzer eine Karte mit einer großen Zoomstufe aufruft, werden die einzelnen Markierungen auf der Karte angezeigt. Beim Verkleinern der Ansicht werden die Markierungen zu Clustern zusammengefügt, um die Lesbarkeit der Karte zu verbessern. Das Markierungs-Clustering-Dienstprogramm ist Teil der Maps SDK for Android-Dienstprogrammbibliothek. Wenn du die Bibliothek noch nicht eingerichtet hast, folge der Anleitung im Einrichtungsleitfaden, bevor du den Rest dieser Seite liest.

Markierungs-Cluster auf einer Karte
Markierungs-Cluster

Um das Markierungs-Clustering-Dienstprogramm zu verwenden, musst du Markierungen als ClusterItem-Objekte zu ClusterManager hinzufügen. Der ClusterManager übergibt die Markierungen an den Algorithm, der sie in verschiedene Cluster umwandelt. Das Rendern erfolgt durch ClusterRenderer, indem Cluster und einzelne Markierungen hinzugefügt und entfernt werden. ClusterRenderer und Algorithm sind modular und können angepasst werden.

Die Dienstprogrammbibliothek wird mit einer Demo-App ausgeliefert, die Beispielimplementierungen für das Markierungs-Clustering-Dienstprogramm enthält. Informationen zum Ausführen der Demo-App findest du im Einrichtungsleitfaden. Die Demo-App enthält folgende Beispiele für das Markierungs-Clustering:

  • ClusteringDemoActivity: Eine einfache Aktivität zum Veranschaulichen des Markierungs-Clusterings
  • BigClusteringDemoActivity: Clustering mit 2.000 Markierungen
  • CustomMarkerClusteringDemoActivity: Erstellen eines benutzerdefinierten Designs für Cluster-Markierungen

Einfache Markierungs-Cluster hinzufügen

Führe die nachfolgenden Schritte aus, um einen einfachen Cluster mit zehn Markierungen zu erstellen. Das Ergebnis sieht so aus, wobei sich die Anzahl der dargestellten/geclusterten Markierungen abhängig von der Zoomstufe verändert:

Eine Karte mit zehn Markierungs-Cluster
Zehn Markierungs-Cluster

Hier sind die erforderlichen Schritte zusammengefasst:

  1. Implementiere ClusterItem, um eine Markierung auf der Karte darzustellen. Das Clusterelement gibt die Position der Markierung als LatLng-Objekt und optional einen Titel oder ein Snippet zurück.
  2. Füge einen neuen ClusterManager hinzu, um die Clusterelemente (Markierungen) basierend auf der Zoomstufe zu gruppieren.
  3. Du musst OnCameraIdleListener() der Karte auf ClusterManager festlegen, weil ClusterManager den Listener implementiert.
  4. Falls du bestimmte Funktionen angeben möchtest, die ausgeführt werden sollen, wenn eine Markierung angeklickt wird, musst du für den OnMarkerClickListener() der Karte den ClusterManager festlegen, weil ClusterManager den Listener implementiert.
  5. Füge die Markierungen in ClusterManager ein.

Hier sind die einzelnen Schritte im Detail beschrieben: Um einen einfachen Cluster bestehend aus zehn Markierungen zu erstellen, erstelle zuerst eine Klasse MyItem, mit der ClusterItem implementiert wird.

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

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
    }

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

Füge in deiner Kartenaktivität ClusterManager hinzu und übergebe die Clusterelemente. Das Typargument <MyItem> deklariert den Typ von ClusterManager als MyItem.

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);
    }
}
      

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)
    }
}
      

Du kannst die Clustering-Animationen auch beim Heran- und Herauszoomen deaktivieren. Wenn die Animation deaktiviert ist, bleiben die Markierungen an der Position, anstatt in und aus den Clustern zu migrieren. Verwende setAnimation() in ClusterManager, um Animationen zu deaktivieren, wie unten gezeigt:

Java

clusterManager.setAnimation(false);
      

Kotlin

clusterManager.setAnimation(false)
      

Infofenster für einen einzelnen Markierungs-Cluster hinzufügen

Wenn du ein Infofenster für bestimmte Markierungs-Cluster hinzufügen möchtest, füge dem Konstruktor deiner Implementierung von ClusterItem Titel und Snippet-Strings hinzu.

Im folgenden Beispiel wird eine Markierung mit einem Infofenster der Methode addItems() hinzugefügt, indem ein Titel und ein Snippet festgelegt werden:

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);
      

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)
      

Markierungs-Cluster anpassen

Der ClusterManager-Konstruktor erstellt einen DefaultClusterRenderer und einen NonHierarchicalDistanceBasedAlgorithm. Du kannst den ClusterRenderer und Algorithm mit den Methoden setAlgorithm(Algorithm<T> algorithm) und setRenderer(ClusterRenderer<T> view) von ClusterManager ändern.

Du kannst ClusterRenderer implementieren, um das Rendern der Cluster anzupassen. DefaultClusterRenderer bietet eine gute Basis für den Start. Wenn du DefaultClusterRenderer ableitest, kannst du die Standardwerte überschreiben.

Ein umfassendes und detailliertes Beispiel findest du in der Demo-App, die mit der Dienstprogrammbibliothek ausgeliefert wird, unter CustomMarkerClusteringDemoActivity.

Benutzerdefinierte Markierungs-Cluster auf einer Karte
Benutzerdefinierte Markierungs-Cluster

CustomMarkerClusteringDemoActivity definiert das eigene Clusterelement Person und rendert es, indem DefaultClusterRenderer als PersonRenderer erweitert wird.

Die Demo zeigt auch, wie die ClusterManager.OnClusterClickListener<Person>-Schnittstelle implementiert wird, um mehr Informationen über die Person anzuzeigen, wenn auf den Cluster geklickt wird. Auf ähnliche Weise kannst du auch ClusterManager.OnClusterItemClickListener<Person> implementieren.

Informationen zum Ausführen der Demo-App findest du im Einrichtungsleitfaden.