地図の上にタイル レイヤとして画像を追加できます。タイルレイヤは、特定のズームレベルで地図タイルの上に配置されます。十分な数のタイルがあれば、複数のズームレベルでマップ全体にわたって Google のマップデータを補うことができます。
はじめに
タイルレイヤ(タイル オーバーレイとも呼ばれる)を使用すると、Google の基本地図タイルの上に画像を重ねて表示できます。この機能を使用すると、アプリにデータ(スポットや交通情報など)やローカル画像を追加できます。kGMSTypeNone
地図タイプと組み合わせると、タイルレイヤを使用して Google の基本地図データを独自のデータに効果的に置き換えることができます。
タイルレイヤは、広い地理的領域を対象とする大きな画像をマップに追加する場合に役立ちます。一方、地面オーバーレイは、地図上の 1 つのポイントに 1 つの画像を固定したい場合に役立ちます。
タイル座標
Maps API は、各ズームレベルの画像を、順序付けられたグリッドに配置された一連の正方形の地図タイルに分割します。地図を新しい位置にスクロールする、または新しいズームレベルにスクロールすると、Maps API は必要なタイルを決定し、そのタイルを取得するタイルのグループに変換します。
Google によるメルカトル図法の実装では、座標(0,0)のタイルは常に地図の北西端になり、x
値は西から東に増分し、y
値は北から南に増分します。タイルは、この原点からの x,y
座標を使用してインデックスが付けられます。たとえば、ズームレベル 2 で地球が 16 個のタイルに分割された場合は、各タイルは一意の x,y
ペアで参照できます。
各マップ タイプは 256 x 256 ポイントの正方形です。ズームレベル 0 では、全世界が 1 つのタイルでレンダリングされます。各ズームレベルは、2 の倍数で倍率が増大します。たとえば、ズームレベル 1 では地図は 2x2 グリッドのタイルとしてレンダリングされ、ズームレベル 2 では 4x4 グリッド、ズームレベル 3 では 8x8 グリッドとしてレンダリングされます。タイルレイヤの画像を作成するには、サポートするズームレベルごとに、各タイルの 256x256 ポイントの画像を作成します。
タイル レイヤの追加
GMSURLTileLayer
オブジェクト、またはGMSTileLayer
またはGMSSyncTileLayer
のカスタム サブクラスをインスタンス化します。- 必要に応じて、
zIndex
プロパティを変更して、他のタイルレイヤとの相対的な位置を調整します。 GMSTileLayer
オブジェクトのmap
プロパティを設定して、オブジェクトを地図に割り当てます。
Maps SDK for iOS には、タイルレイヤの実装に使用できる 3 つのクラスが用意されています。各クラスで、指定された {x,y,zoom}
座標のセットに対して正しい地図タイルを取得する方法を定義する必要があります。使用できるオプションは次のとおりです。
GMSSyncTileLayer
をサブクラス化し、UIImage
インスタンスを返すtileForX:y:zoom
の実装を提供します。GMSTileLayer
をサブクラス化し、後でタイル画像をコールバックする非同期メソッドrequestTileForX:y:zoom
の実装を提供します。- 既存のクラス
GMSURLTileLayer
を使用して、URL からタイルを自動的に取得し、GMSTileURLConstructor
ブロックを提供します。GMSURLTileLayer
はサブクラス化できない具象クラスです。
GMSSyncTileLayer
または GMSTileLayer
をサブクラス化する場合、nil
タイル結果を提供すると、データは利用できないが、将来利用可能になる可能性があることが Maps SDK for iOS に通知されます。または、kGMSTileLayerNoTile
を返して、この場所にタイルがないことを示します。
GMSURLTileLayer
の場合、GMSTileURLConstructor
から nil
を返すと、この場所にタイルがないことを示します。
GMSURLTileLayer を使用して URL からタイルを取得
GMSURLTileLayer
にはサブクラス化は必要ありませんが、GMSTileURLConstructor
ブロックを実装する必要があります。次のコードは、GMSURLTileLayer
を使用して複数階建ての建物のフロアプランを表示する方法を示しています。
Swift
let floor = 1 // Implement GMSTileURLConstructor // Returns a Tile based on the x,y,zoom coordinates, and the requested floor let urls: GMSTileURLConstructor = { (x, y, zoom) in let url = "https://www.example.com/floorplans/L\(floor)_\(zoom)_\(x)_\(y).png" return URL(string: url) } // Create the GMSTileLayer let layer = GMSURLTileLayer(urlConstructor: urls) // Display on the map at a specific zIndex layer.zIndex = 100 layer.map = mapView
Objective-C
NSInteger floor = 1; // Create the GMSTileLayer GMSURLTileLayer *layer = [GMSURLTileLayer tileLayerWithURLConstructor:^NSURL * _Nullable(NSUInteger x, NSUInteger y, NSUInteger zoom) { NSString *url = [NSString stringWithFormat:@"https://www.example.com/floorplans/L%ld_%lu_%lu_%lu.png", (long)floor, (unsigned long)zoom, (unsigned long)x, (unsigned long)y]; return [NSURL URLWithString:url]; }]; // Display on the map at a specific zIndex layer.zIndex = 100; layer.map = mapView;
GMSSyncTileLayer をサブクラス化して UIImage としてタイルを提供
GMSSyncTileLayer
と GMSTileLayer
は、サブクラス化されるように設計された抽象クラスです。これらのクラスを使用して、タイルを UIImage
として提供できます。次の例は、GMSSyncTileLayer
をサブクラス化して、地図上のタイルの上にカスタム画像をレンダリングする方法を示しています。
Swift
class TestTileLayer: GMSSyncTileLayer { override func tileFor(x: UInt, y: UInt, zoom: UInt) -> UIImage? { // On every odd tile, render an image. if (x % 2 == 1) { return UIImage(named: "australia") } else { return kGMSTileLayerNoTile } } }
Objective-C
@interface TestTileLayer : GMSSyncTileLayer @end @implementation TestTileLayer - (UIImage *)tileForX:(NSUInteger)x y:(NSUInteger)y zoom:(NSUInteger)zoom { // On every odd tile, render an image. if (x % 2 == 1) { return [UIImage imageNamed:@"australia"]; } else { return kGMSTileLayerNoTile; } } @end
マップにレイヤーを追加するには、オブジェクトをインスタンス化して map プロパティを設定します。
Swift
let layer = TestTileLayer() layer.map = mapView
Objective-C
GMSTileLayer *layer = [[TestTileLayer alloc] init]; layer.map = mapView;
Retina 端末用の高 DPI タイル
tileSize
を 512 に設定することで、GMSSyncTileLayer
または GMSURLTileLayer
のいずれかで高 DPI 画像を使用できます。tileSize
プロパティは、返されたタイル画像を優先的に表示するピクセル数を示します。デフォルトは 256 です。これは、非 Retina デバイス上の Google マップのタイルのサイズです。
高 DPI デバイスに通常の DPI タイルを表示する場合は、tileSize
を 512 に設定して画像を拡大できます。画像をアップスケールすると、特に細い線やテキストの画質が低下する可能性があります。最適な結果を得るには、tileSize
と画像の DPI をディスプレイに合わせます。Retina デバイスに表示される地図は、tileSize
が 512 の高 DPI 画像を表示すると最適に見えます。一方、Retina 以外のデバイスに表示される地図は、通常の画像とデフォルトの tileSize
である 256 で最適に見えます。
古いタイルを消去する
レイヤにより提供されたタイルが「古く」なったら、レイヤで clearTileCache
メソッドを呼び出して強制的に更新する必要があります。これを呼び出すと、このレイヤ上のすべてのタイルがリロードされます。
Swift
layer.clearTileCache()
Objective-C
[layer clearTileCache];