Esta página descreve o utilitário de clustering de marcadores disponível na biblioteca de utilitários do SDK do Maps para iOS.
Com o clustering de marcadores, você pode colocar um grande número de marcadores em um mapa sem dificultar a leitura. O utilitário de clustering de marcadores ajuda a gerenciar vários marcadores em diferentes níveis de zoom.
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.
A captura de tela a seguir mostra o estilo padrão dos clusters de marcadores:
Abaixo está um exemplo de clusters de marcadores personalizados:
Pré-requisitos e observações
Biblioteca de utilitários do SDK do Maps para iOS
O utilitário de clustering de marcadores faz parte da Biblioteca de utilitários do SDK do Maps para iOS. Se você ainda não configurou a biblioteca, siga o guia antes de ler o restante desta página.
Para obter o melhor desempenho, o número máximo recomendado de marcadores é 10.000.
Permissão de localização
Este exemplo usa o GPS do dispositivo para localizar o usuário e o mapa nas coordenadas dele. Para ativar
isso, adicione uma descrição à permissão NSLocationWhenInUseUsageDescription
no arquivo Info.plist do projeto.
Para adicionar isso, faça o seguinte:
- Clique no arquivo
Info.plistno navegador de projetos do Xcode para abrir o Editor de lista de propriedades. - Clique no ícone "+" ao lado de "Lista de propriedades de informações" para adicionar uma propriedade.
- No campo "key", digite "NSLocationWhenInUseUsageDescription". O Xcode vai traduzir automaticamente isso para o nome longo "Privacy - Location When In Use Usage Description". Para uma lista completa de propriedades possíveis de permissão de localização, consulte Solicitar autorização para Serviços de localização na documentação para desenvolvedores da Apple.
- Deixe o campo "Tipo" definido como "String".
- No campo "Valor", digite uma descrição do motivo pelo qual o app precisa usar a localização do usuário. Por exemplo, "Localiza o usuário para fornecer informações de empresas próximas".
Implementar o clustering de marcadores
A implementação do clustering de marcadores é feita em três etapas:
- Crie uma instância do gerenciador de cluster.
- Transmita os marcadores que você quer agrupar ao gerenciador de clusters.
- Invocar o gerenciador de clusters.
Como criar o gerenciador de clusters
Para usar o gerenciador de clusters, faça o seguinte:
- Defina o
ViewControllerem que o mapa é renderizado para obedecer ao protocoloGMSMapViewDelegate. - Crie uma instância de
GMUClusterManager. - Transmita a instância de
GMSMapViewem que você quer implementar o clustering de marcadores e as implementações dos seguintes protocolos para a instânciaGMUClusterManager:GMUClusterIconGenerator: fornece lógica de aplicativo que busca os ícones de cluster a serem usados em diferentes níveis de zoom.GMUClusterAlgorithm: especifica um algoritmo que determina o comportamento do cluster, como a distância entre os marcadores que serão incluídos.GMUClusterRenderer: fornece a lógica do aplicativo que processa a renderização real dos ícones de cluster no mapa.
- Defina o delegado do mapa na instância
GMUClusterManager.
A biblioteca de utilitários inclui implementações padrão do gerador de ícones (GMUDefaultClusterIconGenerator),
algoritmo (GMUNonHierarchicalDistanceBasedAlgorithm) e renderizador (GMUDefaultClusterRenderer).
Você também pode criar seu próprio gerador de ícones, algoritmo e renderizador de clustering personalizados.
O código a seguir cria um gerenciador de clusters usando esses padrões no callback viewDidLoad
de ViewController:
Swift
import GoogleMaps import GoogleMapsUtils class MarkerClustering: UIViewController, GMSMapViewDelegate { private var mapView: GMSMapView! private var clusterManager: GMUClusterManager! override func viewDidLoad() { super.viewDidLoad() // Set up the cluster manager with the supplied icon generator and // renderer. let iconGenerator = GMUDefaultClusterIconGenerator() let algorithm = GMUNonHierarchicalDistanceBasedAlgorithm() let renderer = GMUDefaultClusterRenderer(mapView: mapView, clusterIconGenerator: iconGenerator) clusterManager = GMUClusterManager(map: mapView, algorithm: algorithm, renderer: renderer) // Register self to listen to GMSMapViewDelegate events. clusterManager.setMapDelegate(self) // ... } // ... }
Objective-C
@import GoogleMaps; @import GoogleMapsUtils; @interface MarkerClustering () <GMSMapViewDelegate> @end @implementation MarkerClustering { GMSMapView *_mapView; GMUClusterManager *_clusterManager; } - (void)viewDidLoad { [super viewDidLoad]; // Set up the cluster manager with a supplied icon generator and renderer. id<GMUClusterAlgorithm> algorithm = [[GMUNonHierarchicalDistanceBasedAlgorithm alloc] init]; id<GMUClusterIconGenerator> iconGenerator = [[GMUDefaultClusterIconGenerator alloc] init]; id<GMUClusterRenderer> renderer = [[GMUDefaultClusterRenderer alloc] initWithMapView:_mapView clusterIconGenerator:iconGenerator]; _clusterManager = [[GMUClusterManager alloc] initWithMap:_mapView algorithm:algorithm renderer:renderer]; // Register self to listen to GMSMapViewDelegate events. [_clusterManager setMapDelegate:self]; // ... } // ... @end
Adicionar marcadores
Há duas maneiras de adicionar marcadores ao cluster de marcadores: individualmente ou como uma matriz.
Marcador individual
Swift
let position = CLLocationCoordinate2D(latitude: 47.60, longitude: -122.33) let marker = GMSMarker(position: position) clusterManager.add(marker)
Objective-C
CLLocationCoordinate2D position = CLLocationCoordinate2DMake(47.60, -122.33); GMSMarker *marker = [GMSMarker markerWithPosition:position]; [_clusterManager addItem:marker];
Matriz de marcadores
Swift
let position1 = CLLocationCoordinate2D(latitude: 47.60, longitude: -122.33) let marker1 = GMSMarker(position: position1) let position2 = CLLocationCoordinate2D(latitude: 47.60, longitude: -122.46) let marker2 = GMSMarker(position: position2) let position3 = CLLocationCoordinate2D(latitude: 47.30, longitude: -122.46) let marker3 = GMSMarker(position: position3) let position4 = CLLocationCoordinate2D(latitude: 47.20, longitude: -122.23) let marker4 = GMSMarker(position: position4) let markerArray = [marker1, marker2, marker3, marker4] clusterManager.add(markerArray)
Objective-C
CLLocationCoordinate2D position1 = CLLocationCoordinate2DMake(47.60, -122.33); GMSMarker *marker1 = [GMSMarker markerWithPosition:position1]; CLLocationCoordinate2D position2 = CLLocationCoordinate2DMake(47.60, -122.46); GMSMarker *marker2 = [GMSMarker markerWithPosition:position2]; CLLocationCoordinate2D position3 = CLLocationCoordinate2DMake(47.30, -122.46); GMSMarker *marker3 = [GMSMarker markerWithPosition:position3]; CLLocationCoordinate2D position4 = CLLocationCoordinate2DMake(47.20, -122.23); GMSMarker *marker4 = [GMSMarker markerWithPosition:position4]; NSArray<GMSMarker *> *markerArray = @[marker1, marker2, marker3, marker4]; [_clusterManager addItems:markerArray];
Como invocar o clusterer de marcadores
Depois de criar o clustering de marcadores e transmitir os marcadores que você quer agrupar, basta chamar o método cluster na instância do clustering de marcadores.
Swift
clusterManager.cluster()
Objective-C
[_clusterManager cluster];
Tratamento de eventos em marcadores e grupos
Em geral, ao usar o SDK do Maps para iOS, para ouvir eventos no mapa, é necessário implementar o protocolo GMSMapViewDelegate. É possível ouvir eventos de mapa, mas não os eventos do gerenciador de clusters com segurança de tipos. Quando o usuário toca em um marcador, um item de cluster individual ou um cluster, a API aciona mapView:didTapMarker: e anexa os dados extras do cluster à propriedade marker.userData. Em seguida, é possível verificar se userData está em conformidade com o protocolo GMUCluster para determinar se um ícone de cluster ou um marcador foi tocado.
Swift
func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool { // center the map on tapped marker mapView.animate(toLocation: marker.position) // check if a cluster icon was tapped if marker.userData is GMUCluster { // zoom in on tapped cluster mapView.animate(toZoom: mapView.camera.zoom + 1) NSLog("Did tap cluster") return true } NSLog("Did tap a normal marker") return false }
Objective-C
- (BOOL)mapView:(GMSMapView *)mapView didTapMarker:(GMSMarker *)marker { // center the map on tapped marker [_mapView animateToLocation:marker.position]; // check if a cluster icon was tapped if ([marker.userData conformsToProtocol:@protocol(GMUCluster)]) { // zoom in on tapped cluster [_mapView animateToZoom:_mapView.camera.zoom + 1]; NSLog(@"Did tap cluster"); return YES; } NSLog(@"Did tap marker in cluster"); return NO; }
O gerenciador de clusters agora intercepta todos os eventos implementados em clusterManager e encaminha os eventos restantes para o delegado do mapa, se fornecido. Os eventos de marcadores padrão (ou seja, marcadores não gerados pelo renderizador de cluster) são sempre encaminhados para o delegado do mapa.
Personalizar o clustering de marcadores
Você pode fornecer uma implementação personalizada para GMUClusterRenderer, GMUClusterIconGenerator ou GMUClusterAlgorithm. É possível basear sua implementação personalizada na implementação de amostra desses protocolos incluída na biblioteca de utilitários ou codificar uma implementação totalmente personalizada seguindo os protocolos.