Os mapas de calor são úteis para representar a distribuição e a densidade de pontos de dados em um mapa.
Introdução
A Biblioteca de utilitários do SDK do Maps para Android inclui um utilitário de mapa de calor usado para adicionar um ou mais mapas de calor a um mapa do Google no seu app.
Este vídeo fala sobre o uso de mapas de calor como uma alternativa aos marcadores quando os dados exigem um grande número de pontos de dados no mapa.
Os mapas de calor permitem que os visualizadores compreendam com mais facilidade a distribuição e a intensidade relativa de pontos de dados em um mapa. Em vez de colocar um marcador em cada localização, eles usam cores para representar a distribuição dos dados.
No exemplo abaixo, o vermelho representa as áreas de alta concentração de delegacias de polícia em Victoria, Austrália.
![Um mapa com mapa de calor mostrando a localização de delegacias de polícia](https://developers.google.cn/static/maps/documentation/android-sdk/images/utility-heatmap.png?authuser=6&hl=pt-br)
Se você ainda não configurou a biblioteca de utilitários do SDK do Maps para Android, siga o guia de configuração antes de ler o restante desta página.
Adicionar um mapa de calor simples
Para adicionar um mapa de calor ao mapa, é necessário um conjunto de dados com as coordenadas de cada localização de interesse. Primeiro, crie um HeatmapTileProvider
e passe a coleção de objetos LatLng
a ele. Depois, crie um novo TileOverlay
, transmitindo o provedor de blocos do mapa de calor e adicione a sobreposição de blocos ao mapa.
O utilitário fornece a classe HeatmapTileProvider
, que implementa a interface TileProvider
para fornecer as imagens de bloco do mapa de calor.
HeatmapTileProvider
aceita uma coleção de objetos LatLng
(ou objetos WeightedLatLng
, conforme descrito abaixo). Ela cria as imagens de bloco para os diversos níveis de zoom de acordo com as opções de raio, gradiente e opacidade especificadas. É possível alterar os valores padrão das opções.
Mais detalhes das etapas:
- Use
HeatmapTileProvider.Builder()
, transmitindo um conjunto de objetosLatLng
para adicionar um novoHeatmapTileProvider
. - Crie um novo objeto
TileOverlayOptions
com as opções relevantes, incluindo oHeatmapTileProvider
. - Chame
GoogleMap.addTileOverlay()
para adicionar a sobreposição ao mapa.
Kotlin
private fun addHeatMap() { var latLngs: List<LatLng?>? = null // Get the data: latitude/longitude positions of police stations. try { latLngs = readItems(R.raw.police_stations) } catch (e: JSONException) { Toast.makeText(context, "Problem reading list of locations.", Toast.LENGTH_LONG) .show() } // Create a heat map tile provider, passing it the latlngs of the police stations. val provider = HeatmapTileProvider.Builder() .data(latLngs) .build() // Add a tile overlay to the map, using the heat map tile provider. val overlay = map.addTileOverlay(TileOverlayOptions().tileProvider(provider)) } @Throws(JSONException::class) private fun readItems(@RawRes resource: Int): List<LatLng?> { val result: MutableList<LatLng?> = ArrayList() val inputStream = context.resources.openRawResource(resource) val json = Scanner(inputStream).useDelimiter("\\A").next() val array = JSONArray(json) for (i in 0 until array.length()) { val `object` = array.getJSONObject(i) val lat = `object`.getDouble("lat") val lng = `object`.getDouble("lng") result.add(LatLng(lat, lng)) } return result }
Java
private void addHeatMap() { List<LatLng> latLngs = null; // Get the data: latitude/longitude positions of police stations. try { latLngs = readItems(R.raw.police_stations); } catch (JSONException e) { Toast.makeText(context, "Problem reading list of locations.", Toast.LENGTH_LONG).show(); } // Create a heat map tile provider, passing it the latlngs of the police stations. HeatmapTileProvider provider = new HeatmapTileProvider.Builder() .data(latLngs) .build(); // Add a tile overlay to the map, using the heat map tile provider. TileOverlay overlay = map.addTileOverlay(new TileOverlayOptions().tileProvider(provider)); } private List<LatLng> readItems(@RawRes int resource) throws JSONException { List<LatLng> result = new ArrayList<>(); InputStream inputStream = context.getResources().openRawResource(resource); String json = new Scanner(inputStream).useDelimiter("\\A").next(); JSONArray array = new JSONArray(json); for (int i = 0; i < array.length(); i++) { JSONObject object = array.getJSONObject(i); double lat = object.getDouble("lat"); double lng = object.getDouble("lng"); result.add(new LatLng(lat, lng)); } return result; }
Neste exemplo, os dados são armazenados em um arquivo JSON, police_stations.json
. Este é um trecho do arquivo:
[ {"lat" : -37.1886, "lng" : 145.708 } , {"lat" : -37.8361, "lng" : 144.845 } , {"lat" : -38.4034, "lng" : 144.192 } , {"lat" : -38.7597, "lng" : 143.67 } , {"lat" : -36.9672, "lng" : 141.083 } ]
Usar pontos de latitude/longitude ponderados
Ao criar um HeatmapTileProvider
, você pode passar uma coleção de coordenadas de latitude/longitude ponderadas. Esse recurso é útil para mostrar a importância de um determinado conjunto de localizações.
Para aplicar ponderação a localizações específicas:
- Crie um novo
WeightedLatLng
para cada local que requer ponderação. Transmita oLatLng
e umdouble
representando a intensidade necessária. A intensidade indica a importância relativa, ou valor, dessa localização. Um valor maior resulta em uma cor de intensidade maior no gradiente do mapa de calor. Por padrão, a cor de maior intensidade é o vermelho. Chame
HeatmapTileProvider.Builder().weightedData()
em vez deHeatmapTileProvider.Builder().data()
para criar o mapa de calor.
Personalizar o mapa de calor
Várias propriedades do mapa de calor são personalizáveis. É possível definir as opções no momento da criação usando as funções Builder
.
Como alternativa, altere uma opção a qualquer momento chamando o setter relevante no HeatmapTileProvider
e, depois, limpe o cache de blocos da sobreposição para que ele redesenhe todos os blocos com as novas opções.
As seguintes opções estão disponíveis:
- Raio: o tamanho do desfoque gaussiano aplicado ao mapa de calor, expresso em pixels. O padrão é 20. O valor precisa estar entre 10 e 50. Use o
radius()
do Builder para definir o valor durante a criação do mapa de calor ou altere o valor posteriormente comsetRadius()
. - Gradiente: uma faixa de cores usada pelo mapa de calor para gerar o mapa de cores, da menor para a maior intensidade. Um gradiente é criado usando duas matrizes: uma matriz de inteiros, contendo as cores, e uma matriz de números flutuantes, indicando o ponto inicial de cada cor, considerado como uma porcentagem da intensidade máxima e especificado como uma fração entre 0 e 1. Você precisa especificar somente uma cor para um gradiente de uma cor ou um mínimo de duas cores para um gradiente de várias cores. O mapa de cores é gerado usando interpolação entre essas cores. O gradiente padrão tem duas cores. Use o
gradient()
do Builder para definir o valor durante a criação do mapa de calor ou altere o valor posteriormente comsetGradient()
. - Opacidade: é a opacidade de toda a camada do mapa de calor, variando de 0 a 1. O padrão é 0,7. Use o
opacity()
do Builder para definir o valor durante a criação do mapa de calor ou altere o valor posteriormente comsetOpacity()
.
Por exemplo, crie um Gradient
para definir o gradiente antes de adicionar o mapa de calor:
Kotlin
// Create the gradient. val colors = intArrayOf( Color.rgb(102, 225, 0), // green Color.rgb(255, 0, 0) // red ) val startPoints = floatArrayOf(0.2f, 1f) val gradient = Gradient(colors, startPoints) // Create the tile provider. val provider = HeatmapTileProvider.Builder() .data(latLngs) .gradient(gradient) .build() // Add the tile overlay to the map. val tileOverlay = map.addTileOverlay( TileOverlayOptions() .tileProvider(provider) )
Java
// Create the gradient. int[] colors = { Color.rgb(102, 225, 0), // green Color.rgb(255, 0, 0) // red }; float[] startPoints = { 0.2f, 1f }; Gradient gradient = new Gradient(colors, startPoints); // Create the tile provider. HeatmapTileProvider provider = new HeatmapTileProvider.Builder() .data(latLngs) .gradient(gradient) .build(); // Add the tile overlay to the map. TileOverlay tileOverlay = map.addTileOverlay(new TileOverlayOptions().tileProvider(provider));
Para alterar a opacidade de um mapa de calor atual:
Kotlin
provider.setOpacity(0.7) tileOverlay?.clearTileCache()
Java
provider.setOpacity(0.7); tileOverlay.clearTileCache();
Alterar o conjunto de dados
Para alterar o conjunto de dados em que um mapa de calor é criado, use HeatmapTileProvider.setData()
ou HeatmapTileProvider.setWeightedData()
para os pontos de WeightedLatLng
. Observação: para adicionar ou remover pontos no mapa de calor, atualize a coleta de dados e use setData()
ou setWeightedData()
.
Kotlin
val data: List<WeightedLatLng> = ArrayList() provider.setWeightedData(data) tileOverlay?.clearTileCache()
Java
List<WeightedLatLng> data = new ArrayList<>(); provider.setWeightedData(data); tileOverlay.clearTileCache();
Remover um mapa de calor
Para fazer isso, é preciso excluir a sobreposição de blocos:
Kotlin
tileOverlay?.remove()
Java
tileOverlay.remove();
Conferir o app de demonstração
Para ver outro exemplo de implementação de um mapa de calor, consulte o HeatmapsDemoActivity
no app de demonstração que acompanha a biblioteca de utilitários. O guia de configuração mostra como executar o app de demonstração.