Grupowanie znaczników

Wybierz platformę: Android iOS JavaScript

Ta strona zawiera opis narzędzia do grupowania znaczników, które jest dostępne w bibliotece narzędzi pakietu SDK Map na iOS.

Dzięki grupowaniu znaczników możesz umieścić na mapie dużą liczbę znaczników, co utrudnia ich czytanie. Narzędzie do grupowania znaczników pomaga zarządzać wieloma znacznikami przy różnych poziomach powiększenia.

Gdy użytkownik wyświetli mapę przy wysokim powiększeniu, pojawią się na niej pojedyncze znaczniki. Gdy użytkownik pomniejszy obszar, znaczniki zostaną połączone w klastry, aby ułatwić przeglądanie mapy.

Ten zrzut ekranu pokazuje domyślny styl klastrów znaczników:

Mapa ze skupionymi znacznikami w stylu domyślnym

Oto przykład niestandardowych klastrów znaczników:

Mapa z niestandardowymi znacznikami grupowymi

Wymagania wstępne i informacje

Maps SDK na iOS – biblioteka narzędzi

Narzędzie do grupowania znaczników jest częścią biblioteki narzędzi Maps SDK na iOS. Jeśli nie masz jeszcze skonfigurowanej biblioteki, zapoznaj się z przewodnikiem po konfiguracji, zanim przeczytasz pozostałą część tej strony.

Zalecana maksymalna liczba znaczników to 10 000.

Dostęp do lokalizacji

W tym przykładzie używamy GPS urządzenia, aby zlokalizować użytkownika oraz mapę na podstawie współrzędnych. Aby to zrobić, musisz dodać opis do uprawnienia NSLocationWhenInUseUsageDescription w pliku Info.plist projektu.

Aby to zrobić:

  1. Kliknij plik Info.plist w Nawigatorze projektów w Xcode, aby otworzyć edytor list usług.
  2. Aby dodać nową usługę, kliknij ikonę „'” obok pozycji „'Lista usług informacyjnych”.
  3. W polu 'key' wpisz 'NSLocationWhereInUseUsageDescription'. Xcode automatycznie przetłumaczy to hasło na długą nazwę &Prywatność – Lokalizacja podczas używania – opis. Pełną listę możliwych właściwości dostępu do lokalizacji znajdziesz w artykule o prośbie o autoryzację usług lokalizacyjnych w dokumentacji Apple dla deweloperów.
  4. W polu 'Type' pozostaw wartość 'ciąg'.
  5. W polu „Wartość” wpisz opis powodu, dla którego aplikacja wymaga użycia lokalizacji użytkownika. Na przykład "lokalizuje użytkownika, aby podać informacje o firmach w pobliżu."

Wdrażanie grupowania znaczników

Implementacja grupowania znaczników przebiega w 3 krokach:

  1. Utwórz instancję menedżera klastra.
  2. Prześlij znaczniki do klastra, które chcesz utworzyć w klastrze.
  3. Wywołanie menedżera klastra.
Aby zobaczyć pełny przykład implementacji implementacji znaczników, zapoznaj się z przykładowymi aplikacjami Swft w języku Objective-C i Swift na GitHubie.

Tworzę menedżera klastra

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

  1. Określ właściwość ViewController, w której jest renderowana Twoja mapa, aby była zgodna z protokołem GMSMapViewDelegate.
  2. Utwórz instancję GMUClusterManager.
  3. Przekaż instancję GMSMapView, w której chcesz zaimplementować klaster znaczników, i implementowanie tych protokołów w instancji GMUClusterManager:
    • GMUClusterIconGenerator: udostępnia logikę aplikacji, która pobiera ikony klastra do użycia na różnych poziomach powiększenia.
    • GMUClusterAlgorithm: określa algorytm określający sposób grupowania znaczników, np. odległość między znacznikami w tym samym klastrze.
    • GMUClusterRenderer: udostępnia logikę aplikacji, która obsługuje rzeczywiste renderowanie ikon klastrów na mapie.
  4. Ustaw przedstawiciela mapy w instancji GMUClusterManager.

Biblioteka narzędzi zawiera domyślne implementacje generatora ikon (GMUDefaultClusterIconGenerator), algorytmu (GMUNonHierarchicalDistanceBasedAlgorithm) i renderera (GMUDefaultClusterRenderer). Opcjonalnie możesz utworzyć własne niestandardowe narzędzie do generowania ikon współpracy i renderowania.

Ten kod tworzy menedżera klastrów z tymi wartościami domyślnymi w wywołaniu zwrotnym viewDidLoad funkcji 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: indywidualnie lub jako tablica.

Znacznik indywidualnych

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ływanie klastra znacznika

Po utworzeniu klastra znaczników i przekazaniu go, który chcesz zebrać, wystarczy wywołać metodę cluster w klastrze.

Swift

clusterManager.cluster()
      

Objective-C

[_clusterManager cluster];
      

Obsługuj zdarzenia na znacznikach i klastrach

Jeśli chcesz nasłuchiwać zdarzeń na mapie za pomocą pakietu SDK Map na iOS, musisz wdrożyć protokół GMSMapViewDelegate. Możesz nasłuchiwać zdarzeń mapowania, ale nie możesz nasłuchiwać zdarzeń menedżera klastra. Gdy użytkownik kliknie znacznik, pojedynczy element klastra lub klaster, interfejs API wywoła funkcję mapView:didTapMarker: i dołączy dodatkowe dane klastra do właściwości marker.userData. Następnie możesz sprawdzić, czy userData jest zgodny z protokołem GMUCluster, i zdecydować, czy została kliknięta ikona 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 klastrów przechwytuje teraz wszystkie zdarzenia zaimplementowane w clusterManager. Przekierowuje pozostałe zdarzenia, jeśli zostały podane. Pamiętaj, że zdarzenia standardowe znaczniki (czyli tagi, które nie są generowane przez mechanizm renderowania klastra) są zawsze przekazywane do przedstawiciela mapy.

Dostosuj klastry znaczników

Możesz podać niestandardową implementację GMUClusterRenderer, GMUClusterIconGenerator lub GMUClusterAlgorithm. Możesz wdrożyć implementację niestandardową, korzystając z przykładowej implementacji tych protokołów znajdujących się w bibliotece narzędzi, lub zakodować całkowicie niestandardową implementację przez wykonanie protokołów.