Grupowanie znaczników

Wybierz platformę: Android iOS JavaScript

Na tej stronie opisano narzędzie do grupowania znaczników dostępne w biblioteka narzędzi w przypadku pakietu Maps SDK na iOS.

Pogrupując znaczniki, możesz umieścić na mapie dużą ich liczbę dzięki czemu mapa jest nieczytelna. Narzędzie do grupowania znaczników pomaga zarządzać wieloma znacznikami na różnych poziomach powiększenia.

Gdy użytkownik wyświetla mapę w dużym powiększeniu, wskazują na mapie. Gdy użytkownik oddala mapę, znaczniki zbierają się połączone w klastry, aby ułatwić przeglądanie mapy.

Poniższy zrzut ekranu przedstawia domyślny styl klastrów znaczników:

Mapa ze znacznikami zgrupowanymi w stylu domyślnym

Poniżej znajduje się przykład niestandardowych klastrów znaczników:

Mapa z niestandardowymi znacznikami klastrowymi

Wymagania wstępne i uwagi

Biblioteka narzędziowych pakietu Maps SDK na iOS

Narzędzie do grupowania znaczników jest częścią Maps SDK na iOS Biblioteka narzędziowa. Jeśli nie masz jeszcze skonfigurowanej biblioteki, postępuj zgodnie z przewodnikiem konfiguracji przed przeczytaniem reszty tej strony.

Aby uzyskać najlepszą wydajność, zalecana maksymalna liczba znaczników to 10 000.

Dostęp do lokalizacji

W tym przykładzie używamy GPS-a urządzenia do lokalizowania użytkownika i mapy na jego współrzędnych. Aby włączyć to, musisz dodać opis do uprawnienia NSLocationWhenInUseUsageDescription w pliku Info.plist projektu.

Aby go dodać, wykonaj te czynności:

  1. Kliknij plik Info.plist w narzędziu Project Navigator w Xcode, aby otworzyć Edytor listy właściwości.
  2. Kliknij przycisk „+”, ikona obok pozycji „Lista właściwości informacji” aby dodać nową usługę.
  3. W kluczu wpisz „NSLocationAfterInUseUsageDescription”. Xcode automatycznie Przetłumacz to na długą nazwę „Privacy - Location With In Use Opis”. Dla pełną listę możliwych właściwości dostępu do lokalizacji, zobacz Prośba o autoryzację usług lokalizacyjnych znajdziesz w dokumentacji Apple dla deweloperów.
  4. Pozostaw pole „Typ”. ustawiona na „Ciąg”.
  5. W polu „Wartość” wpisz opis powodu, dla którego aplikacja wymaga użycia atrybutu lokalizację użytkownika. Na przykład „Znajduje użytkownika, który może podać informacje o firmach w pobliżu”.

Wdrażanie grupowania znaczników

Implementacja grupowania znaczników obejmuje 3 kroki:

  1. Utwórz instancję menedżera klastrów.
  2. Przekaż znaczniki, które chcesz połączyć w grupie, do menedżera klastrów.
  3. Wywołaj menedżera klastra.
. Pełny przykład implementacji grupowania znaczników znajdziesz w przykładowych aplikacjach Objective-C i Swift na GitHubie.

Tworzę menedżera klastrów

Aby użyć menedżera klastrów, wykonaj te czynności:

  1. Ustaw ViewController, w którym jest renderowana mapa, tak aby była zgodna z Protokół GMSMapViewDelegate.
  2. Utwórz instancję GMUClusterManager.
  3. Przekaż instancję GMSMapView, w której chcesz wdrożyć grupowanie znaczników w następujących protokołach i implementacjach w instancji GMUClusterManager:
    • GMUClusterIconGenerator: udostępnia logikę aplikacji, która pobiera i ikony klastrów używane przy różnych poziomach powiększenia.
    • GMUClusterAlgorithm: określa algorytm określający działanie. sposobu grupowania znaczników, na przykład odległości między znacznikami, które mają być uwzględnione w tej samej grupie.
    • GMUClusterRenderer: udostępnia logikę aplikacji, która obsługuje rzeczywiste i renderowanie ikon klastrów na mapie.
  4. Ustaw przedstawiciela do mapy w instancji GMUClusterManager.

Biblioteka narzędzi zawiera domyślne implementacje generatora ikon (GMUDefaultClusterIconGenerator), algorytm (GMUNonHierarchicalDistanceBasedAlgorithm) i mechanizm renderowania (GMUDefaultClusterRenderer). Opcjonalnie możesz utworzyć własny, niestandardowy mechanizm generowania ikon, algorytm i mechanizm renderowania.

Ten kod tworzy menedżera klastra z użyciem tych wartości domyślnych w: viewDidLoad wywołanie zwrotne 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
      

Dodawanie znaczników

Istnieją 2 sposoby dodawania znaczników do klastra znaczników: pojedynczo lub w postaci tablicy.

Indywidualny znacznik

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

Tablica znaczników

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

Wywołuję klaster znaczników

Po utworzeniu klastra znaczników i przekazaniu mu znaczników, które chcesz grupować, musisz wywołać metodę cluster w instancji klastra znaczników.

Swift

clusterManager.cluster()
      

Objective-C

[_clusterManager cluster];
      

Obsługuj zdarzenia w znacznikach i klastrach

Ogólnie rzecz biorąc, jeśli używasz Maps SDK na iOS, aby nasłuchiwać zdarzeń na mapie, musisz zaimplementować GMSMapViewDelegate protokołu. Możesz posłuchać: mapować zdarzenia, ale nie możesz nasłuchują zdarzeń menedżera klastra bezpiecznego typu. Gdy użytkownik kliknie znacznik, pojedynczego elementu klastra lub klastra, to za pomocą interfejsu API mapView:didTapMarker: i dołącza dodatkowe dane klastra do marker.userData. Następnie możesz sprawdzić, czy userData jest zgodny z protokołu GMUCluster w celu określenia, czy kliknięto ikonę klastra lub znacznik.

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

Menedżer klastra przechwytuje teraz wszystkie zdarzenia zaimplementowane w interfejsie clusterManager Przekazuje ono wszystkie pozostałe zdarzenia na mapę na przedstawiciela, jeśli został podany. Pamiętaj, że zdarzenia w przypadku znaczników standardowych (czyli znaczniki, które nie są generowane przez mechanizm renderowania klastra) są zawsze przekazywane przedstawicielowi mapy.

Dostosuj grupowanie znaczników

Możesz użyć niestandardowej implementacji GMUClusterRenderer, GMUClusterIconGenerator lub GMUClusterAlgorithm Możesz oprzeć swoją implementację niestandardową na przykładowej implementacji tych protokołów w narzędziu lub kod w pełni niestandardową implementację, realizując protokoły API.