热图非常适合用来表示地图上数据点的分布情况和密度。
简介
Maps SDK for Android 实用程序库包括一个热图实用程序,您可以利用它向您应用内的 Google 地图添加一个或多个热图。
这段视频介绍了当数据较多,需要在地图上显示大量数据点时,如何将热图用作标记的替代方案。
热图便于查看者了解地图上数据点的分布情况和相对密度。热图不是在每个位置放置标记,而是利用颜色来表示数据的分布情况。
在下例中,红色表示澳大利亚维多利亚州警察局密度较高的区域。
![一幅包含警察局位置热图的地图](https://developers.google.cn/static/maps/documentation/android-sdk/images/utility-heatmap.png?authuser=0000&hl=da)
如果您尚未设置 Maps SDK for Android 实用程序库,请先按照设置指南完成设置,然后再阅读本页面的其余内容。
添加简单热图
如需向您的地图添加热图,您需要一个数据集,其中包含每个地图注点位置的坐标。首先创建一个 HeatmapTileProvider
,并向其传递 LatLng
对象的集合。然后,新建一个 TileOverlay
,向其传递热图图块提供程序,然后向地图添加图块叠加层。
实用程序提供 HeatmapTileProvider
类,该类会实现 TileProvider
接口,为热图提供图块图片。HeatmapTileProvider
接受 LatLng
对象集合(或 WeightedLatLng
对象集合,如下文所述)。它会根据提供的半径、渐变和不透明度选项,创建各种缩放级别的图块图片。您可以更改这些选项的默认值。
以下列出了更详细的步骤:
- 使用
HeatmapTileProvider.Builder()
,向其传递LatLng
对象集合,以添加新的HeatmapTileProvider
。 - 新建一个带相关选项的
TileOverlayOptions
对象,其中包括HeatmapTileProvider
。 - 调用
GoogleMap.addTileOverlay()
以将叠加层添加到地图中。
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; }
在此示例中,数据存储在 police_stations.json
这个 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
时,您可以向其传递一个加权纬度/经度坐标的集合。如果您想说明某一组位置的重要性,便可这样做。
如需对特定位置应用加权,请执行以下操作:
- 为每个需要加权的位置新建一个
WeightedLatLng
。传入LatLng
和表示所需颜色强度的double
。颜色强度表示该位置的相对重要性,也就是价值。价值越高,其在热图渐变中的颜色强度就越高。默认情况下,红色的强度最高。 调用
HeatmapTileProvider.Builder().weightedData()
而非HeatmapTileProvider.Builder().data()
来创建热图。
自定义热图
热图的许多属性都可以自定义。您可以在创建热图时,通过 Builder
函数设置各选项。或者,您也可以随时通过对 HeatmapTileProvider
调用相关 setter 方法来更改选项,然后清除叠加层的图块缓存,以便系统根据新的选项重新绘制所有图块。
提供的选项如下:
- 半径:应用于热图的高斯模糊的范围大小,以像素表示。默认值为 20。必须介于 10 至 50 之间。可以在创建热图时使用构建器的
radius()
设置该值,或者稍后通过setRadius()
更改该值。 - 渐变:热图生成其色表时使用的一系列颜色,范围从强度最低的颜色到强度最高的颜色。创建渐变时会使用两个数组:一个包含颜色值的整数数组,以及一个表示各颜色值起点的浮点数数组(起点是该颜色的强度相较于最高强度的百分比,采用介于 0 到 1 之间的小数形式表示)。对于单色渐变,您只需指定一种颜色;对于多色渐变,则至少需要指定两种颜色。色表是利用这些颜色之间的插值生成的。默认渐变有两种颜色。可以在创建热图时使用构建器的
gradient()
设置该值,或者稍后通过setGradient()
更改该值。 - 不透明度:这是指整个热图图层的不透明度,范围是 0 至 1。默认值为 0.7。可以在创建热图时使用构建器的
opacity()
设置该值,或者稍后通过setOpacity()
更改该值。
例如,可以在添加热图前创建一个 Gradient
来设置渐变:
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));
如需更改现有热图的不透明度,请执行以下操作:
Kotlin
provider.setOpacity(0.7) tileOverlay?.clearTileCache()
Java
provider.setOpacity(0.7); tileOverlay.clearTileCache();
更改数据集
如需更改作为热图构建基础的数据集,请使用 HeatmapTileProvider.setData()
;对于 WeightedLatLng
数据点,请使用 HeatmapTileProvider.setWeightedData()
。注意:如果您想为热图添加数据点,或者移除热图中的数据点,请更新您的数据集,然后使用 setData()
或 setWeightedData()
。
Kotlin
val data: List<WeightedLatLng> = ArrayList() provider.setWeightedData(data) tileOverlay?.clearTileCache()
Java
List<WeightedLatLng> data = new ArrayList<>(); provider.setWeightedData(data); tileOverlay.clearTileCache();
移除热图
如需移除热图,您需要移除图块叠加层:
Kotlin
tileOverlay?.remove()
Java
tileOverlay.remove();
观摩演示版应用
如需再观摩一个热图实现示例,请看一看实用程序库附带的演示版应用中的 HeatmapsDemoActivity
。设置指南向您介绍了如何运行演示版应用。