Na tej stronie znajdziesz opis narzędzia do łączenia znaczników w klastry, które jest dostępne w bibliotece narzędzi pakietu Maps SDK na iOS.
Dzięki łączeniu znaczników w klastry możesz umieścić na mapie dużą liczbę znaczników bez utrudniania jej czytelności. Narzędzie do łączenia znaczników w klastry pomaga zarządzać wieloma znacznikami na różnych poziomach powiększenia.
Gdy użytkownik wyświetla mapę na wysokim poziomie powiększenia, na mapie widoczne są poszczególne znaczniki. Gdy użytkownik oddala widok, znaczniki łączą się w klastry, co ułatwia przeglądanie mapy.
Poniższy zrzut ekranu przedstawia domyślny styl klastrów znaczników:
Poniżej znajdziesz przykład niestandardowych klastrów znaczników:
Wymagania wstępne i uwagi
Biblioteka narzędzi pakietu Maps SDK na iOS
Narzędzie do łączenia znaczników w klastry jest częścią biblioteki narzędzi pakietu Maps SDK na iOS. Jeśli nie masz jeszcze skonfigurowanej biblioteki, przed przeczytaniem reszty tej strony zapoznaj się z przewodnikiem konfiguracji.
Aby uzyskać najlepsze wyniki, zalecamy używanie maksymalnie 10 tys. znaczników.
Dostęp do lokalizacji
W tym przykładzie używamy GPS urządzenia do lokalizowania użytkownika i mapy na podstawie jego współrzędnych. Aby włączyć
to, musisz dodać opis do uprawnienia NSLocationWhenInUseUsageDescription w pliku Info.plist projektu.
Aby to zrobić:
- W Xcode kliknij plik
Info.plistw nawigatorze projektu, aby otworzyć edytor listy właściwości. - Kliknij ikonę „+” obok opcji „Information Property List” (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ść – opis użycia lokalizacji, gdy aplikacja jest używana). Pełną listę możliwych właściwości dostępu do lokalizacji znajdziesz w dokumentacji Apple Developer w artykule Requesting Authorization for Location Services (Prośba o autoryzację usług lokalizacyjnych).
- W polu „Type” (Typ) pozostaw ustawienie „String” (Ciąg znaków).
- W polu „Value” (Wartość) wpisz opis powodu, dla którego Twoja aplikacja wymaga dostępu do lokalizacji użytkownika. Na przykład „Lokalizuje użytkownika, aby wyświetlać informacje o firmach w pobliżu”.
Wdrażanie łączenia znaczników w klastry
Wdrażanie łączenia znaczników w klastry wymaga 3 kroków:
- Utwórz instancję menedżera klastrów.
- Przekaż do menedżera klastrów znaczniki, które chcesz połączyć w klastry.
- Wywołaj menedżera klastrów.
Tworzenie menedżera klastrów
Aby użyć menedżera klastrów:
- Ustaw
ViewController, w którym renderowana jest mapa, tak aby był zgodny zGMSMapViewDelegateprotokołem. - Utwórz instancję
GMUClusterManager. - Przekaż do instancji
GMUClusterManagerinstancjęGMSMapView, w której chcesz wdrożyć łączenie znaczników w klastry , oraz implementacje tych protokołów:GMUClusterIconGenerator: udostępnia logikę aplikacji, która pobiera ikony klastrów do użycia na różnych poziomach powiększenia.GMUClusterAlgorithm: określa algorytm, który decyduje o sposobie łączenia znaczników w klastry , np. o odległości między znacznikami, które mają być uwzględnione w tym samym klastrze.GMUClusterRenderer: udostępnia logikę aplikacji, która obsługuje rzeczywiste renderowanie ikon klastrów na mapie.
- Ustaw delegata mapy w instancji
GMUClusterManager.
Biblioteka narzędzi zawiera domyślne implementacje generatora ikon (GMUDefaultClusterIconGenerator),
algorytmu (GMUNonHierarchicalDistanceBasedAlgorithm) i renderera (GMUDefaultClusterRenderer).
Możesz też utworzyć własny niestandardowy generator ikon, algorytm i renderer.
Poniższy kod tworzy menedżera klastrów, który używa tych domyślnych ustawień w viewDidLoad
wywołaniu zwrotnym 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
Znaczniki można dodawać do rozwiązania do łączenia znaczników w klastry na 2 sposoby: pojedynczo lub jako tablicę.
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ływanie narzędzia do łączenia znaczników w klastry
Gdy utworzysz rozwiązanie do łączenia znaczników w klastry i przekażesz do niego znaczniki, które chcesz połączyć w klastry, wszystko co musisz zrobić, to wywołać metodę cluster w instancji rozwiązania do łączenia znaczników w klastry.
Swift
clusterManager.cluster()
Objective-C
[_clusterManager cluster];
Obsługa zdarzeń dotyczących znaczników i klastrów
Ogólnie rzecz biorąc, aby nasłuchiwać zdarzeń na mapie podczas korzystania z pakietu Maps SDK na iOS, musisz zaimplementować
protokół GMSMapViewDelegate. Możesz nasłuchiwać
zdarzeń na mapie, ale nie możesz
nasłuchiwać zdarzeń menedżera klastrów, które są bezpieczne pod względem typów. Gdy użytkownik kliknie znacznik,
pojedynczy element klastra lub klaster, interfejs API wywoła
mapView:didTapMarker: i dołączy dodatkowe dane klastra do
właściwości marker.userData. Następnie możesz sprawdzić, czy userData jest zgodna z
protokołem GMUCluster, aby określić, czy kliknięto ikonę klastra czy 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, które zostały zaimplementowane w
clusterManager. Wszystkie pozostałe zdarzenia przekazuje do delegata mapy, jeśli jest on dostępny. Pamiętaj, że zdarzenia dotyczące standardowych znaczników
(czyli znaczników, które nie zostały wygenerowane przez mechanizm renderowania klastrów) są zawsze przekazywane
do delegata mapy.
Dostosowywanie łączenia znaczników w klastry
Możesz podać niestandardową implementację dla
GMUClusterRenderer, GMUClusterIconGenerator, lub
GMUClusterAlgorithm. Możesz oprzeć swoją niestandardową implementację
na przykładowej implementacji tych protokołów zawartej w bibliotece narzędzi
lub napisać w pełni niestandardową implementację, która spełnia wymagania protokołów.