É possível adicionar imagens sobre o mapa como uma camada de blocos. Essas camadas são colocadas sobre um bloco de mapa em um nível de zoom específico. Com blocos suficientes, você pode complementar os dados do mapa do Google para o mapa inteiro, em vários níveis de zoom.
Introdução
As camadas de blocos (também chamadas de sobreposições de blocos) permitem sobrepor imagens nos blocos do mapa básico do Google. Essa é uma excelente forma de adicionar ao app dados, como pontos de interesse ou informações de trânsito, e imagens locais. Quando combinadas com o tipo de mapa kGMSTypeNone
, as camadas de blocos permitem substituir os dados do mapa básico do Google pelos seus próprios.
As camadas de blocos são úteis quando você quer adicionar várias imagens ao mapa, geralmente cobrindo grandes áreas geográficas. Por outro lado, as sobreposições de solo são úteis quando você quer corrigir uma única imagem em um ponto do mapa.
Coordenadas de bloco
A API Maps divide as imagens de cada nível de zoom em um conjunto de blocos de mapa quadrados, organizados em uma grade ordenada. Quando a rolagem é usada para mostrar um novo local do mapa ou o nível de zoom é alterado, a API Maps determina quais blocos são necessários e converte essa informação em um conjunto de blocos a recuperar.
Para a projeção de Mercator do Google, o bloco com coordenadas (0,0) fica sempre no canto noroeste do mapa, com valores x
aumentando de oeste para leste e valores 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 de 2 x 2 ou uma grade de 4 x 4 no nível de zoom 2, uma grade 8 x 8 no nível de zoom 3 e assim por diante. Se você estiver criando imagens para uma camada de blocos, será necessário gerar uma nova imagem de 256 x 256 pontos para cada bloco em todos os níveis de zoom que você pretende oferecer.
Como adicionar uma camada de blocos
- Instancie um objeto
GMSURLTileLayer
ou uma subclasse personalizada deGMSTileLayer
/GMSSyncTileLayer
. - Se quiser, modifique a propriedade
zIndex
para ajustar a posição 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 buscar o bloco de mapa correto para um conjunto específico 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
, fornecendo a implementação do método assíncronorequestTileForX:y:zoom
, que depois retorna uma imagem de bloco. - Use a classe existente,
GMSURLTileLayer
, para buscar blocos automaticamente em URLs, fornecendo o blocoGMSTileURLConstructor
.GMSURLTileLayer
é uma classe concreta que não pode ser transformada em subclasses.
No caso da subclasse GMSSyncTileLayer
ou GMSTileLayer
, o envio de um resultado de bloco nil
informa ao SDK do Maps para iOS que os dados estão indisponíveis no momento, mas podem ser disponibilizados no futuro. Como alternativa,
retorne kGMSTileLayerNoTile
para indicar que não há um bloco nesse
local.
Para GMSURLTileLayer
, retornar nil
do GMSTileURLConstructor
vai
indicar que não há um bloco nesse local.
Usar "GMSURLTileLayer" para buscar blocos de URLs
O GMSURLTileLayer
não requer subclasses, mas você precisa implementar o bloco GMSTileURLConstructor
. O código abaixo mostra como usar GMSURLTileLayer
para mostrar a planta baixa de um edifício de 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;
Crie uma subclasse de GMSSyncTileLayer
para servir Blocos como um UIImage
.
GMSSyncTileLayer
e GMSTileLayer
são classes abstratas projetadas para serem
subclasses. Você pode usar essas classes para exibir blocos como UIImage
s. O exemplo abaixo mostra como renderizar uma imagem personalizada em alguns dos blocos no mapa criando subclasses 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 de DPI alto com GMSSyncTileLayer
ou GMSURLTileLayer
, definindo tileSize
como 512.
A propriedade tileSize
indica o número de pixels que as imagens de bloco retornadas preferem exibir. O padrão é 256, a dimensão de um bloco do Google Maps em um dispositivo que não é Retina.
Se você está exibindo blocos com DPI normal em um dispositivo de DPI alto, é possível aumentar as
imagens definindo tileSize
como 512. O aumento do dimensionamento das imagens pode reduzir
a qualidade, especialmente para linhas finas ou texto. Para melhores resultados, combine o
tileSize
e o DPI da imagem com a tela. Os mapas mostrados em um dispositivo com tela Retina ficam melhores ao mostrar imagens de DPI alto com um tileSize
de 512. Já os mapas mostrados em dispositivos não Retina têm uma ótima aparência com imagens normais e com o tileSize
padrão, que é 256.
Limpeza de blocos desatualizados
Se os blocos fornecidos pela camada ficarem "desatualizados", o método
clearTileCache
vai precisar ser chamado na camada para forçar uma atualização. Isso fará com que todos os blocos dessa camada sejam recarregados.
Swift
layer.clearTileCache()
Objective-C
[layer clearTileCache];