Bản đồ nhiệt rất hữu ích trong việc biểu thị sự phân bố và mật độ của các điểm dữ liệu trên bản đồ.
Giới thiệu
SDK Maps dành cho Thư viện tiện ích Android chứa một tiện ích bản đồ nhiệt mà bạn có thể sử dụng để thêm một hoặc nhiều bản đồ nhiệt vào bản đồ của Google trong ứng dụng.
Video này thảo luận về việc sử dụng bản đồ nhiệt để thay thế cho điểm đánh dấu, khi dữ liệu của bạn yêu cầu một số lượng lớn các điểm dữ liệu trên bản đồ.
Bản đồ nhiệt giúp người xem dễ dàng hiểu được sự phân bố và cường độ tương đối của các điểm dữ liệu trên bản đồ. Thay vì đặt một điểm đánh dấu ở từng vị trí, bản đồ nhiệt sử dụng màu sắc để thể hiện sự phân phối dữ liệu.
Trong ví dụ bên dưới, màu đỏ thể hiện những khu vực tập trung nhiều đồn cảnh sát ở Victoria, Úc.
Nếu bạn chưa thiết lập SDK Maps dành cho thư viện Tiện ích Android, hãy làm theo hướng dẫn thiết lập trước khi đọc phần còn lại của trang này.
Thêm một bản đồ nhiệt đơn giản
Để thêm bản đồ nhiệt vào bản đồ, bạn sẽ cần có một tập dữ liệu bao gồm các toạ độ của từng vị trí mà bạn quan tâm. Trước tiên, hãy tạo một HeatmapTileProvider
, truyền vào đó tập hợp các đối tượng LatLng
. Sau đó, tạo một TileOverlay
mới, truyền vào đó trình cung cấp ô bản đồ nhiệt và thêm lớp phủ ô vào bản đồ.
Tiện ích này cung cấp lớp HeatmapTileProvider
. Lớp này triển khai giao diện TileProvider
để cung cấp hình ảnh thẻ thông tin cho bản đồ nhiệt.
HeatmapTileProvider
chấp nhận một tập hợp các đối tượng LatLng
(hoặc các đối tượng WeightedLatLng
, như mô tả dưới đây). Công cụ này tạo hình ảnh thẻ thông tin cho nhiều mức thu phóng, dựa trên các tuỳ chọn bán kính, độ dốc và độ mờ được cung cấp. Bạn có thể thay đổi giá trị mặc định cho các tuỳ chọn này.
Xem các bước chi tiết hơn:
- Sử dụng
HeatmapTileProvider.Builder()
, truyền vào đó một tập hợp các đối tượngLatLng
để thêmHeatmapTileProvider
mới. - Tạo một đối tượng
TileOverlayOptions
mới với các tuỳ chọn liên quan, bao gồm cảHeatmapTileProvider
. - Gọi
GoogleMap.addTileOverlay()
để thêm lớp phủ vào bản đồ.
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; }
Đối với ví dụ này, dữ liệu được lưu trữ trong tệp JSON, police_stations.json
. Dưới đây là bản trích từ tệp:
[ {"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 } ]
Sử dụng vĩ độ/kinh độ có trọng số
Khi tạo HeatmapTileProvider
, bạn có thể truyền vào đó một tập hợp
các toạ độ vĩ độ/kinh độ có trọng số. Việc này rất hữu ích nếu bạn muốn minh hoạ tầm quan trọng của một nhóm vị trí cụ thể.
Cách áp dụng trọng số cho các vị trí cụ thể:
- Tạo một
WeightedLatLng
mới cho từng vị trí cần có trọng số. Truyền vàoLatLng
vàdouble
đại diện cho cường độ cần thiết. Cường độ cho biết tầm quan trọng hoặc giá trị tương đối của vị trí này. Giá trị cao hơn sẽ dẫn đến màu có cường độ cao hơn trong hiệu ứng chuyển màu của bản đồ nhiệt. Theo mặc định, màu có cường độ cao nhất là màu đỏ. Gọi
HeatmapTileProvider.Builder().weightedData()
thay vìHeatmapTileProvider.Builder().data()
để tạo bản đồ nhiệt.
Tuỳ chỉnh bản đồ nhiệt
Một số thuộc tính của bản đồ nhiệt có thể tuỳ chỉnh được. Bạn có thể đặt các tuỳ chọn này tại thời điểm tạo tệp, thông qua các hàm Builder
.
Ngoài ra, bạn có thể thay đổi một tuỳ chọn bất cứ lúc nào bằng cách gọi phương thức setter có liên quan trên HeatmapTileProvider
, sau đó xoá bộ nhớ đệm của thẻ thông tin của lớp phủ để vẽ lại tất cả các thẻ thông tin với các tuỳ chọn mới.
Bạn có thể chọn trong các phương án sau đây:
- Bán kính: Kích thước của vùng làm mờ Gaussian được áp dụng cho bản đồ nhiệt, được biểu thị bằng pixel. Giá trị mặc định là 20. Phải nằm trong khoảng từ 10 đến 50. Sử dụng
radius()
của Builder để đặt giá trị khi tạo bản đồ nhiệt hoặc thay đổi giá trị vào lúc khác bằngsetRadius()
. - gradient (Chuyển màu): Một dải màu mà bản đồ nhiệt sử dụng để tạo bản đồ màu, từ cường độ thấp nhất đến cao nhất. Độ dốc được tạo bằng 2 mảng: một mảng số nguyên chứa các màu và một mảng số thực cho biết điểm bắt đầu của mỗi màu, được tính dưới dạng phần trăm cường độ tối đa và được biểu thị dưới dạng phân số từ 0 đến 1. Bạn chỉ cần chỉ định một màu cho hiệu ứng chuyển màu đơn sắc hoặc tối thiểu hai màu cho hiệu ứng chuyển màu nhiều màu. Bản đồ màu được tạo bằng cách nội suy giữa các màu đó. Dải chuyển màu mặc định có 2 màu. Sử dụng
gradient()
của Builder để đặt giá trị khi tạo bản đồ nhiệt hoặc thay đổi giá trị vào lúc khác bằngsetGradient()
. - Độ mờ: Đây là độ mờ của toàn bộ lớp bản đồ nhiệt và nằm trong khoảng từ 0 đến 1. Giá trị mặc định là 0,7. Sử dụng
opacity()
của Builder để đặt giá trị khi tạo bản đồ nhiệt hoặc thay đổi giá trị vào lúc khác bằngsetOpacity()
.
Ví dụ: tạo một Gradient
để đặt độ chuyển màu trước khi thêm bản đồ nhiệt:
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));
Cách thay đổi độ mờ của bản đồ nhiệt hiện có:
Kotlin
provider.setOpacity(0.7) tileOverlay?.clearTileCache()
Java
provider.setOpacity(0.7); tileOverlay.clearTileCache();
Thay đổi tập dữ liệu
Để thay đổi tập dữ liệu dùng để tạo bản đồ nhiệt, hãy sử dụng HeatmapTileProvider.setData()
hoặc HeatmapTileProvider.setWeightedData()
cho WeightedLatLng
điểm. Lưu ý: Nếu bạn muốn thêm điểm vào bản đồ nhiệt hoặc xoá các điểm khỏi bản đồ nhiệt, hãy cập nhật hoạt động thu thập dữ liệu rồi sử dụng setData()
hoặc setWeightedData()
.
Kotlin
val data: List<WeightedLatLng> = ArrayList() provider.setWeightedData(data) tileOverlay?.clearTileCache()
Java
List<WeightedLatLng> data = new ArrayList<>(); provider.setWeightedData(data); tileOverlay.clearTileCache();
Xoá bản đồ nhiệt
Để xoá bản đồ nhiệt, bạn cần xoá lớp phủ ô:
Kotlin
tileOverlay?.remove()
Java
tileOverlay.remove();
Xem ứng dụng minh hoạ
Để tham khảo một ví dụ khác về cách triển khai bản đồ nhiệt, hãy xem HeatmapsDemoActivity
trong ứng dụng minh hoạ đi kèm với thư viện tiện ích. Hướng dẫn thiết lập cho bạn biết cách chạy ứng dụng minh hoạ.