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