Google Maps Android Heatmap-Dienstprogramm

Heatmaps ermöglichen es, die Verteilung und Dichte von Datenpunkten auf einer Karte darzustellen.

Einführung

Die Maps SDK for Android-Dienstprogrammbibliothek enthält ein Heatmap-Dienstprogramm, mit dem du einer Google-Karte in deiner App eine oder mehrere Heatmaps hinzufügen kannst.

In diesem Video wird die Verwendung von Heatmaps anstelle von Markierungen erörtert, wenn für deine Daten eine große Anzahl Datenpunkte auf der Karte erforderlich ist.

Mit Heatmaps ist es einfacher, die Verteilung und relative Intensität von Datenpunkten auf einer Karte zu erkennen. Statt eine Markierung an jedem Standort zu platzieren, wird die Verteilung von Daten bei Heatmaps anhand von Farben dargestellt.

Im nachfolgenden Beispiel sind Bereiche mit einer hohen Konzentration von Polizeidienststellen in Victoria, Australien, in Rot dargestellt.

Eine Karte mit einer Heatmap, auf der die Standorte von Polizeidienststellen zu sehen sind
Heatmap auf einer Karte

Wenn du die Maps SDK for Android-Dienstprogrammbibliothek noch nicht eingerichtet hast, folge der Einrichtungsanleitung, bevor du mit dem Rest dieser Seite fortfährst.

Einfache Heatmap hinzufügen

Wenn du deiner Karte eine Heatmap hinzufügen möchtest, benötigst du einen Datensatz mit Koordinaten für jeden entsprechenden Standort. Erstelle zuerst ein HeatmapTileProvider-Objekt und übergebe ihm die Sammlung von LatLng-Objekten. Erstelle dann ein neues TileOverlay, übergib den Heatmap-Kachelanbieter und füge das Kachel-Overlay der Karte hinzu.

Das Dienstprogramm stellt die Klasse HeatmapTileProvider bereit, die die Schnittstelle TileProvider implementiert, um die Kachelbilder für die Heatmap zu liefern. HeatmapTileProvider akzeptiert eine Sammlung von LatLng-Objekten (oder WeightedLatLng-Objekten, wie unten beschrieben). Die Kachelbilder werden für verschiedene Zoomstufen basierend auf den definierten Optionen für Radius, Farbverlauf und Deckkraft erstellt. Du kannst die Standardwerte für diese Optionen ändern.

Hier sind die einzelnen Schritte im Detail beschrieben:

  1. Verwende HeatmapTileProvider.Builder() und übergib eine Sammlung von LatLng-Objekten, um ein neues HeatmapTileProvider-Element hinzuzufügen.
  2. Erstelle ein neues TileOverlayOptions-Objekt mit den relevanten Optionen, einschließlich HeatmapTileProvider.
  3. Rufe GoogleMap.addTileOverlay() auf, um das Overlay zur Karte hinzuzufügen.

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

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
}
      

In diesem Beispiel werden die Daten in der JSON-Datei police_stations.json gespeichert. Hier siehst du einen Auszug aus der Datei:

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

Gewichtete Breiten-/Längenangaben verwenden

Beim Erstellen von HeatmapTileProvider kannst du eine Sammlung gewichteter Breiten-/Längengradkoordinaten übergeben. Das ist sinnvoll, wenn du die Bedeutung einer bestimmten Standortgruppe hervorheben möchtest.

So kannst du einzelnen Standorten eine Gewichtung zuweisen:

  1. Erstelle ein neues WeightedLatLng-Objekt für jeden Standort, der gewichtet werden muss. Übergib die Werte LatLng und double für die erforderliche Intensität. Mit der Intensität wird die relative Bedeutung oder der Wert dieses Standorts angegeben. Ein höherer Wert führt im Farbverlauf der Heatmap zu einer farblich intensiveren Darstellung. Standardmäßig ist Rot die Farbe mit der höchsten Intensität.
  2. Rufe HeatmapTileProvider.Builder().weightedData() statt HeatmapTileProvider.Builder().data() auf, um die Heatmap zu erstellen.

Heatmap anpassen

Du kannst verschiedene Eigenschaften der Heatmap anpassen. Die Optionen lassen sich beim Erstellen mithilfe der Builder-Funktionen festlegen. Du kannst eine Option auch jederzeit ändern, indem du die entsprechende Setter-Methode in HeatmapTileProvider aufrufst und dann den Kachel-Cache des Overlays löschst, damit alle Kacheln mit den neuen Optionen neu abgerufen werden.

Folgende Optionen sind verfügbar:

  1. Radius: Die Größe des auf die Heatmap angewendeten Gaußschen Weichzeichners, ausgedrückt in Pixeln. Der Standardwert ist 20. Der Wert muss zwischen 10 und 50 liegen. Verwende radius() des Builders, um den Wert beim Erstellen der Heatmap festzulegen, oder ändere den Wert später mit setRadius().
  2. Verlauf: Der Farbverlauf von der niedrigsten zur höchsten Intensität, der in der Heatmap zum Erstellen der Farbkarte verwendet wird. Ein Farbverlauf wird mithilfe von zwei Arrays erstellt: ein Ganzzahl-Array, das die Farben enthält, und ein Gleitkommazahl-Array, das den Anfangspunkt für jede Farbe in Form eines Prozentsatzes der maximalen Intensität angibt, ausgedrückt als Teilwert zwischen 0 und 1. Für einen einfarbigen Farbverlauf musst du nur eine Farbe angeben; für mehrfarbige Farbverläufe sind mindestens zwei Farben zu definieren. Die Farbkarte wird durch Interpolieren dieser Farben generiert. Der Standardfarbverlauf verfügt über zwei Farben. Verwende gradient() des Builders, um den Wert beim Erstellen der Heatmap festzulegen, oder ändere den Wert später mit setGradient().
  3. Deckkraft: Das ist die Deckkraft der gesamten Heatmap-Ebene. Der Wert liegt zwischen 0 und 1. Der Standardwert ist „0,7“. Verwende den opacity() des Builders, um den Wert beim Erstellen der Heatmap festzulegen, oder ändere den Wert später mit setOpacity().

Erstelle beispielsweise einen Gradient, um den Farbverlauf vor dem Hinzufügen der Heatmap festzulegen:

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

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

So änderst du die Deckkraft einer vorhandenen Heatmap:

Java

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

Kotlin

provider.setOpacity(0.7)
tileOverlay.clearTileCache()
      

Datensatz ändern

Wenn du den Datensatz ändern möchtest, auf dem eine Heatmap beruht, verwende HeatmapTileProvider.setData() oder HeatmapTileProvider.setWeightedData() für WeightedLatLng-Punkte. Hinweis: Wenn du der Heatmap Punkte hinzufügen oder Punkte daraus entfernen möchtest, aktualisiere die Datensammlung und verwende dann setData() oder setWeightedData().

Java

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

Kotlin

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

Heatmap entfernen

Um die Heatmap zu entfernen, musst du das Kachel-Overlay entfernen.

Java

tileOverlay.remove();
      

Kotlin

tileOverlay.remove()
      

Demo-App ansehen

Ein weiteres Beispiel für eine Heatmap-Implementierung findest du in der HeatmapsDemoActivity in der Demo-App, die im Lieferumfang der Dienstprogrammbibliothek enthalten ist. Im Einrichtungsleitfaden erhältst du Informationen zum Ausführen der Demo-App.