Uma sobreposição de blocos, geralmente chamada de camada de blocos, é uma coleção de imagens que aparece sobre os blocos do mapa de base.
Exemplos de código
O repositório ApiDemos (link em inglês) no GitHub inclui um exemplo que demonstra a sobreposição de blocos:
- TileOverlayDemoActivity – Java: recursos de sobreposição de blocos em Java
- TileCoordinateDemoActivity – Java: o sistema de coordenadas usado para sobreposições de blocos em Java
- TileOverlayDemoActivity – Kotlin: recursos de sobreposição de blocos em Kotlin
- TileCoordinateDemoActivity – Kotlin: o sistema de coordenadas usado para sobreposições de blocos em Kotlin
Introdução
Uma TileOverlay
define um conjunto de imagens adicionadas sobre os blocos do mapa de base.
É necessário fornecer os blocos para cada nível de zoom que você pretende oferecer. Se você tem blocos suficientes em vários níveis de zoom, pode complementar os dados do mapa do Google para o mapa inteiro.
As sobreposições de blocos são úteis para adicionar várias imagens ao mapa e cobrir áreas geográficas amplas. Enquanto isso, as sobreposições de solo são uma ótima maneira de corrigir uma única imagem em uma área do mapa.
As sobreposições de blocos transparentes podem ser usadas para adicionar recursos ao mapa, definindo de forma programática um fator de transparência na sobreposição de blocos ou fornecendo imagens de blocos transparentes.
Coordenadas e níveis de zoom de blocos
A API Google Maps divide as imagens de cada nível de zoom em um conjunto de blocos de mapa quadrados, organizados em uma grade. Quando um mapa muda para uma nova localização ou um novo nível de zoom, a API Maps determina quais blocos são necessários e converte essa informação em um conjunto de blocos a recuperar.
O bloco com as coordenadas (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 as coordenadas X, Y da origem em questão.
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. No nível 2, a grade é de 4 x 4. No nível 3, a grade é de 8 x 8, e assim por diante.
Por exemplo, no nível de zoom 2, o planeta é dividido em 16 blocos. Cada bloco pode ser referenciado por uma combinação exclusiva de X, Y e zoom:
Ao criar imagens para uma camada de blocos, é preciso gerar uma imagem para cada bloco em todos os níveis de zoom que você pretende oferecer. Ao exibir blocos, o Google Maps tenta exibir 256 dp (pixels independentes de dispositivo). Para dispositivos de alta resolução, recomendamos retornar blocos com dpi alto (512 x 512 px). Consulte a documentação para desenvolvedores Android se quiser informações sobre como oferecer compatibilidade com diferentes tamanhos e densidades de tela.
Observação: os níveis de zoom permitidos pela câmera dependem de vários fatores e não estão relacionados aos níveis de zoom aceitos pelos seus blocos.
-
GoogleMap.getMaxZoomLevel()
retorna o nível de zoom máximo disponível na posição atual da câmera. Esse valor considera o tipo de mapa usado no momento. Por exemplo, um mapa de satélite ou de terreno pode ter um nível de zoom máximo menor que os blocos do mapa de base. -
GoogleMap.getMinZoomLevel()
retorna o nível de zoom mínimo, que é o mesmo para todos os locais (ao contrário do nível de zoom máximo), mas pode variar entre dispositivos e tamanhos de mapa.
Adicionar uma sobreposição de blocos
A forma mais simples e comum de criar uma sobreposição de blocos é fornecer um URL apontando para a imagem de bloco relevante.
UrlTileProvider
é uma implementação parcial de TileProvider
que fornece blocos de imagem com base em um URL. Essa classe exige que todas as imagens tenham as mesmas dimensões.
É necessário implementar UrlTileProvider.getTileUrl()
, que aceita as coordenadas do bloco (X, Y, zoom) e retorna um URL que aponta para a imagem a ser usada no bloco. O método retorna "nulo" quando não existe um bloco para as coordenadas X, Y e zoom informadas. Um URL pode apontar para um recurso da Web, do Android ou um arquivo no disco local.
Configure um repositório de imagens de blocos em um servidor, definidas para todas as coordenadas X e Y e os níveis de zoom que você pretende oferecer. Depois, adicione a sobreposição de blocos:
- Defina um
UrlTileProvider
para fornecer as imagens de bloco. - Substitua
getTileUrl()
para construir o URL de cada imagem de bloco. - Forneça um objeto
TileOverlayOptions
com as opções relevantes: fadeIn
: booleano. Especifica se os blocos vão aparecer gradualmente. O valor padrão étrue
. Desative a exibição gradual para alternar rapidamente entre as sobreposições de blocos. Para informações sobre a relação entre transparência e exibição gradual, consulte a seção sobre transparência abaixo.tileProvider
: oTileProvider
que será usado na sobreposição.transparency
: ponto flutuante. Define um fator de transparência para imagens de bloco. O valor precisa estar no intervalo[0.0f, 1.0f]
, em que0.0f
significa totalmente opaco (padrão) e1.0f
significa totalmente transparente. Consulte na seção sobre transparência abaixo um exemplo de código e a relação entre transparência e exibição gradual.visible
: booleano. Especifica a visibilidade da sobreposição dos blocos. Uma sobreposição de blocos invisível (valorfalse
) não é desenhada no mapa, mas mantém todas as demais propriedades. O padrão étrue
.zIndex
: determina a ordem em que a sobreposição dos blocos será desenhada em relação a outras sobreposições, incluindo sobreposições de solo, círculos, polilinhas e polígonos. As sobreposições com um Z-index mais alto são desenhadas sobre aquelas que têm um Z-index mais baixo. A ordem das sobreposições que têm o mesmo Z-index é aleatória. O valor padrão do Z-index é 0. Os marcadores são sempre desenhados sobre as outras sobreposições, independentemente do Z-index delas.- Chame
GoogleMap.addTileOverlay()
para adicionar a sobreposição ao mapa.
Kotlin
private lateinit var map: GoogleMap var tileProvider: TileProvider = object : UrlTileProvider(256, 256) { override fun getTileUrl(x: Int, y: Int, zoom: Int): URL? { /* Define the URL pattern for the tile images */ val url = "http://my.image.server/images/$zoom/$x/$y.png" return if (!checkTileExists(x, y, zoom)) { null } else try { URL(url) } catch (e: MalformedURLException) { throw AssertionError(e) } } /* * Check that the tile server supports the requested x, y and zoom. * Complete this stub according to the tile range you support. * If you support a limited range of tiles at different zoom levels, then you * need to define the supported x, y range at each zoom level. */ private fun checkTileExists(x: Int, y: Int, zoom: Int): Boolean { val minZoom = 12 val maxZoom = 16 return zoom in minZoom..maxZoom } } val tileOverlay = map.addTileOverlay( TileOverlayOptions() .tileProvider(tileProvider) )
Java
private GoogleMap map; TileProvider tileProvider = new UrlTileProvider(256, 256) { @Override public URL getTileUrl(int x, int y, int zoom) { /* Define the URL pattern for the tile images */ String s = String.format("http://my.image.server/images/%d/%d/%d.png", zoom, x, y); if (!checkTileExists(x, y, zoom)) { return null; } try { return new URL(s); } catch (MalformedURLException e) { throw new AssertionError(e); } } /* * Check that the tile server supports the requested x, y and zoom. * Complete this stub according to the tile range you support. * If you support a limited range of tiles at different zoom levels, then you * need to define the supported x, y range at each zoom level. */ private boolean checkTileExists(int x, int y, int zoom) { int minZoom = 12; int maxZoom = 16; return (zoom >= minZoom && zoom <= maxZoom); } }; TileOverlay tileOverlay = map.addTileOverlay(new TileOverlayOptions() .tileProvider(tileProvider));
Para conferir um exemplo de UrlTileProvider
na prática, consulte TileOverlayDemoActivity
no exemplo de código que acompanha o SDK do Google Play Services.
Definir transparência para sobreposições de blocos
Pode ser útil sobrepor blocos transparentes no mapa para que os usuários consigam ler o mapa abaixo dos blocos sobrepostos. Faça isso fornecendo seus próprios blocos transparentes ou definindo programaticamente um fator de transparência da sobreposição de blocos.
O exemplo de código a seguir alterna a transparência da sobreposição de blocos entre 0.5f
e 0.0f
:
Kotlin
private var tileOverlayTransparent: TileOverlay? = null override fun onMapReady(map: GoogleMap) { tileOverlayTransparent = map.addTileOverlay( TileOverlayOptions() .tileProvider(object : UrlTileProvider(256, 256) { // ... }) .transparency(0.5f) ) } // Switch between 0.0f and 0.5f transparency. fun toggleTileOverlayTransparency() { tileOverlayTransparent?.let { it.transparency = 0.5f - it.transparency } }
Java
private TileOverlay tileOverlayTransparent; @Override public void onMapReady(GoogleMap map) { tileOverlayTransparent = map.addTileOverlay(new TileOverlayOptions() .tileProvider(new UrlTileProvider(256, 256) { // ... }) .transparency(0.5f)); } // Switch between 0.0f and 0.5f transparency. public void toggleTileOverlayTransparency() { if (tileOverlayTransparent != null) { tileOverlayTransparent.setTransparency(0.5f - tileOverlayTransparent.getTransparency()); } }
A transparência é implementada como multiplicador de canal alfa para imagens de blocos. Para definir a transparência de uma sobreposição de blocos, forneça um objeto TileOverlayOptions
com uma transparency
no intervalo [0.0f, 1.0f]
, conforme o exemplo acima. Um valor de 0.0f
significa que a sobreposição de blocos é totalmente opaca, e 1.0f
significa que ela é totalmente transparente. O valor padrão é 0.0f
(opaca).
É possível acessar a transparência da sobreposição de blocos chamando TileOverlay.getTransparency()
. Para mudá-la, chame TileOverlay.setTransparency()
.
Transparência, animação e exibição gradual
Não há animação quando a transparência é alterada. A opção de transparência opera junto com a fadeIn.
A exibição gradual oferece animação de transparência no carregamento do bloco. Se você definir um valor de transparência, os blocos serão mostrados de forma gradual, de totalmente transparentes até o valor definido. Se você mudar a transparência durante o aparecimento gradual, a animação vai continuar até a nova transparência desejada.
Remover uma sobreposição de blocos
É possível remover uma sobreposição de blocos com o método TileOverlay.remove()
.
Kotlin
tileOverlay?.remove()
Java
tileOverlay.remove();
Limpar blocos desatualizados
Se os blocos fornecidos pela sobreposição ficarem "desatualizados", chame clearTileCache()
para forçar uma atualização. Como resultado, todos os blocos da sobreposição serão atualizados. Por exemplo, se os blocos fornecidos pelo TileProvider
mudarem, chame clearTileCache()
depois, para garantir que os blocos anteriores não sejam mais renderizados.
Kotlin
tileOverlay?.clearTileCache()
Java
tileOverlay.clearTileCache();