圖塊圖層

選取平台: Android iOS JavaScript

You can add images on top of your map as a Tile Layer. 圖塊圖層會放在特定縮放等級的地圖圖塊上方。有了足夠的圖塊,您就能以多種縮放等級補充整個地圖中的 Google 地圖資料。

簡介

圖塊圖層 (有時稱為「圖塊疊加層」) 可讓您將圖片疊加在 Google 基本地圖圖塊上方。這是在應用程式中加入資料 (例如搜尋點或路況資訊) 和當地圖像的好方法。與 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 的圖塊方格,縮放等級為 2 時則為 4x4 方格;縮放等級為 3 的 8x8 方格,以此類推。如果要建立圖塊圖層的圖片,您必須針對每個要支援的縮放等級,為每個圖塊建立新的 256x256 點圖片。

新增圖塊圖層

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

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 的形式提供資訊方塊。以下範例說明如何將 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

如要將高 DPI 圖片與 GMSSyncTileLayerGMSURLTileLayer 搭配使用,請將 tileSize 設為 512。tileSize 屬性表示傳回的圖塊圖片偏好顯示的像素數量;預設值為 256,也就是非 Retina 裝置上的 Google 地圖圖塊尺寸。

如要在高 DPI 裝置上顯示一般 DPI 圖塊,可以將 tileSize 設為 512,藉此調整圖片大小。請注意,放大圖片可能會降低圖片品質,尤其是對於細線或文字而言,更是如此。為獲得最佳結果,請讓畫面顯示 tileSize 和圖片 DPI。tileSize 為 512 的高 DPI 圖片時,在 Retina 裝置上顯示的地圖可呈現最佳效果;在非 Retina 裝置上,顯示的地圖在一般圖片和 256 的預設 tileSize 上看起來都非常好。

正在清除過時的圖塊

如果圖層提供的資訊方塊「過時」,則圖層應呼叫 clearTileCache 方法,以強制重新整理。這會導致系統重新載入這個圖層的所有圖塊。

Swift

layer.clearTileCache()
      

Objective-C

[layer clearTileCache];