此页面介绍了 实用程序库 (适用于 Maps SDK for iOS)。
通过将标记聚类,您可以将大量标记放置在地图上 而且不会使地图难以阅读标记聚类实用程序可帮助您 管理不同缩放级别的多个标记。
当用户以较高的放大倍数查看地图时,地图上会显示每一个具体标记。当用户缩小地图时,标记会聚集在一起, 集中在一起,以便更轻松地查看地图。
下面的屏幕截图显示了标记聚类的默认样式:
![一幅采用默认样式并包含聚类标记的地图](https://developers.google.cn/static/maps/documentation/ios-sdk/images/clustering-default-icon.png?authuser=7&hl=sr)
下面是一个自定义标记聚类的示例:
![一幅包含自定义的已聚类标记的地图](https://developers.google.cn/static/maps/documentation/ios-sdk/images/clustering-custom-icon.png?authuser=7&hl=sr)
前提条件和说明
Maps SDK for iOS 实用程序库
标记聚类实用程序是 Maps SDK for iOS 实用程序库。如果您尚未设置该库,请先按照设置指南操作,然后再阅读本页面的其余内容。
为获得最佳性能,建议的最大标记数量为 10,000。
位置信息权限
此示例使用设备的 GPS 根据用户的坐标定位用户和地图。启用
因此,您必须为 NSLocationWhenInUseUsageDescription
权限添加说明
在项目的 Info.plist
文件中。
如需添加,请执行以下操作:
- 点击 Xcode 中 Project Navigator 中的
Info.plist
文件,以打开 属性列表编辑器。 - 点击“+”“信息属性列表”旁边的图标以添加新的媒体资源
- 在“密钥”中字段中,输入“NSLocationWhenInUseUsageDescription”。Xcode 会自动 将以下内容转换为长名称“Privacy - Location when Use UsageDescription”。对于 可能的位置权限属性的完整列表,请参阅 请求授权使用位置信息服务 。
- 保留“类型”字段设置为“String”。
- 在“值”字段中输入说明,说明您的应用需要使用 用户的地理位置例如,“定位用户以提供附近的商家信息”。
实现标记聚类
实现标记聚类需要三个步骤:
如需查看有关如何实现标记聚类的完整示例,请参阅 GitHub 上的 Objective-C 和 Swift 示例应用。创建集群管理器
如需使用集群管理器,请执行以下操作:
- 设置用于渲染地图的
ViewController
,使其符合GMSMapViewDelegate
协议。 - 创建
GMUClusterManager
的实例。 - 传递您想要实现标记聚类的
GMSMapView
实例GMUClusterManager
实例的以下协议及其实现: <ph type="x-smartling-placeholder">- </ph>
GMUClusterIconGenerator
:提供用于提取 在不同缩放级别下使用的聚类图标。GMUClusterAlgorithm
:指定用于确定行为的算法 标记的聚类方式,例如要在同一聚类中添加的标记之间的距离。GMUClusterRenderer
:提供用于处理实际 在地图上的聚类图标渲染。
- 在
GMUClusterManager
实例上设置地图委托。
实用程序库包含图标生成器的默认实现 (GMUDefaultClusterIconGenerator
),
算法 (GMUNonHierarchicalDistanceBasedAlgorithm
) 和渲染程序 (GMUDefaultClusterRenderer
)。
您可以选择创建自己的自定义图标生成器、算法和渲染程序。
以下代码会在 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
添加标记
向标记聚类器添加标记的方法有两种:单独添加标记或以数组的形式添加标记。
单个标记
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];
标记数组
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];
调用标记聚类器
创建标记聚类器并向其传递要聚类的标记后,
只需在标记聚类器实例上调用 cluster
方法即可。
Swift
clusterManager.cluster()
Objective-C
[_clusterManager cluster];
处理标记和聚类上的事件
一般来说,在使用 Maps SDK for iOS 时,若要监听地图上的事件,您必须实现
GMSMapViewDelegate
协议。您可以收听
地图事件,但您不能
监听类型安全的集群管理器事件。当用户点按标记时,
单个集群项或集群,则 API 会触发
mapView:didTapMarker:
,并将额外的集群数据附加到
marker.userData
属性。然后,您可以检查 userData
是否符合
GMUCluster
协议,用于确定是否点按了聚类图标或标记。
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; }
现在,聚类管理器会拦截您在
clusterManager
。它会将任何剩余事件转发到地图
委托(如果提供)。请注意,标准标记的事件
(即不是由聚类渲染程序生成的标记)始终会转发
传递给地图委托。
自定义标记聚类
您可以为
GMUClusterRenderer
、GMUClusterIconGenerator
或
GMUClusterAlgorithm
。您可以将自定义实现方案作为基础
实用程序中包括的这些协议的示例实现
库实现,也可以通过执行
协议