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 的圖塊,或 2x2 的縮放等級為 2、以 8x8 的縮放等級,在縮放等級 3 為算繪,依此類推。如果要為圖塊圖層建立圖片,您必須針對要支援的每個縮放等級,為每個圖塊建立新的 256x256 點圖片。
新增資訊方塊圖層
- 將
GMSURLTileLayer
物件或GMSTileLayer
/GMSSyncTileLayer
的自訂子類別執行個體化。 - 視需要修改
zIndex
屬性,以調整相對於其他圖塊圖層的位置。 - 設定其
map
屬性,將GMSTileLayer
物件指派給地圖。
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];