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 點圖片。
新增圖塊圖層
- 將
GMSURLTileLayer
物件或GMSTileLayer
/GMSSyncTileLayer
的自訂子類別執行個體化。 - 視需要修改
zIndex
屬性,以便調整相對於其他圖塊圖層的位置。 - 設定
GMSTileLayer
物件的map
屬性,將物件指派給地圖。
Maps SDK for iOS 提供三種類別,可用來導入圖塊圖層。您必須針對每個類別,定義如何為指定的 {x,y,zoom}
座標組合擷取正確的地圖圖塊。可用選項如下:
- 子類別
GMSSyncTileLayer
,提供可傳回UIImage
例項的tileForX:y:zoom
實作。 - 子類別
GMSTileLayer
,提供實作非同步方法requestTileForX:y:zoom
,之後使用圖塊圖片回呼的方法。 - 使用現有類別
GMSURLTileLayer
從網址自動擷取資訊方塊,提供GMSTileURLConstructor
區塊。GMSURLTileLayer
是無法設為子類別的具體類別。
如果是將 GMSSyncTileLayer
或 GMSTileLayer
設為子類別,提供 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
使用
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
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 圖片與 GMSSyncTileLayer
或 GMSURLTileLayer
搭配使用。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];