Tiện ích bản đồ nhiệt dành cho Android của Google Maps

Chọn nền tảng: Android iOS

Bản đồ nhiệt rất hữu ích để 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

Thư viện tiện ích SDK Maps dành cho Android bao gồm một tiện ích bản đồ nhiệt. Bạn có thể dùng tiện ích này để thêm một hoặc nhiều bản đồ nhiệt vào bản đồ Google trong ứng dụng của mình.

Video này thảo luận về việc sử dụng bản đồ nhiệt thay 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 đ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 điểm đánh dấu tại mỗi vị trí, bản đồ nhiệt sử dụng màu sắc để biểu thị sự phân phối của dữ liệu.

Trong ví dụ dưới đây, màu đỏ biểu thị những khu vực có mật độ đồn cảnh sát cao ở Victoria, Úc.

Bản đồ có biểu đồ nhiệt cho thấy vị trí của các đồn cảnh sát
Bản đồ nhiệt trên bản đồ

Nếu bạn chưa thiết lập thư viện Tiện ích Maps SDK cho 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 bản đồ nhiệt đơn giản

Để thêm bản đồ nhiệt vào bản đồ, bạn sẽ cần một tập dữ liệu bao gồm toạ độ cho từng vị trí mà bạn quan tâm. Trước tiên, hãy tạo một HeatmapTileProvider, truyền cho đối tượng này tập hợp các đối tượng LatLng. Sau đó, hãy tạo một TileOverlay mới, truyền cho nó 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, triển khai giao diện TileProvider để cung cấp hình ảnh ô 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ả bên dưới). Thao tác này sẽ tạo hình ảnh ô cho nhiều mức thu phóng, dựa trên các lựa chọn bán kính, độ dốc và độ mờ được cung cấp. Bạn có thể thay đổi các giá trị mặc định cho các lựa chọn này.

Hãy xem xét các bước chi tiết hơn:

  1. Sử dụng HeatmapTileProvider.Builder(), truyền cho nó một tập hợp các đối tượng LatLng để thêm HeatmapTileProvider mới.
  2. Tạo một đối tượng TileOverlayOptions mới bằng các lựa chọn có liên quan, bao gồm cả HeatmapTileProvider.
  3. 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;
}

      

Trong ví dụ này, dữ liệu được lưu trữ trong một tệp JSON, police_stations.json. Sau đây là một đoạ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 các điểm vĩ độ/kinh độ có trọng số

Khi tạo một HeatmapTileProvider, bạn có thể truyền cho nó một tập hợp các toạ độ vĩ độ/kinh độ có trọng số. Điều 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 hệ số cho các vị trí cụ thể:

  1. Tạo một WeightedLatLng mới cho mỗi vị trí yêu cầu hệ số. Truyền vào LatLngdouble biểu thị cường độ cần thiết. Cường độ cho biết tầm quan trọng tương đối hoặc giá trị của vị trí này. Giá trị càng cao thì màu trong hiệu ứng chuyển màu của bản đồ nhiệt sẽ có cường độ càng cao. Theo mặc định, màu có cường độ cao nhất là màu đỏ.
  2. Gọi HeatmapTileProvider.Builder().weightedData() thay vì HeatmapTileProvider.Builder().data() để tạo bản đồ nhiệt.

Tuỳ chỉnh bản đồ nhiệt

Bạn có thể tuỳ chỉnh một số thuộc tính của bản đồ nhiệt. Bạn có thể đặt các lựa chọn tại thời điểm tạo thông qua các hàm Builder. Ngoài ra, bạn có thể thay đổi một lựa chọn bất cứ lúc nào bằng cách gọi phương thức thiết lập có liên quan trên HeatmapTileProvider, rồi xoá bộ nhớ đệm của ô lớp phủ để vẽ lại tất cả các ô bằng các lựa chọn mới.

Bạn có các tuỳ chọn sau đây:

  1. Bán kính: Kích thước của hiệu ứ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 Trình tạo để đặt giá trị khi tạo bản đồ nhiệt hoặc thay đổi giá trị sau này bằng setRadius().
  2. Chuyển màu: Một dải màu mà bản đồ nhiệt dùng để tạo bản đồ màu, từ cường độ thấp nhất đến cao nhất. Một hiệu ứng chuyển màu được tạo bằng cách sử dụng hai 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 từng màu, được biểu thị dưới dạng tỷ lệ phần trăm của cường độ tối đa và được biểu thị dưới dạng một phân số từ 0 đến 1. Bạn chỉ cần chỉ định một màu cho độ dốc một màu hoặc tối thiểu hai màu cho độ dốc nhiều màu. Bản đồ màu được tạo bằng cách sử dụng phép nội suy giữa các màu đó. Độ dốc mặc định có 2 màu. Sử dụng gradient() của Trình tạo để đặt giá trị khi tạo bản đồ nhiệt hoặc thay đổi giá trị sau này bằng setGradient().
  3. Độ 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 Trình tạo để đặt giá trị khi tạo bản đồ nhiệt hoặc thay đổi giá trị sau này bằng setOpacity().

Ví dụ: tạo một Gradient để đặt vùng 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 mà dựa vào đó để tạo bản đồ nhiệt, hãy 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 biểu đồ nhiệt hoặc xoá điểm khỏi biểu đồ nhiệt, hãy cập nhật quy trình 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ạ

Để xem 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ạ.