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 方格,以此類推。如果您要為圖塊圖層建立圖片,則必須針對每個要支援的縮放等級,為每個圖塊建立新的 256x256 點圖片。
Add a Tile Layer
- 建立
GMSURLTileLayer
物件,或GMSTileLayer
或GMSSyncTileLayer
的自訂子類別。 - 您可以視需要修改
zIndex
屬性,調整其相對於其他圖塊圖層的位置。 - 設定
GMSTileLayer
物件的map
屬性,將物件指派給地圖。
Maps SDK for iOS 提供三個可用於實作圖塊圖層的類別。您必須為每個類別定義如何針對特定 {x,y,zoom}
座標集合擷取正確的地圖圖塊。可用的選項如下:
- 子類別
GMSSyncTileLayer
,提供tileForX:y:zoom
的實作項目,可傳回UIImage
例項。 - 建立
GMSTileLayer
子類別,提供非同步方法requestTileForX:y:zoom
的實作項目,以便稍後以圖塊圖片回呼。 - 使用現有的
GMSURLTileLayer
類別,自動從網址擷取圖塊,提供GMSTileURLConstructor
區塊。GMSURLTileLayer
是無法再細分的具體類別。
如果是為 GMSSyncTileLayer
或 GMSTileLayer
建立子類別,提供 nil
圖塊結果會告知 Maps SDK for iOS,目前無法取得資料,但日後可能會提供。或者,您也可以傳回 kGMSTileLayerNoTile
,表示這個位置沒有方塊。
對於 GMSURLTileLayer
,從 GMSTileURLConstructor
傳回 nil
表示這個位置沒有任何資訊方塊。
Use GMSURLTileLayer to fetch tiles from URLs
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;
Subclass GMSSyncTileLayer to serve tiles as a 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 裝置上顯示的地圖,如果顯示高 DPI 圖片且 tileSize
為 512,會呈現最佳效果;在非 Retina 裝置上顯示的地圖,如果顯示一般圖片且預設 tileSize
為 256,會呈現最佳效果。
清除過時的圖塊
如果圖層提供的圖塊變成「過時」,則應在圖層上呼叫 clearTileCache
方法,強制重新整理。這會使系統重新載入此圖層的所有圖塊。
Swift
layer.clearTileCache()
Objective-C
[layer clearTileCache];