Utilità mappa termica Google Maps per Android

Seleziona piattaforma:Android iOS

Le mappe termiche sono utili per rappresentare la distribuzione e la densità dei punti dati su una mappa.

Introduzione

La libreria di utilità di Maps SDK for Android include un'utilità per le mappe di calore, che puoi utilizzare per aggiungere una o più mappe di calore a una mappa di Google nella tua applicazione.

Questo video illustra l'utilizzo delle mappe termiche come alternativa ai marcatori quando i dati richiedono un numero elevato di punti dati sulla mappa.

Le mappe termiche consentono agli spettatori di comprendere facilmente la distribuzione e l'intensità relativa dei punti di dati su una mappa. Anziché posizionare un indicatore in ogni località, le mappe termiche utilizzano il colore per rappresentare la distribuzione dei dati.

Nell'esempio riportato di seguito, il colore rosso rappresenta le aree con un'alta concentrazione di stazioni di polizia a Victoria, in Australia.

Una mappa con una mappa termica che mostra la posizione delle stazioni di polizia
Una mappa termica su una mappa

Se non hai ancora configurato la libreria di utilità di Maps SDK for Android, segui la guida alla configurazione prima di leggere il resto di questa pagina.

Aggiungere una mappa termica semplice

Per aggiungere una mappa termica alla mappa, devi disporre di un set di dati costituito dalle coordinate di ogni posizione di interesse. Per prima cosa, crea un HeatmapTileProvider, passando la raccolta di oggetti LatLng. Poi crea un nuovo TileOverlay, passando il fornitore di riquadri della mappa termica e aggiungendo l'overlay dei riquadri alla mappa.

L'utilità fornisce la classe HeatmapTileProvider, che implementa l'interfaccia TileProvider per fornire le immagini dei riquadri per la mappa termica. HeatmapTileProvider accetta una raccolta di oggetti LatLng (o oggetti WeightedLatLng, come descritto di seguito). Crea le immagini delle tessere per vari livelli di zoom, in base alle opzioni di raggio, gradiente e opacità fornite. Puoi modificare i valori predefiniti per queste opzioni.

Analizziamo i passaggi in modo più dettagliato:

  1. Utilizza HeatmapTileProvider.Builder(), passando una raccolta di oggetti LatLng, per aggiungere un nuovo HeatmapTileProvider.
  2. Crea un nuovo oggetto TileOverlayOptions con le opzioni pertinenti, incluso HeatmapTileProvider.
  3. Chiama GoogleMap.addTileOverlay() per aggiungere l'overlay alla mappa.

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;
}

      

Per questo esempio, i dati vengono archiviati in un file JSON, police_stations.json. Ecco un estratto del file:

[
{"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 }
]

Utilizzare punti di latitudine/longitudine ponderati

Quando crei un HeatmapTileProvider, puoi passargli una raccolta di coordinate di latitudine/longitudine ponderate. Questa opzione è utile se vuoi illustrare l'importanza di un insieme specifico di località.

Per applicare la ponderazione a località specifiche:

  1. Crea un nuovo WeightedLatLng per ogni località che richiede la ponderazione. Passa LatLng e double che rappresenta l'intensità richiesta. L'intensità indica l'importanza relativa o il valore di questa posizione. Un valore più alto comporterà un colore di intensità maggiore nel gradiente della mappa termica. Per impostazione predefinita, il colore di intensità più elevata è il rosso.
  2. Chiama HeatmapTileProvider.Builder().weightedData(), anziché HeatmapTileProvider.Builder().data(), per creare la mappa termica.

Personalizzare la mappa termica

Alcune proprietà della mappa di calore sono personalizzabili. Puoi impostare le opzioni al momento della creazione tramite le funzioni Builder. In alternativa, modifica un'opzione in qualsiasi momento chiamando l'emittente pertinente sul HeatmapTileProvider, quindi cancella la cache dei riquadri dell'overlay in modo che vengano ridisegnati tutti i riquadri con le nuove opzioni.

Sono disponibili le seguenti opzioni:

  1. Raggio:la dimensione della sfocatura gaussiana applicata alla mappa di calore, espressa in pixel. Il valore predefinito è 20. Il valore deve essere compreso tra 10 e 50. Utilizza il generatore radius() per impostare il valore durante la creazione della mappa termica o modifica il valore in un secondo momento con setRadius().
  2. Gradiente:una gamma di colori che la mappa termica utilizza per generare la mappa dei colori, che va dall'intensità più bassa a quella più alta. Viene creato un gradiente utilizzando due array: un array di numeri interi contenente i colori e un array di numeri in virgola mobile che indica il punto di partenza di ogni colore, espresso come percentuale dell'intensità massima e come frazione da 0 a 1. Devi specificare un solo colore per un gradiente a un solo colore o un minimo di due colori per un gradiente multicolore. La mappa dei colori viene generata utilizzando l'interpolazione tra questi colori. La sfumatura predefinita ha due colori. Utilizza gradient() del generatore per impostare il valore durante la creazione della heatmap o modifica il valore in un secondo momento con setGradient().
  3. Opacità:l'opacità dell'intero livello della mappa termica, compresa tra 0 e 1. Il valore predefinito è 0,7. Utilizza opacity() nel generatore per impostare il valore durante la creazione della mappa di calore oppure modifica il valore in un secondo momento con setOpacity().

Ad esempio, crea un Gradient per impostare il gradiente prima di aggiungere la mappa termica:

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));

      

Per modificare l'opacità di una mappa termica esistente:

Kotlin

provider.setOpacity(0.7)
tileOverlay?.clearTileCache()

      

Java

provider.setOpacity(0.7);
tileOverlay.clearTileCache();

      

Modificare il set di dati

Per modificare il set di dati su cui è basata una mappa termica, utilizza HeatmapTileProvider.setData(), o HeatmapTileProvider.setWeightedData() per i punti WeightedLatLng. Nota: se vuoi aggiungere punti alla heatmap o rimuoverli, aggiorna la raccolta dei dati e poi utilizza setData() o setWeightedData().

Kotlin

val data: List<WeightedLatLng> = ArrayList()
provider.setWeightedData(data)
tileOverlay?.clearTileCache()

      

Java

List<WeightedLatLng> data = new ArrayList<>();
provider.setWeightedData(data);
tileOverlay.clearTileCache();

      

Rimuovere una mappa termica

Per rimuovere la mappa termica, devi rimuovere la sovrapposizione del riquadro:

Kotlin

tileOverlay?.remove()

      

Java

tileOverlay.remove();

      

Visualizza l'app demo

Per un altro esempio di implementazione di una mappa termica, dai un'occhiata a HeatmapsDemoActivity nell'app demo fornita con la libreria di utilità. La guida alla configurazione mostra come eseguire l'app demo.