マーカー クラスタリング

プラットフォームを選択: Android iOS JavaScript

このページでは、Maps SDK for iOS 用 ユーティリティ ライブラリ で使用できるマーカー クラスタリング ユーティリティについて説明します

マーカーをクラスタ化すると、地図を読みにくくすることなく、多数のマーカーを地図上に配置できます 。マーカー クラスタリング ユーティリティを使うと、異なるズームレベルにある複数のマーカーを 管理できます。

ユーザーが高いズームレベルでマップを表示すると、個別の マーカーがマップ上に表示されます。ユーザーがズームアウトすると、マーカーがクラスタに集まり 、地図が見やすくなります。

次のスクリーンショットは、マーカー クラスターのデフォルトのスタイルを示しています。

デフォルトのスタイルでクラスタリングされたマーカーのあるマップ

以下に、カスタム マーカー クラスターの例を示します。

カスタムのクラスタリングされたマーカーのあるマップ

前提条件と注意事項

Google Maps SDK for iOS ユーティリティ ライブラリ

マーカー クラスタリング ユーティリティは、 Google Maps SDK for iOS ユーティリティ ライブラリに含まれています。ライブラリをまだセットアップしていない場合は、 このページの残りを読む前に、設定ガイド に従ってセットアップしてください。

最高のパフォーマンスを実現するために推奨されるマーカーの最大数は 10,000 です。

位置情報の利用許可

この例では、デバイスの GPS を使用してユーザーの位置を特定し、地図をユーザーの座標に表示します。これを有効にするには、プロジェクトのInfo.plist ファイルでNSLocationWhenInUseUsageDescription権限に説明を追加する必要があります。

追加する手順は次のとおりです。

  1. Xcode のプロジェクト ナビゲータで Info.plist ファイルをクリックして、 プロパティ リスト エディタを開きます。
  2. [Information Property List] の横にある [+] アイコンをクリックして、新しいプロパティを追加します。
  3. [key] フィールドに「NSLocationWhenInUseUsageDescription」と入力します。Xcode は、これを「Privacy - Location When In Use Usage Description」という長い名前に自動的に 変換します。位置情報の利用許可プロパティの完全なリストについては、Apple デベロッパー ドキュメントの ロケーション サービスへの承認のリクエストをご覧ください。
  4. [Type] フィールドは [String] に設定したままにします。
  5. [Value] フィールドに、アプリでユーザーの位置情報を使用する必要がある理由の説明を入力します。たとえば、「ユーザーの位置を特定して、近くのビジネス リスティングを提供します。」などです。

マーカー クラスタリングを実装する

マーカー クラスタリングの実装は、次の 3 つの手順で行います。

  1. クラスタ マネージャー インスタンスを作成します。
  2. クラスタ化するマーカーをクラスタ マネージャーに渡します。
  3. クラスタ マネージャーを呼び出します。
マーカー クラスタリングを実装する方法の完全な例については、GitHub の Objective-C と Swift のサンプルアプリをご覧ください

クラスタ マネージャーを作成する

クラスタ マネージャーを使用するには、次の操作を行います。

  1. 地図がレンダリングされる ViewController を設定して、 GMSMapViewDelegate プロトコルに準拠させます。
  2. GMUClusterManager のインスタンスを作成します。
  3. マーカー クラスタリングを実装する GMSMapView のインスタンスと、次のプロトコルの実装を GMUClusterManager インスタンスに渡します。
    • 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
      

マーカーを追加する

マーカー クラスタにマーカーを追加する方法は、個別に追加する方法と配列として追加する方法の 2 つがあります。

個々のマーカー

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プロパティに添付します。次に、userDataGMUCluster プロトコルに準拠しているかどうかを確認して、クラスタアイコンまたはマーカーがタップされたかどうかを判断できます。

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に実装したイベントをインターセプトするようになりました。残りのイベントは、指定されている場合は地図の デリゲートに転送されます。標準マーカーのイベント (つまり、クラスタ レンダラによって生成されないマーカー)は常に地図のデリゲートに転送されます。

マーカー クラスタリングをカスタマイズする

GMUClusterRendererGMUClusterIconGenerator、または GMUClusterAlgorithmのカスタム実装を提供できます。カスタム実装は、ユーティリティ ライブラリに含まれているこれらのプロトコルのサンプル実装に基づいて作成することも、プロトコルを満たすことで完全にカスタム実装をコーディングすることもできます。