Google 地圖 Android 熱視圖公用程式

熱視圖適合用來在地圖上呈現資料點的分布情形和密度。

簡介

Maps SDK for Android 公用程式庫提供熱視圖公用程式,可用來在應用程式的 Google 地圖中加入一或多個熱視圖。

這部影片說明當資料需要用到地圖上的大量資料點時,如何以熱視圖替代標記叢集。

熱視圖能在地圖上顯示資料點的分布位置及相對強度,讓檢視者一目瞭然。這類地圖並不會在各個地點放置標記,而是使用顏色來表示資料的分布情形。

在下方範例中,紅色代表澳洲維多利亞省警察局數量最密集的區域。

含警察局位置熱視圖的地圖
地圖上的熱視圖

如果您尚未設定 Maps SDK for Android 公用程式庫,請先按照設定指南完成設定,再閱讀本頁面的其餘內容。

新增簡單的熱視圖

如要在地圖中加入熱視圖,您需要一個由各個搜尋點位置座標構成的資料集。首先建立 HeatmapTileProvider,並向其傳遞 LatLng 物件集合。接著建立新的 TileOverlay,然後向其傳遞熱視圖圖塊提供者,接著將圖塊疊加層新增至地圖。

公用程式會提供 HeatmapTileProvider 類別;這個類別會導入 TileProvider 介面來提供熱視圖的圖塊圖片。HeatmapTileProvider 可接受 LatLng 物件的集合 (或 WeightedLatLng 物件,請見下文說明)。該類別會根據提供的半徑、漸層和不透明度選項,為不同縮放等級建立圖塊圖片。您可以變更這些選項的預設值

詳細步驟如下:

  1. 使用 HeatmapTileProvider.Builder(),然後向其傳遞 LatLng 物件集合,藉此新增 HeatmapTileProvider
  2. 利用相關選項 (包括 HeatmapTileProvider) 建立新的 TileOverlayOptions 物件。
  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。傳入 LatLngdouble,代表指定強度。強度代表該位置的相對重要性或價值。值越大,熱視圖的漸層色彩強度就越高。根據預設,強度最高的顏色是紅色。
  2. 請呼叫 HeatmapTileProvider.Builder().weightedData() (而不是 HeatmapTileProvider.Builder().data()) 來建立熱視圖。

自訂熱視圖

熱視圖有多種屬性可供自訂。您可以在建立熱視圖時,透過 Builder 函式設定選項。或者,您也可以隨時在 HeatmapTileProvider 上呼叫相關的 setter 來變更選項,然後清除疊加層的圖塊快取,讓系統根據新的選項重新繪製所有圖塊。

可用選項如下所示:

  1. 半徑:套用至熱視圖的高斯模糊效果範圍 (以像素表示,預設值為 20)。此值必須介於 10 至 50 之間。請在建立熱視圖時使用建構工具的 radius() 來設定值,或稍後使用 setRadius() 變更該值。
  2. 漸層:熱視圖用來產生彩色地圖的色彩範圍,範圍從最低強度到最高強度。建立漸層時會使用兩個陣列,分別是包含色彩的整數陣列,以及指出各顏色起始點的浮點陣列,代表占最高強度的百分比,並以 0 到 1 之間的小數值表示。您必須為單一顏色漸層指定單個顏色,或為多色漸層指定至少兩種顏色。彩色地圖會使用這些顏色的內插類型來產生。預設漸層有兩種顏色。請在建立熱視圖時使用建構工具的 gradient() 來設定值,或者日後再使用 setGradient() 變更該值。
  3. 不透明度:這是整個熱視圖圖層的不透明度,範圍從 0 到 1,預設值為 0.7。您可以在建立熱視圖時使用建構工具的 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設定指南會示範如何執行試用版應用程式。