Utilitaire de carte de densité de Google Maps pour Android

Les cartes de densité sont utiles pour représenter la répartition et la densité des points de données sur une carte.

Introduction

La bibliothèque d'utilitaires du SDK Maps pour Android contient un utilitaire de carte de densité, qui vous permet d'ajouter une ou plusieurs cartes de densité à une carte Google dans votre application.

Cette vidéo explique l'utilisation des cartes de densité comme alternative aux repères, lorsque vous avez besoin d'ajouter de nombreux points de données sur la carte.

Les cartes de densité permettent aux utilisateurs de mieux comprendre la répartition et l'intensité relative des points de données sur une carte. Au lieu de placer un repère à chaque point géographique, les cartes de densité utilisent des couleurs pour représenter la répartition des données.

Dans l'exemple ci-dessous, le rouge représente les zones avec une forte concentration de commissariats à Victoria, en Australie.

Une carte avec une carte de densité montrant l'emplacement des commissariats
Carte de densité sur une carte

Si vous n'avez pas encore configuré la bibliothèque d'utilitaires du SDK Maps pour Android, suivez le guide de configuration avant de poursuivre la lecture de cette page.

Ajouter une carte de densité simple

Pour ajouter une carte de densité à votre carte, vous devez disposer d'un jeu de données comprenant les coordonnées de chaque point géographique présentant un intérêt. Commencez par créer un objet HeatmapTileProvider, en lui transmettant la collection d'objets LatLng. Créez ensuite un autre TileOverlay, en lui transmettant le fournisseur de tuiles de la carte de densité, puis ajoutez la superposition de tuiles à la carte.

L'utilitaire fournit la classe HeatmapTileProvider, qui met en œuvre l'interface TileProvider pour fournir les images de tuiles de la carte de densité. HeatmapTileProvider accepte une collection d'objets LatLng (ou d'objets WeightedLatLng, comme décrit ci-dessous). Il crée les images de tuiles pour différents niveaux de zoom, en fonction des options de rayon, de dégradé et d'opacité fournies. Vous pouvez modifier les valeurs par défaut de ces options.

Examinons les étapes plus en détail :

  1. Utilisez HeatmapTileProvider.Builder(), en lui transmettant une collection d'objets LatLng, pour ajouter un nouveau HeatmapTileProvider.
  2. Créez un objet TileOverlayOptions avec les options appropriées, y compris le HeatmapTileProvider.
  3. Appelez GoogleMap.addTileOverlay() pour ajouter la superposition à la carte.

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
}
      

Pour cet exemple, les données sont stockées dans un fichier JSON, police_stations.json. Voici un extrait du fichier :

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

Utiliser des points de latitude/longitude pondérés

Lors de la création d'un HeatmapTileProvider, vous pouvez lui transmettre une collection de coordonnées de latitude/longitude pondérées. Cela peut être utile si vous souhaitez souligner l'importance d'un ensemble de points géographiques en particulier.

Pour appliquer une pondération à des points géographiques spécifiques :

  1. Créez un objet WeightedLatLng pour chaque point géographique nécessitant une pondération. Spécifiez LatLng et un double représentant l'intensité requise. L'intensité indique l'importance, ou valeur, relative de ce point géographique. Plus la valeur est élevée, plus l'intensité de la couleur du dégradé de la carte de densité est forte. Par défaut, la couleur la plus intense est le rouge.
  2. Appelez HeatmapTileProvider.Builder().weightedData(), au lieu de HeatmapTileProvider.Builder().data(), pour créer la carte de densité.

Personnaliser la carte de densité

Un certain nombre de propriétés de la carte de densité sont personnalisables. Vous pouvez définir les options au moment de la création, via les fonctions Builder. De même, vous pouvez modifier une option à tout moment en appelant le setter approprié sur le HeatmapTileProvider, puis en supprimant le cache des tuiles de la superposition afin de redessiner toutes les tuiles en tenant compte des nouvelles options.

Les options suivantes sont disponibles :

  1. Rayon : Taille du flou gaussien appliqué à la carte de densité, exprimée en pixels. La valeur par défaut est 20. Doit être compris entre 10 et 50. Utilisez le radius() du Builder pour définir la valeur lors de la création de la carte de densité, ou modifiez la valeur par la suite avec setRadius().
  2. Dégradé : Gamme de couleurs que la carte de densité utilise pour générer sa carte de couleurs, de l'intensité la plus faible à la plus élevée. Un dégradé est créé à l'aide de deux tableaux : un tableau de nombres entiers contenant les couleurs et un tableau de valeurs flottantes indiquant le point de départ de chaque couleur, fournies en tant que pourcentage de l'intensité maximale et exprimées sous forme de fraction de 0 à 1. Vous devez indiquer une seule couleur pour les dégradés unis, ou deux couleurs au minimum pour les dégradés multicolores. La carte de couleurs est générée en faisant une interpolation entre ces couleurs. Le dégradé par défaut a deux couleurs. Utilisez le gradient() du Builder pour définir la valeur lors de la création de la carte de densité, ou modifiez la valeur par la suite avec setGradient().
  3. Opacité : Définit l'opacité du calque de la carte de densité, exprimée sous la forme d'une valeur comprise entre 0 et 1. La valeur par défaut est 0,7. Utilisez le opacity() du Builder pour définir la valeur lors de la création de la carte de densité, ou modifiez la valeur par la suite avec setOpacity().

Par exemple, créez un Gradient pour définir le dégradé avant d'ajouter la carte de densité :

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

Pour changer l'opacité d'une carte de densité existante :

Java

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

Kotlin

provider.setOpacity(0.7)
tileOverlay.clearTileCache()
      

Modifier l'ensemble de données

Pour modifier l'ensemble de données à partir duquel la carte de densité est construite, utilisez HeatmapTileProvider.setData() ou HeatmapTileProvider.setWeightedData() pour les points WeightedLatLng. Remarque : Si vous souhaitez ajouter des points à la carte de densité ou en supprimer, mettez à jour votre collecte de données, puis utilisez setData() ou setWeightedData().

Java

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

Kotlin

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

Supprimer une carte de densité

Pour supprimer la carte de densité, vous devez supprimer la superposition de tuiles :

Java

tileOverlay.remove();
      

Kotlin

tileOverlay.remove()
      

Voir l'application de démonstration

Pour voir un autre exemple de mise en œuvre de carte de densité, consultez l'activité HeatmapsDemoActivity dans l'application de démonstration intégrée à la bibliothèque d'utilitaires. Le guide de configuration vous explique comment exécuter l'application de démonstration.