Utilità di clustering di Google Maps per Android

Seleziona piattaforma: Android iOS JavaScript

Grazie al raggruppamento degli indicatori, puoi posizionare un numero elevato di indicatori su una mappa senza renderla di difficile lettura.

Introduzione

Questo video illustra l'utilizzo del clustering degli indicatori quando i dati richiedono un numero elevato di punti dati sulla mappa.

L'utilità di clustering degli indicatori consente di gestire più indicatori con livelli di zoom diversi. Per essere precisi, gli 'indicatori' sono in realtà 'items' a questo punto, e diventano solo 'Markers' quando vengono visualizzati. Tuttavia, per maggiore chiarezza, questo documento chiamerà questi elementi 'indicatori' in tutto.

Quando un utente visualizza la mappa a un livello di zoom elevato, vengono visualizzati i singoli indicatori. Quando l'utente riduce lo zoom, gli indicatori vengono raccolti in cluster per semplificare la visualizzazione della mappa. L'utilità di clustering dell'indicatore fa parte della libreria di utilità di Maps per Android. Se non hai ancora configurato la libreria, segui la guida alla configurazione prima di leggere il resto di questa pagina.

Una mappa con indicatori in cluster
Indicatori con cluster

Per utilizzare l'utilità di cluster di indicatori, devi aggiungere gli indicatori come oggetti ClusterItem a ClusterManager. ClusterManager passa gli indicatori al Algorithm, che li trasforma in un set di cluster. ClusterRenderer si occupa del rendering aggiungendo e rimuovendo i cluster e i singoli indicatori. ClusterRenderer e Algorithm sono collegabili e possono essere personalizzati.

La libreria di utilità fornisce un'app demo che fornisce implementazioni di esempio dell'utilità di clustering degli indicatori. Per assistenza nell'esecuzione dell'app demo, consulta la guida alla configurazione. L'app demo include i seguenti esempi di clustering degli indicatori:

  • ClusteringDemoActivity: una semplice attività che mostra il clustering degli indicatori.
  • BigClusteringDemoActivity: clustering con 2000 indicatori.
  • CustomMarkerClusteringDemoActivity: creazione di un design personalizzato per gli indicatori in cluster.

Aggiungi un semplice cluster di indicatori

Per creare un semplice cluster di dieci indicatori, segui i passaggi riportati di seguito. Il risultato sarà simile a questo, anche se il numero di indicatori mostrati/in cluster cambierà a seconda del livello di zoom:

Una mappa con dieci indicatori in cluster
Dieci indicatori in cluster

Ecco un riepilogo dei passaggi richiesti:

  1. Implementa ClusterItem per rappresentare un indicatore sulla mappa. L'elemento del cluster restituisce la posizione dell'indicatore come oggetto LatLng e un titolo o snippet facoltativo.
  2. Aggiungi una nuova ClusterManager per raggruppare gli elementi del cluster (indicatori) in base al livello di zoom.
  3. Imposta OnCameraIdleListener() della mappa su ClusterManager, poiché ClusterManager implementa il listener.
  4. Se vuoi aggiungere funzionalità specifiche in risposta a un evento di clic sull'indicatore, imposta OnMarkerClickListener() per la mappa su ClusterManager, poiché ClusterManager implementa il listener.
  5. Inserisci gli indicatori in ClusterManager.

Esamina i passaggi in modo più dettagliato: per creare il nostro semplice cluster di dieci indicatori, crea prima una classe MyItem che implementa ClusterItem.

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

      

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

      

Nell'attività della mappa, aggiungi ClusterManager e specifica gli elementi nel cluster. Osserva l'argomento di tipo <MyItem>, che dichiara che ClusterManager è di tipo 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)
    }
}

      

Puoi anche scegliere di disattivare le animazioni di clustering quando aumenti e diminuisci lo zoom. Se l'animazione è disattivata, gli indicatori si posizionano invece di eseguire la migrazione all'interno e all'esterno dei cluster. Per disattivare le animazioni, usa setAnimation() in ClusterManager, come mostrato di seguito:

Java


clusterManager.setAnimation(false);

      

Kotlin


clusterManager.setAnimation(false)

      

Aggiungere una finestra informativa a un singolo indicatore in cluster

Per aggiungere una finestra informativa per specifici indicatori in cluster, aggiungi le stringhe title e snippet nel costruttore della tua implementazione di ClusterItem.

L'esempio seguente aggiunge un indicatore con una finestra informativa nel metodo addItems(), impostando un titolo e uno snippet:

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)

      

Personalizzare i cluster di indicatori

Il costruttore ClusterManager crea DefaultClusterRenderer e NonHierarchicalDistanceBasedAlgorithm. Puoi modificare ClusterRenderer e Algorithm utilizzando i metodi setAlgorithm(Algorithm<T> algorithm) e setRenderer(ClusterRenderer<T> view) di ClusterManager.

Puoi implementare ClusterRenderer per personalizzare il rendering dei cluster. DefaultClusterRenderer è un'ottima base di partenza. La sottoclasse DefaultClusterRenderer può sostituire le impostazioni predefinite.

Per un esempio dettagliato di personalizzazione, dai un'occhiata a CustomMarkerClusteringDemoActivity nell'app demo fornita con la libreria di utilità.

Una mappa con indicatori in cluster personalizzati
Indicatori personalizzati in cluster

CustomMarkerClusteringDemoActivity definisce il proprio elemento cluster, Person, e ne esegue il rendering estendendo DefaultClusterRenderer come PersonRenderer.

La demo mostra anche come implementare l'interfaccia ClusterManager.OnClusterClickListener<Person> per visualizzare ulteriori informazioni sull'utente quando fa clic sul cluster. Puoi anche implementare ClusterManager.OnClusterItemClickListener<Person> in modo simile.

Per assistenza nell'esecuzione dell'app demo, consulta la guida alla configurazione.