标记聚类

请选择平台: Android iOS JavaScript

此页面介绍了 实用程序库 (适用于 Maps SDK for iOS)

通过将标记聚类,您可以将大量标记放置在地图上 而且不会使地图难以阅读标记聚类实用程序可帮助您 管理不同缩放级别的多个标记。

当用户以较高的放大倍数查看地图时,地图上会显示每一个具体标记。当用户缩小地图时,标记会聚集在一起, 集中在一起,以便更轻松地查看地图。

下面的屏幕截图显示了标记聚类的默认样式:

一幅采用默认样式并包含聚类标记的地图

下面是一个自定义标记聚类的示例:

一幅包含自定义的已聚类标记的地图

前提条件和说明

Maps SDK for iOS 实用程序库

标记聚类实用程序是 Maps SDK for iOS 实用程序库。如果您尚未设置该库,请先按照设置指南操作,然后再阅读本页面的其余内容。

为获得最佳性能,建议的最大标记数量为 10,000。

位置信息权限

此示例使用设备的 GPS 根据用户的坐标定位用户和地图。启用 因此,您必须为 NSLocationWhenInUseUsageDescription 权限添加说明 在项目的 Info.plist 文件中。

如需添加,请执行以下操作:

  1. 点击 Xcode 中 Project Navigator 中的 Info.plist 文件,以打开 属性列表编辑器。
  2. 点击“+”“信息属性列表”旁边的图标以添加新的媒体资源
  3. 在“密钥”中字段中,输入“NSLocationWhenInUseUsageDescription”。Xcode 会自动 将以下内容转换为长名称“Privacy - Location when Use UsageDescription”。对于 可能的位置权限属性的完整列表,请参阅 请求授权使用位置信息服务
  4. 保留“类型”字段设置为“String”。
  5. 在“值”字段中输入说明,说明您的应用需要使用 用户的地理位置例如,“定位用户以提供附近的商家信息”。

实现标记聚类

实现标记聚类需要三个步骤:

  1. 创建集群管理器实例。
  2. 将您想要聚类的标记传递给聚类管理器。
  3. 调用集群管理器。
如需查看有关如何实现标记聚类的完整示例,请参阅 GitHub 上的 Objective-C 和 Swift 示例应用

创建集群管理器

如需使用集群管理器,请执行以下操作:

  1. 设置用于渲染地图的 ViewController,使其符合 GMSMapViewDelegate 协议。
  2. 创建 GMUClusterManager 的实例。
  3. 传递您想要实现标记聚类的 GMSMapView 实例 GMUClusterManager 实例的以下协议及其实现: <ph type="x-smartling-placeholder">
      </ph>
    • GMUClusterIconGenerator:提供用于提取 在不同缩放级别下使用的聚类图标。
    • GMUClusterAlgorithm:指定用于确定行为的算法 标记的聚类方式,例如要在同一聚类中添加的标记之间的距离。
    • GMUClusterRenderer:提供用于处理实际 在地图上的聚类图标渲染。
  4. 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。它会将任何剩余事件转发到地图 委托(如果提供)。请注意,标准标记的事件 (即不是由聚类渲染程序生成的标记)始终会转发 传递给地图委托。

自定义标记聚类

您可以为 GMUClusterRendererGMUClusterIconGeneratorGMUClusterAlgorithm。您可以将自定义实现方案作为基础 实用程序中包括的这些协议的示例实现 库实现,也可以通过执行 协议