Stay organized with collections Save and categorize content based on your preferences.
This page describes the marker clustering utility that's available in the utility library for the Maps SDK for iOS.
By clustering your markers, you can put a large number of markers on a map without making the map hard to read. The marker clustering utility helps you manage multiple markers at different zoom levels.
When a user views the map at a high zoom level, the individual markers show on the map. When the user zooms out, the markers gather together into clusters, to make viewing the map easier.
The following screenshot shows the default style of marker clusters:
Below is an example of custom marker clusters:
Prerequisites and notes Maps SDK for iOS Utility LibraryThe marker clustering utility is part of the Maps SDK for iOS Utility Library. If you haven't yet set up the library, follow the setup guide before reading the rest of this page.
For best performance, the recommended maximum number of markers is 10,000.
Location permissionThis example uses the device's GPS to locate the user and the map on their coordinates. To enable this, you must add a description to the NSLocationWhenInUseUsageDescription
permission in the project's Info.plist
file.
To add this, do the following:
Info.plist
file in the Project Navigator in Xcode to open the Property List Editor.Implementing marker clustering takes three steps:
To see a complete example of how to implement marker clustering, check out the Objective-C and Swift
example apps on GitHub.
Creating the cluster managerTo use the cluster manager, do the following:
ViewController
where your map is rendered to conform to the GMSMapViewDelegate
protocol.GMUClusterManager
.GMSMapView
you want to implement marker clustering in and implementations of the following protocols to the GMUClusterManager
instance:
GMUClusterIconGenerator
: Provides application logic that fetches the cluster icons to be used at different zoom levels.GMUClusterAlgorithm
: Specifies an algorithm that determines the behavior of how markers are clustered, such as the distance between markers to include in the same cluster.GMUClusterRenderer
: Provides application logic that handles the actual rendering of the cluster icons on the map.GMUClusterManager
instance.The utility library includes default implementations of the icon generator (GMUDefaultClusterIconGenerator
), algorithm (GMUNonHierarchicalDistanceBasedAlgorithm
) and renderer (GMUDefaultClusterRenderer
). You may optionally create your own custom clustrering icon genertator, algorithm and renderer.
The following code creates a cluster manager using these defaults in the viewDidLoad
callback of ViewController
:
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]; // ... } // ... @endAdding markers
There are two ways to add markers to the marker clusterer: individually or as an array.
Individual marker Swiftlet 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];Array of markers 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];Invoking the marker clusterer
Once you have created your marker clusterer and passed it the markers you wish to cluster, all you have to do is call the cluster
method on your marker clusterer instance.
clusterManager.cluster()Objective-C
[_clusterManager cluster];Handle events on markers and clusters
In general when using the Maps SDK for iOS, to listen to events on the map you must implement the GMSMapViewDelegate
protocol. You can listen to map events, but you can't listen to the type-safe cluster manager events. When the user taps a marker, an individual cluster item, or a cluster, the API triggers mapView:didTapMarker:
and attaches the extra cluster data to the marker.userData
property. You can then check if the userData
conforms to the GMUCluster
protocol to determine if a cluster icon or a marker was tapped.
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; }
The cluster manager now intercepts any events that you've implemented on clusterManager
. It forwards any remaining events to the map delegate, if provided. Note that events for standard markers (that is, markers not generated by the cluster renderer) are always forwarded to the map delegate.
You can provide a custom implementation for the GMUClusterRenderer
, GMUClusterIconGenerator
, or GMUClusterAlgorithm
. You can base your custom implementation on the sample implementation of these protocols included in the utility library, or you can code a fully custom implementation by fulfilling the protocols.
Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 4.0 License, and code samples are licensed under the Apache 2.0 License. For details, see the Google Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.
Last updated 2025-07-23 UTC.
[[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Missing the information I need","missingTheInformationINeed","thumb-down"],["Too complicated / too many steps","tooComplicatedTooManySteps","thumb-down"],["Out of date","outOfDate","thumb-down"],["Samples / code issue","samplesCodeIssue","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2025-07-23 UTC."],[[["The marker clustering utility for the Maps SDK for iOS helps manage the display of large numbers of markers by grouping them into clusters at different zoom levels."],["Implementing marker clustering involves creating a cluster manager, adding markers to it, and invoking the clustering process."],["You can customize the appearance and behavior of marker clusters by providing your own implementations for cluster rendering, icon generation, and clustering algorithms."],["The utility library includes default implementations for cluster rendering, icon generation, and clustering algorithms that you can use directly or as a basis for customization."],["To handle events on markers and clusters, implement the `GMSMapViewDelegate` protocol and check the `marker.userData` property to determine if a cluster or individual marker was tapped."]]],[]]
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4