タイルレイヤ

プラットフォームを選択: Android iOS JavaScript

地図の上にタイル レイヤとして画像を追加できます。タイルレイヤは、特定のズームレベルで地図タイルの上に配置されます。十分な数のタイルを使用すると、複数のズームレベルで、地図全体の 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 グリッドとしてレンダリングされます。タイルレイヤの画像を作成する場合は、サポートするズームレベルごとに、タイルごとに 256 x 256 のポイント画像を新たに作成する必要があります。

タイルレイヤの追加

  1. GMSURLTileLayer オブジェクト、または GMSTileLayer / GMSSyncTileLayer のカスタム サブクラスをインスタンス化します。
  2. 必要に応じて zIndex プロパティを変更し、他のタイルレイヤとの相対的な位置を調整します。
  3. 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 を返すと、この位置にタイルがないことを示します。

GMSGMSTileLayer を使用して 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 として提供する

GMSSyncTileLayerGMSTileLayer は、サブクラス化するように設計された抽象クラスです。これらのクラスを使用して、タイルを 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];