地図の上にタイル レイヤとして画像を追加できます。タイルレイヤーは、特定のズームレベルでマップの上に配置されます。複数のズームレベルに十分な数のタイルがある場合は、マップ全体について 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
を使用して、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];