letfloor=1// Implement GMSTileURLConstructor// Returns a Tile based on the x,y,zoom coordinates, and the requested floorleturls:GMSTileURLConstructor={(x,y,zoom)inleturl="https://www.example.com/floorplans/L\(floor)_\(zoom)_\(x)_\(y).png"returnURL(string:url)}// Create the GMSTileLayerletlayer=GMSURLTileLayer(urlConstructor:urls)// Display on the map at a specific zIndexlayer.zIndex=100layer.map=mapView
Objective-C
NSIntegerfloor=1;// Create the GMSTileLayerGMSURLTileLayer*layer=[GMSURLTileLayertileLayerWithURLConstructor:^NSURL*_Nullable(NSUIntegerx,NSUIntegery,NSUIntegerzoom){NSString*url=[NSStringstringWithFormat:@"https://www.example.com/floorplans/L%ld_%lu_%lu_%lu.png",(long)floor,(unsignedlong)zoom,(unsignedlong)x,(unsignedlong)y];return[NSURLURLWithString:url];}];// Display on the map at a specific zIndexlayer.zIndex=100;layer.map=mapView;
classTestTileLayer:GMSSyncTileLayer{overridefunctileFor(x:UInt,y:UInt,zoom:UInt)->UIImage?{// On every odd tile, render an image.if(x%2==1){returnUIImage(named:"australia")}else{returnkGMSTileLayerNoTile}}}
Objective-C
@interfaceTestTileLayer : GMSSyncTileLayer@end@implementationTestTileLayer-(UIImage*)tileForX:(NSUInteger)xy:(NSUInteger)yzoom:(NSUInteger)zoom{// On every odd tile, render an image.if(x%2==1){return[UIImageimageNamed:@"australia"];}else{returnkGMSTileLayerNoTile;}}@end
[null,null,["最后更新时间 (UTC):2025-08-31。"],[[["\u003cp\u003eTile layers allow you to overlay images on top of Google Maps base map tiles to add custom data or imagery.\u003c/p\u003e\n"],["\u003cp\u003eTile layers are organized in a grid system, with each tile representing a square portion of the map at a specific zoom level.\u003c/p\u003e\n"],["\u003cp\u003eYou can create tile layers using \u003ccode\u003eGMSURLTileLayer\u003c/code\u003e to fetch tiles from URLs or by subclassing \u003ccode\u003eGMSSyncTileLayer\u003c/code\u003e or \u003ccode\u003eGMSTileLayer\u003c/code\u003e to provide tile images directly.\u003c/p\u003e\n"],["\u003cp\u003eUse a \u003ccode\u003etileSize\u003c/code\u003e of 512 for high DPI tiles on Retina devices for optimal visual quality.\u003c/p\u003e\n"],["\u003cp\u003eCall \u003ccode\u003eclearTileCache\u003c/code\u003e to refresh stale or outdated tile data.\u003c/p\u003e\n"]]],[],null,["Select platform: [Android](/maps/documentation/android-sdk/tileoverlay \"View this page for the Android platform docs.\") [iOS](/maps/documentation/ios-sdk/tiles \"View this page for the iOS platform docs.\") [JavaScript](/maps/documentation/javascript/customoverlays \"View this page for the JavaScript platform docs.\")\n\n\u003cbr /\u003e\n\nYou can add images on top of your map as a Tile Layer. Tile Layers are\nplaced overtop of a map tile at a specific zoom level. With enough tiles, you\ncan supplement Google's map data for the entire map, at multiple zoom levels.\n\nIntroduction\n\nTile layers, sometimes referred to as Tile Overlays, let you superimpose\nimages on top of Google's base map tiles. Use this feature to add data,\nsuch as points of interest or traffic information, and local imagery to\nyour app. When combined with the `kGMSTypeNone` map type,\ntile layers effectively let you replace Google's base map data with your own.\n\nTile layers are useful when you want to add extensive imagery, typically\ncovering large geographical areas, to the map. By contrast, [ground\noverlays](/maps/documentation/ios-sdk/overlays) are useful when you want to fix a single image at one\npoint on the map.\n\nTile coordinates\n\nThe Maps API breaks up imagery at each zoom level into a set of square map\ntiles, which are arranged in an ordered grid. When a map scrolls to\na new location, or to a new zoom level, the Maps API determines which tiles\nare needed, and translates that into a set of tiles to retrieve.\n\nIn the Google implementation of the Mercator projection, the tile with\ncoordinate (0,0) is always at the northwest corner of the map, with `x` values\nincreasing from west to east and `y` values increasing from north to south.\nTiles are indexed using `x,y` coordinates from that origin. For example, at\nzoom level 2, when the earth is divided up into 16 tiles, each tile can be\nreferenced by a unique `x,y` pair:\n\nEach map tile is a 256x256 point square. At zoom level 0, the entire world is\nrendered in a single tile. Each zoom level increases the magnification by a\nfactor of two. So, for example, at zoom level 1 the map is rendered as a 2x2\ngrid of tiles, at zoom level 2 as a 4x4 grid , and at zoom level 3 as an 8x8\ngrid. To create images for a tile layer, create a\n256x256 point image for each tile at each zoom level that you want to support.\n\nAdd a Tile Layer\n\n1. Instantiate a [`GMSURLTileLayer`](/maps/documentation/ios-sdk/reference/objc/Classes/GMSURLTileLayer) object, or a custom subclass of [`GMSTileLayer`](/maps/documentation/ios-sdk/reference/objc/Classes/GMSTileLayer) or [`GMSSyncTileLayer`](/maps/documentation/ios-sdk/reference/objc/Classes/GMSSyncTileLayer).\n2. Optionally modify the `zIndex` property to adjust its position in relation to other tile layers.\n3. Assign the `GMSTileLayer` object to the map by setting its `map` property.\n\nThe Maps SDK for iOS provides three classes that can be used to\nimplement a tile layer. With each class, you will need to define how to fetch\nthe correct map tile for a given set of `{x,y,zoom}` coordinates. The\navailable options are:\n\n- Subclass `GMSSyncTileLayer`, providing the implementation of `tileForX:y:zoom` that returns `UIImage` instances.\n- Subclass `GMSTileLayer`, providing the implementation of the asynchronous method `requestTileForX:y:zoom` that later calls back with a tile image.\n- Use the existing class, `GMSURLTileLayer`, to fetch tiles automatically from URLs, providing the `GMSTileURLConstructor` block. `GMSURLTileLayer` is a concrete class that cannot be subclassed.\n\nIn the case of subclassing `GMSSyncTileLayer` or `GMSTileLayer`, providing a\n`nil` tile result will tell the Maps SDK for iOS that data is\nunavailable but that it may be available in the future. Alternatively,\nreturn `kGMSTileLayerNoTile` to indicate that there is no tile at this\nlocation.\n\nFor `GMSURLTileLayer`, returning `nil` from the `GMSTileURLConstructor` will\nindicate that there is no tile at this location.\n\nUse GMSURLTileLayer to fetch tiles from URLs\n\nThe `GMSURLTileLayer` does not require subclassing, but you will have to\nimplement the `GMSTileURLConstructor` block. The below code shows how to\nuse `GMSURLTileLayer` to display the floor plan of a multistory building.\n\n\nSwift \n\n```swift\nlet floor = 1\n\n// Implement GMSTileURLConstructor\n// Returns a Tile based on the x,y,zoom coordinates, and the requested floor\nlet urls: GMSTileURLConstructor = { (x, y, zoom) in\n let url = \"https://www.example.com/floorplans/L\\(floor)_\\(zoom)_\\(x)_\\(y).png\"\n return URL(string: url)\n}\n\n// Create the GMSTileLayer\nlet layer = GMSURLTileLayer(urlConstructor: urls)\n\n// Display on the map at a specific zIndex\nlayer.zIndex = 100\nlayer.map = mapView\n \n```\n\nObjective-C \n\n```objective-c\nNSInteger floor = 1;\n\n// Create the GMSTileLayer\nGMSURLTileLayer *layer = [GMSURLTileLayer tileLayerWithURLConstructor:^NSURL * _Nullable(NSUInteger x, NSUInteger y, NSUInteger zoom) {\n NSString *url = [NSString stringWithFormat:@\"https://www.example.com/floorplans/L%ld_%lu_%lu_%lu.png\",\n (long)floor, (unsigned long)zoom, (unsigned long)x, (unsigned long)y];\n return [NSURL URLWithString:url];\n}];\n\n// Display on the map at a specific zIndex\nlayer.zIndex = 100;\nlayer.map = mapView;\n \n```\n\n\u003cbr /\u003e\n\nSubclass GMSSyncTileLayer to serve tiles as a UIImage\n\nThe `GMSSyncTileLayer` and `GMSTileLayer` are abstract classes designed to be\nsubclassed. You can use these classes to serve tiles as `UIImage`'s. The below\nexample shows how to render a custom image over some of the tiles on the map\nby subclassing `GMSSyncTileLayer`.\n\n\nSwift \n\n```swift\nclass TestTileLayer: GMSSyncTileLayer {\n override func tileFor(x: UInt, y: UInt, zoom: UInt) -\u003e UIImage? {\n // On every odd tile, render an image.\n if (x % 2 == 1) {\n return UIImage(named: \"australia\")\n } else {\n return kGMSTileLayerNoTile\n }\n }\n}\n\n \n```\n\nObjective-C \n\n```objective-c\n@interface TestTileLayer : GMSSyncTileLayer\n@end\n\n@implementation TestTileLayer\n\n- (UIImage *)tileForX:(NSUInteger)x y:(NSUInteger)y zoom:(NSUInteger)zoom {\n // On every odd tile, render an image.\n if (x % 2 == 1) {\n return [UIImage imageNamed:@\"australia\"];\n } else {\n return kGMSTileLayerNoTile;\n }\n}\n\n@end\n \n```\n\n\u003cbr /\u003e\n\nTo add the layer to your map, instantiate the object and set its map property.\n\n\nSwift \n\n```swift\nlet layer = TestTileLayer()\nlayer.map = mapView\n \n```\n\nObjective-C \n\n```objective-c\nGMSTileLayer *layer = [[TestTileLayer alloc] init];\nlayer.map = mapView;\n \n```\n\n\u003cbr /\u003e\n\nHigh DPI Tiles for Retina devices\n\nYou can use high DPI images with either [`GMSSyncTileLayer`](/maps/documentation/ios-sdk/reference/objc/Classes/GMSSyncTileLayer)\nor [`GMSURLTileLayer`](/maps/documentation/ios-sdk/reference/objc/Classes/GMSURLTileLayer) by setting the `tileSize` to 512.\nThe `tileSize` property indicates the number of pixels that the returned tile\nimages will prefer to display as; this defaults to 256 --- the dimension\nof a Google Maps tile on a non-Retina device.\n\nIf you are displaying normal DPI tiles on a high DPI device you can scale the\nimages up by setting `tileSize` to 512. Note that upscaling images may reduce\nimage quality, especially for fine lines or text. For best results, match the\n`tileSize` and image DPI to the display. Maps shown on a Retina device will\nlook their best when displaying high DPI images with a `tileSize` of 512;\nwhile maps shown on a non-Retina device will look great with normal images\nand the default `tileSize` of 256.\n| **Note:** Values less than 256 are not recommended for Retina devices.\n\nClear stale tiles\n\nIf the tiles provided by the layer become 'stale', then the method\n`clearTileCache` should be called on the layer to force a refresh. This will\ncause all of the tiles on this layer to be reloaded.\n\n\nSwift \n\n```swift\nlayer.clearTileCache()\n \n```\n\nObjective-C \n\n```objective-c\n[layer clearTileCache];\n \n```\n\n\u003cbr /\u003e"]]