Утилита для работы с тепловыми картами в Google Картах на Android

Тепловые карты используются для визуализации распределения и плотности точек данных на карте.

Введение

Библиотека утилит Maps SDK для Android содержит утилиту для работы с тепловыми картами. С ее помощью можно добавить одну или несколько тепловых карт на Google Карты в вашем приложении.

В этом видеоролике обсуждается использование тепловых карт в качестве альтернативы маркерам, когда ваши данные отображаются большим количеством точек на карте.

Тепловые карты помогают пользователям понять распределение и относительную интенсивность точек данных на карте. На тепловых картах распределение данных визуализируется с помощью цветов, а не отдельных маркеров в каждой точке, о которой имеются данные.

В приведенном ниже примере красным цветом обозначены области с большим количеством полицейских участков в австралийском городе Виктория.

Тепловая карта расположения полицейских участков
Тепловая карта

Если вы еще не настроили библиотеку утилит Maps SDK для Android, выполните инструкции из этого руководства, прежде чем продолжить чтение данной статьи.

Как добавить простую тепловую карту

Чтобы добавить тепловую карту в приложение, вам понадобится набор данных, состоящий из координат каждого интересующего вас места. Сначала создайте объект HeatmapTileProvider и передайте ему коллекцию объектов LatLng. Затем создайте новый объект TileOverlay, передав ему объект поставщика фрагментов тепловой карты, и добавьте мозаичное наложение на карту.

Утилита предоставляет класс HeatmapTileProvider, который реализует интерфейс TileProvider, предоставляющий изображения фрагментов для тепловой карты. HeatmapTileProvider принимает коллекцию объектов LatLng (или объектов 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().weightedData() (вместо метода HeatmapTileProvider.Builder().data()), чтобы создать тепловую карту.

Как настроить тепловую карту

Многие свойства тепловой карты можно изменить. Необходимые параметры можно установить с помощью функций Builder при создании тепловой карты. Вы также можете изменить параметр в любое время, вызвав соответствующий сеттер объекта HeatmapTileProvider, а затем очистив кеш накладываемых фрагментов, чтобы повторно перерисовать все фрагменты с применением новых параметров.

Доступны описанные ниже параметры.

  1. Radius (Радиус). Размер гауссова размытия, применяемого к тепловой карте, выраженный в пикселях. Значение по умолчанию – 20. Допустимый диапазон значений – от 10 до 50. Используйте метод radius() класса Builder, чтобы задать значение при создании тепловой карты, или измените значение позже с помощью метода setRadius().
  2. Gradient (Градиент). Диапазон цветов, используемый при создании карты цветов для тепловой карты, в диапазоне от минимальной до максимальной интенсивности. Для создания градиента используются два массива: массив целочисленных значений (integer), содержащий цвета, и массив значений с плавающей запятой (float), указывающий начальную точку для каждого цвета. Последний массив представлен процентными значениями от максимальной интенсивности, которые выражаются дробной величиной от нуля до единицы. Для одноцветного градиента необходимо указать только один цвет, а для многоцветного – как минимум два. Для создания карты цветов используется интерполяция между этими цветами. По умолчанию градиент содержит два цвета. Используйте метод gradient() класса Builder, чтобы задать значение при создании тепловой карты, или измените значение позже с помощью метода setGradient().
  3. Opacity (Непрозрачность). Это непрозрачность всего слоя тепловой карты. Диапазон допустимых значений – от 0 до 1. Значение по умолчанию – 0,7. Используйте метод opacity() класса Builder, чтобы задать значение при создании тепловой карты, или измените значение позже с помощью метода 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()
      

Как изменить набор данных

Чтобы изменить набор данных, на основе которого создается тепловая карта, используйте метод HeatmapTileProvider.setData() (или метод HeatmapTileProvider.setWeightedData()для точек со взвешенными координатами WeightedLatLng). Примечание. Чтобы добавить или удалить точки на тепловой карте, обновите свою коллекцию данных, а затем вызовите метод 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 демонстрационного приложения из библиотеки утилит. В руководстве по настройке рассказывается, как запустить демонстрационное приложение.