圖塊圖層

透過集合功能整理內容 你可以依據偏好儲存及分類內容。
選取平台: Android iOS JavaScript

You can add images on top of your map as a Tile Layer. 圖塊圖層位於特定縮放等級的地圖圖塊上方。如果圖塊數量夠多,您就可以在多種縮放等級中,為整個地圖補充 Google 的地圖資料。

引言

圖塊圖層 (有時稱為「圖塊疊加層」) 可讓您在 Google #39 基本地圖圖塊上方疊加圖片。這是在應用程式中新增資料 (例如搜尋點或路況資訊) 和本機圖像的好方法。與 kGMSTypeNone 地圖類型搭配使用時,圖塊圖層可讓您以自己的資料取代 Google 的基本地圖資料。

當您想在地圖上新增大量圖像 (通常是涵蓋大範圍的地理區域) 時,圖塊圖層就非常實用。相反地,如果您想修正地圖上某個時間點的單一圖片,區域疊加層就非常實用。

圖塊座標

Maps API 會將各個縮放等級的圖像的圖像分解成一組正方形的圖塊,並排成有序的格線。地圖捲動至新位置或新的縮放等級時,Maps API 會判斷需要哪些圖塊,並將其轉譯成一組圖塊。

在 Google 的麥卡托投影實作中,座標 (0,0) 的圖塊一律位於地圖的西北角,同時 x 值會從西到東逐漸增加,y 值則從北到南逐漸增加。圖塊是使用從該原點開始的 x,y 座標來建立索引。舉例來說,縮放等級為 2 時,如果將地球區分成 16 個圖塊,每個圖塊都可使用不重複的 x,y 組合參照:

Each map tile is a 256x256 point square. 縮放等級為 0 時,全世界將會以單一圖塊顯示。每個縮放等級皆可放大兩倍。因此,縮放等級為 1 時,地圖會算成 2x2 的圖塊,或 2x4 的縮放等級,縮放等級為 3 的 8x8 格線,依此類推。如要為圖塊圖層建立圖片,您必須針對要支援的每個縮放等級,為每個圖塊建立新的 256x256 點圖片。

新增資訊方塊圖層

  1. GMSURLTileLayer 物件執行個體化或 GMSTileLayer/GMSSyncTileLayer 的自訂子類別。
  2. 視需要修改 zIndex 屬性,以調整相對於其他圖塊圖層的位置。
  3. 設定其 map 屬性,將 GMSTileLayer 物件指派給地圖。

Maps SDK for iOS 提供三個類別,可用於實作圖塊圖層。每個類別都必須定義您針對一組 {x,y,zoom} 座標擷取正確的地圖圖塊。可用的選項如下:

  • 子類別 GMSSyncTileLayer,提供傳回 UIImage 例項的 tileForX:y:zoom 實作。
  • 子類別 GMSTileLayer,提供非同步方法 requestTileForX:y:zoom 的實作,後來以圖塊圖片傳回。
  • 使用現有類別 GMSURLTileLayer 從網址自動擷取圖塊,並提供 GMSTileURLConstructor 區塊。GMSURLTileLayer 是無法加入子類別的具體類別。

建立 GMSSyncTileLayerGMSTileLayer 子類別時,提供 nil 圖塊結果會告知 Maps SDK for iOS,說明資料目前無法使用,但日後可能提供。或者,傳回 kGMSTileLayerNoTile,表示這個位置沒有設定方塊。

GMSURLTileLayer 中,從 GMSTileURLConstructor 傳回 nil 表示此位置沒有設定方塊。

使用「GMSURLTileLayer」從網址擷取資訊方塊

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's 的圖塊。以下範例說明如何將 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
      

To add the layer to your map, instantiate the object and set its map property.

Swift

let layer = TestTileLayer()
layer.map = mapView
      

Objective-C

GMSTileLayer *layer = [[TestTileLayer alloc] init];
layer.map = mapView;
      

High DPI Tiles for Retina devices

tileSize 設為 512,即可將高 DPI 圖片與 GMSSyncTileLayerGMSURLTileLayer 搭配使用。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];