このページでは、Maps SDK for iOS 用 ユーティリティ ライブラリ で使用できるマーカー クラスタリング ユーティリティについて説明します。
マーカーをクラスタ化すると、地図を読みにくくすることなく、多数のマーカーを地図上に配置できます 。マーカー クラスタリング ユーティリティを使うと、異なるズームレベルにある複数のマーカーを 管理できます。
ユーザーが高いズームレベルでマップを表示すると、個別の マーカーがマップ上に表示されます。ユーザーがズームアウトすると、マーカーがクラスタに集まり 、地図が見やすくなります。
次のスクリーンショットは、マーカー クラスターのデフォルトのスタイルを示しています。
以下に、カスタム マーカー クラスターの例を示します。
前提条件と注意事項
Google Maps SDK for iOS ユーティリティ ライブラリ
マーカー クラスタリング ユーティリティは、 Google Maps SDK for iOS ユーティリティ ライブラリに含まれています。ライブラリをまだセットアップしていない場合は、 このページの残りを読む前に、設定ガイド に従ってセットアップしてください。
最高のパフォーマンスを実現するために推奨されるマーカーの最大数は 10,000 です。
位置情報の利用許可
この例では、デバイスの GPS を使用してユーザーの位置を特定し、地図をユーザーの座標に表示します。これを有効にするには、プロジェクトのInfo.plist ファイルでNSLocationWhenInUseUsageDescription権限に説明を追加する必要があります。
追加する手順は次のとおりです。
- Xcode のプロジェクト ナビゲータで
Info.plistファイルをクリックして、 プロパティ リスト エディタを開きます。 - [Information Property List] の横にある [+] アイコンをクリックして、新しいプロパティを追加します。
- [key] フィールドに「NSLocationWhenInUseUsageDescription」と入力します。Xcode は、これを「Privacy - Location When In Use Usage Description」という長い名前に自動的に 変換します。位置情報の利用許可プロパティの完全なリストについては、Apple デベロッパー ドキュメントの ロケーション サービスへの承認のリクエストをご覧ください。
- [Type] フィールドは [String] に設定したままにします。
- [Value] フィールドに、アプリでユーザーの位置情報を使用する必要がある理由の説明を入力します。たとえば、「ユーザーの位置を特定して、近くのビジネス リスティングを提供します。」などです。
マーカー クラスタリングを実装する
マーカー クラスタリングの実装は、次の 3 つの手順で行います。
マーカー クラスタリングを実装する方法の完全な例については、GitHub の Objective-C と Swift のサンプルアプリをご覧ください。クラスタ マネージャーを作成する
クラスタ マネージャーを使用するには、次の操作を行います。
- 地図がレンダリングされる
ViewControllerを設定して、GMSMapViewDelegateプロトコルに準拠させます。 GMUClusterManagerのインスタンスを作成します。- マーカー クラスタリングを実装する
GMSMapViewのインスタンスと、次のプロトコルの実装をGMUClusterManagerインスタンスに渡します。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
マーカーを追加する
マーカー クラスタにマーカーを追加する方法は、個別に追加する方法と配列として追加する方法の 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プロパティに添付します。次に、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のカスタム実装を提供できます。カスタム実装は、ユーティリティ
ライブラリに含まれているこれらのプロトコルのサンプル実装に基づいて作成することも、プロトコルを満たすことで完全にカスタム実装をコーディングすることもできます。