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.
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:
Veja a seguir um resumo das etapas necessárias:
- 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. - Adicione um novo
ClusterManager
para agrupar os itens de cluster (marcadores) de acordo com o nível de zoom. - Defina o
OnCameraIdleListener()
do mapa comoClusterManager
, já queClusterManager
implementa o listener. - Se você quiser adicionar uma funcionalidade específica em resposta a um evento de clique de marcador, defina o
OnMarkerClickListener()
do mapa comoClusterManager
, já queClusterManager
implementa o listener. - 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
.
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; } }
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
.
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); } }
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:
Kotlin
clusterManager.setAnimation(false)
Java
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:
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);
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.
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.