É possível adicionar imagens sobre o mapa como uma camada de blocos. As camadas de blocos são colocadas sobre um bloco de mapa com um nível específico de zoom. Com blocos suficientes, você pode complementar os dados de mapa do Google para todo o mapa, em diversos níveis de zoom.
Introdução
As camadas de blocos (às vezes chamadas de sobreposições de blocos) permitem sobrepor
imagens sobre os blocos de mapa básico do Google. É uma forma excelente de adicionar dados, como pontos de interesse ou informações sobre o trânsito, e imagens locais ao seu app. Quando combinadas com o tipo de mapa kGMSTypeNone
, as camadas de blocos permitem substituir eficazmente os dados do mapa básico do Google pelos seus próprios dados.
As camadas de blocos são úteis para adicionar uma grande quantidade de imagens ao mapa, cobrindo normalmente áreas geográficas amplas. Em comparação, as sobreposições de solo são úteis para fixar uma única imagem em um ponto do mapa.
Coordenadas de bloco
A Maps API divide as imagens em cada nível de zoom em um conjunto de blocos de mapa quadrados, organizados em uma grade ordenada. Quando um mapa rola para uma nova localização ou para um novo nível de zoom, a API Maps determina quais blocos são necessários e os converte em um conjunto de blocos a recuperar.
Para a implementação da projeção Mercator no Google, o bloco com a coordenada (0,0) está sempre no canto noroeste do mapa, com os valores de x
aumentando de oeste para leste e os valores de y
aumentando de norte para sul.
Os blocos são indexados usando coordenadas x,y
dessa origem. Por exemplo, no
nível de zoom 2, quando a Terra está dividida em 16 blocos, cada bloco pode ser
referenciado por um par de x,y
exclusivo:
Cada bloco de mapa é um quadrado de 256x256 pontos. No nível de zoom 0, o mundo inteiro é renderizado em um único bloco. Cada nível de zoom aumenta a ampliação por um fator de dois. Portanto, no nível de zoom 1, o mapa é renderizado como uma grade de blocos 2x2, ou uma grade 4x4 no nível de zoom 2, uma grade 8x8 no nível de zoom 3 e assim por diante. Para criar imagens para uma camada de blocos, é preciso criar uma nova imagem de 256x256 pontos para cada bloco em cada nível de zoom que você pretende oferecer.
Adicionar uma camada de blocos
- Instancie um objeto
GMSURLTileLayer
ou uma subclasse personalizada deGMSTileLayer
ouGMSSyncTileLayer
. - Opcionalmente, modifique a propriedade
zIndex
para ajustar a posição dela em relação a outras camadas de blocos. - Atribua o objeto
GMSTileLayer
ao mapa definindo a propriedademap
.
O SDK do Maps para iOS oferece três classes que podem ser usadas para
implementar uma camada de blocos. Em cada classe, é necessário definir como acessar
o bloco de mapa correto para um determinado conjunto de coordenadas {x,y,zoom}
. As opções disponíveis são estas:
- Subclasse
GMSSyncTileLayer
, fornecendo a implementação detileForX:y:zoom
que retorna instâncias deUIImage
. - Subclasse
GMSTileLayer
, que fornece a implementação do método assíncronorequestTileForX:y:zoom
, que depois chama de volta com uma imagem de bloco. - Use a classe atual,
GMSURLTileLayer
, para buscar blocos automaticamente de URLs, fornecendo o blocoGMSTileURLConstructor
.GMSURLTileLayer
é uma classe concreta que não permite a criação de subclasses.
No caso de subclassificação de GMSSyncTileLayer
ou GMSTileLayer
, o fornecimento de um resultado de bloco nil
informa ao SDK do Maps para iOS que os dados não estão disponíveis no momento, mas podem estar disponíveis no futuro. Como alternativa,
retorne kGMSTileLayerNoTile
para indicar que não há bloco nesse
local.
Para GMSURLTileLayer
, retornar nil
do GMSTileURLConstructor
indica que não há bloco nesse local.
Usar GMSURLTileLayer para buscar blocos em URLs
O GMSURLTileLayer
não exige a criação de subclasses, mas é necessário
implementar o bloco GMSTileURLConstructor
. O código abaixo mostra como
usar GMSURLTileLayer
para mostrar a planta baixa de um edifício com vários andares.
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;
Subclasse GMSSyncTileLayer para servir blocos como um UIImage
GMSSyncTileLayer
e GMSTileLayer
são classes abstratas projetadas para serem
subclasses. Use essas classes para fornecer blocos como UIImage
. O exemplo abaixo mostra como renderizar uma imagem personalizada em alguns blocos do mapa criando uma subclasse de 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
Para adicionar a camada ao seu mapa, instancie o objeto e defina sua propriedade de mapa.
Swift
let layer = TestTileLayer() layer.map = mapView
Objective-C
GMSTileLayer *layer = [[TestTileLayer alloc] init]; layer.map = mapView;
Blocos de DPI alto para dispositivos Retina
É possível usar imagens com DPI alto com GMSSyncTileLayer
ou GMSURLTileLayer
definindo o tileSize
como 512.
A propriedade tileSize
indica o número de pixels preferencial para exibição das imagens de bloco. O padrão é 256, a dimensão de um bloco do Google Maps em um dispositivo não Retina.
Se você está exibindo arquivos com DPI normal em um dispositivo de DPI alto, é possível aumentar o dimensionamento das
imagens definindo tileSize
como 512. Observe que o aumento do dimensionamento das imagens pode reduzir
a qualidade, principalmente para linhas finas ou texto. Para obter os melhores resultados, corresponda o
tileSize
e o DPI da imagem à tela. Os mapas mostrados em um dispositivo Retina
têm a melhor aparência quando exibem imagens de DPI alto com um tileSize
de 512.
Já os mapas mostrados em um dispositivo não Retina têm uma boa aparência com imagens normais
e o tileSize
padrão de 256.
Limpar blocos desatualizados
Se os blocos fornecidos pela camada ficarem "desatualizados", chame o método
clearTileCache
na camada para forçar uma atualização. Isso vai
recarregar todos os blocos dessa camada.
Swift
layer.clearTileCache()
Objective-C
[layer clearTileCache];