Google マップ Android ヒートマップ ユーティリティ

ヒートマップは、マップ上のデータポイントの分布と密度を表すのに役立ちます。

はじめに

Maps SDK for Android ユーティリティ ライブラリには、アプリケーションで Google マップに 1 つ以上のヒートマップを追加するために使用できるヒートマップ ユーティリティが含まれています。

この動画では、マップ上に多数のデータポイントが必要なデータの場合に、マーカーの代わりとしてヒートマップを使用する方法を説明します。

ヒートマップを使用すると、マップ上のデータポイントの分布と相対密度を閲覧者にわかりやすく示すことができます。各場所にマーカーを配置するのではなく、ヒートマップでは色を使用してデータの分布を表します。

次の例では、オーストラリアのビクトリアにおいて、警察署の密度が高い地域が赤で表されています。

警察署の場所を示すヒートマップが表示されているマップ
マップ上のヒートマップ

Maps SDK for Android ユーティリティ ライブラリをまだ設定していない場合は、このページの残りを読む前に、設定ガイドをお読みください。

単純なヒートマップを追加する

マップにヒートマップを追加するには、対象の位置それぞれを示す座標のデータセットが必要です。まず、HeatmapTileProvider を作成し、これに LatLng オブジェクトのコレクションを渡します。次に、新しい TileOverlay を作成し、これにヒートマップ タイル プロバイダを渡して、マップにタイル オーバーレイを追加します。

ユーティリティには HeatmapTileProvider クラスが用意されており、これが TileProvider インターフェースを実装して、ヒートマップのタイル画像を提供します。 HeatmapTileProviderLatLng オブジェクト(または下記WeightedLatLng オブジェクト)のコレクションを受け入れます。これにより、さまざまなズームレベルのタイル画像が、指定された半径、グラデーション、不透明度のオプションに基づいて作成されます。これらのオプションのデフォルト値は変更できます。

次に、各ステップの詳細を示します。

  1. HeatmapTileProvider.Builder() を使用し、LatLng オブジェクトのコレクションを渡して、新しい HeatmapTileProvider を追加します。
  2. 新しい TileOverlayOptions オブジェクトを作成し、HeatmapTileProvider などの適切なオプションを指定します。
  3. GoogleMap.addTileOverlay() を呼び出して、マップにオーバーレイを追加します。

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
}

      

この例では、データは JSON ファイル police_stations.json に保存されています。ファイルの抜粋を以下に示します。

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

重み付き緯度 / 経度ポイントを使用する

HeatmapTileProvider を作成する際、これに重み付き緯度 / 経度の座標のコレクションを渡すことができます。これは、特定の場所のセットの重要度を示す場合に役立ちます。

特定の場所に重みを付けるには、以下のようにします。

  1. 重み付けを必要とする場所ごとに新しい WeightedLatLng を作成します。LatLng と必要な強度を表す double を渡します。強度は、この場所の相対的な重要度、つまり価値を示します。価値が高いほど、ヒートマップのグラデーションでより高い強度の色で示されます。デフォルトでは、最高強度の色は赤です。
  2. HeatmapTileProvider.Builder().data() ではなく HeatmapTileProvider.Builder().weightedData() を呼び出して、ヒートマップを作成します。

ヒートマップをカスタマイズする

ヒートマップのプロパティの多くはカスタマイズできます。作成時に Builder 関数を使ってオプションを設定できます。 または、HeatmapTileProvider で適切な setter を呼び出して、いつでもオプションを変更できます。変更後は、オーバーレイのタイル キャッシュを消去して、新しいオプションを適用してすべてのタイルが再描画されるようにします。

以下のオプションを使用できます。

  1. Radius: ピクセル単位で示される、ヒートマップに適用されるガウスぼかしのサイズ。デフォルト値は 20 です。10 から 50 の間である必要があります。Builder の radius() を使ってヒートマップの作成時に値を設定するか、setRadius() を使って後から値を変更します。
  2. Gradient: ヒートマップが色マップを生成するために使用する、最低強度から最高強度までの色の範囲。グラデーションは 2 つの配列を使用して作成されます。色を含む整数配列と、各色の開始点を示す浮動小数配列です。開始点は最大強度に対する割合で示され、0 から 1 の間の小数として表されます。単色のグラデーションでは色を 1 つのみ指定する必要があり、複数色のグラデーションでは 2 色以上指定する必要があります。色マップは、これらの色間の補間を使用して生成されます。デフォルトのグラデーションでは 2 色が使用されます。Builder の gradient() を使ってヒートマップの作成時に値を設定するか、setGradient() を使って後から値を変更します。
  3. Opacity: これはヒートマップ レイヤ全体の不透明度で、範囲は 0 から 1 です。デフォルトは 0.7 です。Builder の opacity() を使ってヒートマップの作成時に値を設定するか、setOpacity() を使って後から値を変更します。

たとえば、Gradient を作成して、ヒートマップを追加する前にグラデーションを設定します。

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

      

既存のヒートマップの不透明度を変更するには、次のようにします。

Java


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

      

Kotlin


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

      

データセットを変更する

ヒートマップの基となるデータセットを変更するには、WeightedLatLng のポイントに対して HeatmapTileProvider.setData() または HeatmapTileProvider.setWeightedData() を使用します。ヒートマップにポイントを追加したり、ヒートマップからポイントを削除したりするには、データ コレクションをアップデートしてから、setData() または setWeightedData() を使用します。

Java


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

      

Kotlin


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

      

ヒートマップを削除する

ヒートマップを削除するには、タイル オーバーレイを削除する必要があります。

Java


tileOverlay.remove();

      

Kotlin


tileOverlay?.remove()

      

デモアプリを見る

ヒートマップ実装の別の例については、ユーティリティ ライブラリに付属のデモアプリにある HeatmapsDemoActivity をご覧ください。また、設定ガイドでは、デモアプリを実行する方法を説明しています。