图块图层

请选择平台: Android iOS JavaScript

您可以将图片作为图块图层添加在地图上。图块图层会放置在特定缩放级别的地图图块之上。如果您有足够的图块,则可以在多个缩放级别为整个地图补充 Google 的地图数据。

简介

借助图块图层(有时称为图块叠加层),您可以在 Google 的基本地图图块上叠加图像。这是向应用添加数据(例如地图注点或交通信息)和本地图像的绝佳方式。与 kGMSTypeNone 地图类型搭配使用时,图块图层可让您有效地将 Google 的基本地图数据替换为您自己的数据。

如果您要为地图添加大量图像(通常覆盖大片地域),就需要使用图块图层。而如果想将单个图片固定在地图上的某一点,则适合使用地面叠加层

图块坐标

Maps API 将各缩放级别的图像分解成一组以有序网格形式排列的方形地图图块。当地图滚动至新位置,或者切换到新的缩放级别时,Maps API 会确定需要哪些图块,并将该信息转换为需要检索的一组图块。

为了便于 Google 实现墨卡托投影法,坐标为 (0,0) 的图块始终位于地图的西北角,x 值从西向东增加,y 值从北向南增加。系统使用基于该原点的 x,y 坐标为图块建立索引。例如,缩放级别为 2 时,地球分成 16 个图块,每个图块都可通过唯一的 x,y 来定位。

分为四行和四列图块的世界地图。

每个地图图块都是一个256x256的正方形点阵。缩放级别为 0 时,整个世界使用单个图块渲染。每个缩放级别都会使放大倍率增加一倍。因此,缩放级别为 1 时,地图将渲染为一个 2x2 图块网格;缩放级别为 2 时,渲染为一个 4x4 网格;缩放级别为 3 时,渲染为一个 8x8 网格,依此类推。如果您要为图块图层创建图片,则需要为您希望支持的每个缩放级别的每个图块创建一个新的 256x256 像素图片。

添加图块图层

  1. 实例化 GMSURLTileLayer 对象,或 GMSTileLayerGMSSyncTileLayer 的自定义子类。
  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
      

要将图层添加到地图,请实例化对象并设置其地图属性。

Swift

let layer = TestTileLayer()
layer.map = mapView
      

Objective-C

GMSTileLayer *layer = [[TestTileLayer alloc] init];
layer.map = mapView;
      

用于Retina设备的高DPI图块

您可以将 tileSize 设置为 512,以便在 GMSSyncTileLayerGMSURLTileLayer 中使用高 DPI 图片。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];