Utilitário de clustering de marcadores do Google Maps para Android

Selecione a plataforma: Android iOS JavaScript

Com o clustering de marcadores, você pode colocar um grande número de marcadores em um mapa sem dificultar a leitura.

Introdução

Este vídeo discute o uso de clustering de marcadores como uma alternativa aos marcadores quando os dados exigem um grande número de pontos de dados no mapa.

O utilitário de clustering de marcadores ajuda a gerenciar vários marcadores em diferentes níveis de zoom. Na verdade, os "marcadores" são "itens" por enquanto e só se tornam "marcadores" quando são renderizados. No entanto, para maior clareza, este documento vai usar sempre o termo "marcadores".

Quando um usuário vê um mapa com bastante zoom, os marcadores individuais aparecem no mapa. Quando o usuário diminui o zoom, os marcadores se reúnem em clusters, facilitando a visualização. O utilitário de clustering de marcadores faz parte da Biblioteca de utilitários do SDK do Maps para Android. Se você ainda não configurou a biblioteca, siga o guia antes de ler o restante desta página.

Mapa com marcadores em cluster
Marcadores em cluster

Para usar o utilitário de clustering de marcadores, é necessário adicionar os marcadores como objetos ClusterItem ao ClusterManager. ClusterManager transmite os marcadores para Algorithm, que os transforma em um conjunto de clusters. ClusterRenderer é responsável pela renderização, adicionando e removendo clusters e marcadores individuais. ClusterRenderer e Algorithm são conectáveis e podem ser personalizados.

A biblioteca de utilitários é fornecida com um app de demonstração, que oferece implementações de exemplo do utilitário de clustering de marcadores. Para receber ajuda com a execução do app de demonstração, consulte o guia de configuração. O app de demonstração inclui os seguintes exemplos de clustering de marcadores:

  • ClusteringDemoActivity: uma atividade simples demonstrando o clustering de marcadores.
  • BigClusteringDemoActivity: clustering com 2.000 marcadores.
  • CustomMarkerClusteringDemoActivity: criação de um projeto personalizado para marcadores em cluster.

Adicionar um clusterer de marcadores simples

Siga estas etapas para criar um cluster simples de dez marcadores. O resultado será semelhante ao mostrado a seguir, embora o número de marcadores mostrados/em cluster mude em função do nível de zoom:

Mapa com 10 marcadores em cluster
Dez marcadores em cluster

Veja a seguir um resumo das etapas necessárias:

  1. Implemente ClusterItem para representar um marcador no mapa. O item de cluster retorna a posição do marcador como um objeto LatLng e um título ou snippet opcional.
  2. Adicione um novo ClusterManager para agrupar os itens de cluster (marcadores) de acordo com o nível de zoom.
  3. Defina o OnCameraIdleListener() do mapa como ClusterManager, já que ClusterManager implementa o listener.
  4. Se você quiser adicionar uma funcionalidade específica em resposta a um evento de clique de marcador, defina o OnMarkerClickListener() do mapa como ClusterManager, já que ClusterManager implementa o listener.
  5. Alimente os marcadores no ClusterManager.

Mais detalhes das etapas: para criar nosso cluster simples com 10 marcadores, primeiro crie uma classe MyItem que implemente ClusterItem.



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

     

Na atividade do mapa, adicione ClusterManager e alimente os itens do cluster. Observe o argumento de tipo <MyItem>, que declara ClusterManager como sendo do tipo 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);
   
}
}

     

Também é possível desativar as animações de clustering ao aumentar e diminuir o zoom. Se a animação estiver desativada, os marcadores serão colocados em uma posição, em vez de migrar dos clusters. Para desativar as animações, use setAnimation() em ClusterManager, como abaixo:



clusterManager
.setAnimation(false)

     

clusterManager
.setAnimation(false);

     

Adicionar uma janela de informações para um marcador em cluster individual

Para adicionar uma janela de informações a marcadores em cluster específicos, inclua strings de título e snippet ao construtor da implementação de ClusterItem.

O exemplo a seguir adiciona um marcador com uma janela de informações no método addItems(), definindo um título e snippet:



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

     

Personalizar os clusters de marcadores

O construtor ClusterManager cria um DefaultClusterRenderer e um NonHierarchicalDistanceBasedAlgorithm. É possível alterar o ClusterRenderer e o Algorithm usando os métodos setAlgorithm(Algorithm<T> algorithm) e setRenderer(ClusterRenderer<T> view) de ClusterManager.

Você pode implementar ClusterRenderer para personalizar a renderização dos clusters. DefaultClusterRenderer fornece uma boa base para começar. Quando a subclasse é DefaultClusterRenderer, é possível modificar os padrões.

Para ver um exemplo detalhado de personalização, consulte CustomMarkerClusteringDemoActivity no app de demonstração que acompanha a biblioteca de utilitários.

Mapa com marcadores em cluster personalizados
Marcadores em cluster personalizados

CustomMarkerClusteringDemoActivity define o próprio item de cluster, um Person, e o renderiza ao estender DefaultClusterRenderer como PersonRenderer.

A demonstração também mostra como implementar a interface ClusterManager.OnClusterClickListener<Person> para exibir mais informações sobre a pessoa quando o cluster é clicado. Também é possível implementar ClusterManager.OnClusterItemClickListener<Person> de maneira semelhante.

Para receber ajuda com a execução do app de demonstração, consulte o guia de configuração.