地図の上にタイル レイヤとして画像を追加できます。タイルレイヤは、特定のズームレベルのマップタイル上に配置されます。十分な数のタイルがあれば、複数のズームレベルで地図全体の 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
プロパティを変更して、他のタイルレイヤに対する位置を調整します。 map
プロパティを設定して、GMSTileLayer
オブジェクトを地図に割り当てます。
Maps SDK for iOS には、タイルレイヤの実装に使用できる 3 つのクラスが用意されています。クラスごとに、指定された {x,y,zoom}
座標のセットに対して正しい地図タイルを取得する方法を定義する必要があります。使用できるオプションは次のとおりです。
GMSSyncTileLayer
をサブクラス化して、UIImage
インスタンスを返すtileForX:y:zoom
の実装を提供します。GMSTileLayer
をサブクラス化し、後でタイル画像を返す非同期メソッドrequestTileForX:y:zoom
の実装を提供します。- 既存のクラスの
GMSURLTileLayer
を使用して、GMSTileURLConstructor
ブロックを指定して URL からタイルを自動的に取得します。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];