Na tej stronie opisujemy narzędzie do grupowania znaczników, które jest dostępne w bibliotece narzędzi pakietu Maps SDK na iOS.
Dzięki grupowaniu znaczników możesz umieścić na mapie dużą liczbę znaczników, nie powodując, że mapa będzie czytelna. Narzędzie do grupowania znaczników ułatwia zarządzanie wieloma znacznikami na różnych poziomach powiększenia.
Gdy użytkownik wyświetla mapę w dużym powiększeniu, poszczególne znaczniki są widoczne na mapie. Gdy użytkownik pomniejsza mapę, znaczniki zbierają się w klastry, aby ułatwić przeglądanie mapy.
Zrzut ekranu poniżej pokazuje domyślny styl klastrów znaczników:
Poniżej znajdziesz przykład niestandardowych klastrów znaczników:
Wymagania wstępne i uwagi
Biblioteka narzędziowa pakietu Maps SDK na iOS
Narzędzie do grupowania znaczników jest częścią biblioteki narzędziowej pakietu Maps SDK na iOS. Jeśli nie masz jeszcze skonfigurowanej biblioteki, zapoznaj się z pozostałą częścią tej strony, postępując zgodnie z przewodnikiem po konfiguracji.
Aby uzyskać najlepszą skuteczność, zalecana maksymalna liczba znaczników to 10 tys.
Dostęp do lokalizacji
W tym przykładzie używany jest GPS urządzenia, aby zlokalizować użytkownika i mapę na jego współrzędnych. Aby włączyć tę funkcję, musisz dodać opis do uprawnienia NSLocationWhenInUseUsageDescription
w pliku Info.plist
projektu.
Aby to dodać, wykonaj te czynności:
- Kliknij plik
Info.plist
w usłudze Project Navigator w Xcode, aby otworzyć edytor listy usług. - Kliknij ikonę „+” obok pozycji „Lista właściwości informacji”, aby dodać nową właściwość.
- W polu „key” (klucz) wpisz „NSLocationWhenInUseUsageDescription”. Xcode automatycznie przetłumaczy to na długą nazwę „Privacy - Location when In Use Usage Description” (Prywatność – lokalizacja podczas używania). Pełną listę możliwych właściwości dostępu do lokalizacji znajdziesz w sekcji Prośba o autoryzację dla usług lokalizacyjnych w dokumentacji dla deweloperów Apple.
- W polu „Typ” pozostaw ustawienie „Ciąg”.
- W polu „Wartość” wpisz opis, dlaczego aplikacja wymaga użycia lokalizacji użytkownika. Na przykład „Wyświetla użytkownik, który chce udostępnić wizytówki firm w pobliżu”.
Wdrażanie grupowania znaczników
Wdrażanie grupowania znaczników obejmuje 3 kroki:
- Utwórz instancję menedżera klastra.
- Przekaż znaczniki, które chcesz pogrupować, do menedżera klastrów.
- Wywołaj menedżera klastra.
Tworzę menedżera klastra
Aby użyć menedżera klastrów, wykonaj te czynności:
- Ustaw
ViewController
, w którym jest renderowana mapa, tak aby była zgodna z protokołemGMSMapViewDelegate
. - Utwórz instancję
GMUClusterManager
. - Przekaż do instancji
GMUClusterManager
instancjęGMSMapView
, w której chcesz wdrożyć klastry znaczników, oraz implementacje tych protokołów:GMUClusterIconGenerator
: udostępnia logikę aplikacji, która pobiera ikony klastra, które mają być używane przy różnych poziomach powiększenia.GMUClusterAlgorithm
: określa algorytm określający sposób grupowania znaczników, np. odległość między znacznikami do uwzględnienia w tej samej grupie.GMUClusterRenderer
: udostępnia logikę aplikacji, która automatycznie renderuje ikony klastrów na mapie.
- Ustaw delegata map w instancji
GMUClusterManager
.
Biblioteka narzędziowa zawiera domyślne implementacje generatora ikon (GMUDefaultClusterIconGenerator
), algorytmu (GMUNonHierarchicalDistanceBasedAlgorithm
) i mechanizmu renderowania (GMUDefaultClusterRenderer
). Opcjonalnie możesz utworzyć własny mechanizm generowania ikon klastra, algorytm i mechanizm renderowania.
Ten kod tworzy menedżera klastra z użyciem tych wartości domyślnych w wywołaniu zwrotnym viewDidLoad
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.
Pojedynczy 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
Gdy utworzysz klaster znaczników i przekażesz mu znaczniki, które chcesz pogrupować, wystarczy, że wywołasz metodę cluster
w instancji klastra znaczników.
Swift
clusterManager.cluster()
Objective-C
[_clusterManager cluster];
Obsługa zdarzeń w znacznikach i klastrach
Ogólnie, aby nasłuchiwać zdarzeń na mapie, używając pakietu SDK Map Google na iOS, musisz wdrożyć protokół GMSMapViewDelegate
. Możesz nasłuchiwać zdarzeń mapowania, ale nie możesz nasłuchiwać zdarzeń menedżera klastra bezpiecznego dla typu. Gdy użytkownik kliknie znacznik, pojedynczy element klastra lub klaster, interfejs API aktywuje 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
, aby określić, 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 klastrów przechwytuje teraz wszystkie zdarzenia zaimplementowane w clusterManager
. Przekazuje wszystkie pozostałe zdarzenia do delegata mapowania, jeśli został podany. Pamiętaj, że zdarzenia związane ze znacznikami standardowymi (czyli znaczniki, które nie zostały wygenerowane przez mechanizm renderowania klastra) są zawsze przekierowywane do delegata mapy.
Dostosuj grupowanie znaczników
Możesz podać niestandardową implementację dla właściwości GMUClusterRenderer
, GMUClusterIconGenerator
lub GMUClusterAlgorithm
. Własną implementację możesz oprzeć na przykładowej implementacji tych protokołów w bibliotece narzędzi lub na kodowaniu w pełni niestandardowej implementacji, wypełniając wybrane protokoły.