Mapy termiczne są przydatne do przedstawiania rozkładu i gęstości punktów danych na mapie.
Wstęp
Biblioteka narzędziowa pakietu Maps SDK na Androida zawiera narzędzie mapy termicznej, za pomocą którego możesz dodać do mapy Google w swojej aplikacji jedną lub więcej map termicznych.
W tym filmie omawiamy użycie map termicznych jako alternatywy dla znaczników, gdy dane wymagają dużej liczby punktów danych na mapie.
Mapy termiczne ułatwiają widzom zrozumienie rozkładu i względnej intensywności punktów danych na mapie. Zamiast umieszczania znacznika w każdej lokalizacji, mapy termiczne wykorzystują kolor do reprezentowania rozkładu danych.
W poniższym przykładzie kolor czerwony oznacza obszary o dużym zagęszczeniu komisariatów policji w Victorii w Australii.
Jeśli nie masz jeszcze skonfigurowanej biblioteki narzędziowej pakietu Maps SDK na Androida, zapoznaj się z pozostałą częścią tej strony, postępując zgodnie z przewodnikiem konfiguracji.
Dodaj prostą mapę termiczną
Aby dodać do mapy mapę termiczną, potrzebujesz zbioru danych zawierającego współrzędne każdej interesującej Cię lokalizacji. Najpierw utwórz HeatmapTileProvider
, przekazując go do kolekcji obiektów LatLng
. Następnie utwórz nowy obiekt TileOverlay
, który będzie przekazywać go jako dostawcę kafelka mapy termicznej, i dodaj do mapy nakładkę z kafelkami.
Narzędzie dostarcza klasę HeatmapTileProvider
, która implementuje interfejs TileProvider
w celu dostarczania obrazów kafelków na potrzeby mapy termicznej.
HeatmapTileProvider
akceptuje zbiór obiektów LatLng
(lub WeightedLatLng
, jak opisano poniżej). Tworzy obrazki kafelków o różnych poziomach powiększenia w zależności od dostępnych opcji promienia, gradientu i nieprzezroczystości. Możesz zmienić wartości domyślne tych opcji.
Szczegółowy opis poszczególnych kroków:
- Użyj
HeatmapTileProvider.Builder()
, aby dodać do niej zbiórLatLng
obiektów, aby dodać nowy obiektHeatmapTileProvider
. - Utwórz nowy obiekt
TileOverlayOptions
z odpowiednimi opcjami, w tym zHeatmapTileProvider
. - Aby dodać nakładkę do mapy, wywołaj
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; }
W tym przykładzie dane zostaną zapisane w pliku JSON o nazwie police_stations.json
. Oto fragment z pliku:
[ {"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 } ]
Użyj ważonych punktów szerokości i długości geograficznej
Podczas tworzenia obiektu HeatmapTileProvider
możesz przekazać mu zbiór ważonych współrzędnych szerokości i długości geograficznej. Jest to przydatne, gdy chcesz pokazać znaczenie określonego zestawu lokalizacji.
Aby zastosować wagi do określonych lokalizacji:
- Utwórz nową właściwość
WeightedLatLng
dla każdej lokalizacji, która wymaga wagi. Podaj w polachLatLng
idouble
, które wskazują wymaganą intensywność. Intensywność wskazuje względne znaczenie lub wartość danej lokalizacji. Wyższa wartość oznacza intensywniejszy kolor w gradiencie mapy termicznej. Domyślnie kolorem o największej intensywności jest czerwony. Aby utworzyć mapę termiczną, wywołaj
HeatmapTileProvider.Builder().weightedData()
zamiastHeatmapTileProvider.Builder().data()
.
Dostosuj mapę termiczną
Kilka właściwości mapy termicznej można dostosować. Opcje możesz ustawić podczas tworzenia za pomocą funkcji Builder
.
Możesz też w dowolnym momencie zmienić opcję, wywołując odpowiednią metodę ustawiającą w HeatmapTileProvider
, a następnie wyczyść pamięć podręczną kafelków nakładki, aby ponownie rysować wszystkie kafelki z nowymi opcjami.
Dostępne są te ustawienia:
- Promień: rozmiar rozmycia Gaussa zastosowanego do mapy termicznej, wyrażony w pikselach. Wartość domyślna to 20. Wartość musi mieścić się w zakresie od 10 do 50. Użyj
radius()
konstruktora, aby ustawić wartość podczas tworzenia mapy termicznej, lub zmień ją później za pomocąsetRadius()
. - Gradient: zakres kolorów używanych przez mapę termiczną do wygenerowania mapy kolorów – od najniższej do największej intensywności. Gradient jest tworzony za pomocą 2 tablic: liczb całkowitych zawierających kolory oraz tablicy zmiennoprzecinkowej, która wskazuje punkt początkowy każdego koloru, wyrażona jako procent maksymalnej intensywności i wyrażona jako ułamek od 0 do 1. Dla gradientu jednokolorowego musisz określić tylko jeden kolor, a dla gradientu wielokolorowego – co najmniej dwa. Mapa kolorów jest generowana przez interpolację między tymi kolorami. Gradient domyślny ma 2 kolory. Użyj
gradient()
konstruktora, aby ustawić wartość podczas tworzenia mapy termicznej, lub zmień ją później wsetGradient()
. - Przezroczystość: przezroczystość całej warstwy mapy termicznej mieści się w zakresie od 0 do 1. Wartością domyślną jest 0,7. Użyj właściwości
opacity()
konstruktora, aby ustawić wartość podczas tworzenia mapy termicznej, lub zmień ją później za pomocą funkcjisetOpacity()
.
Na przykład utwórz Gradient
, aby ustawić gradient przed dodaniem mapy termicznej:
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));
Aby zmienić przezroczystość istniejącej mapy termicznej:
Kotlin
provider.setOpacity(0.7) tileOverlay?.clearTileCache()
Java
provider.setOpacity(0.7); tileOverlay.clearTileCache();
Zmiana zbioru danych
Aby zmienić zbiór danych, na podstawie którego powstaje mapa termiczna, użyj właściwości HeatmapTileProvider.setData()
lub HeatmapTileProvider.setWeightedData()
dla WeightedLatLng
punktów. Uwaga: jeśli chcesz dodać punkty do mapy termicznej lub usunąć je z mapy termicznej, zaktualizuj zbiór danych, a potem użyj właściwości setData()
lub setWeightedData()
.
Kotlin
val data: List<WeightedLatLng> = ArrayList() provider.setWeightedData(data) tileOverlay?.clearTileCache()
Java
List<WeightedLatLng> data = new ArrayList<>(); provider.setWeightedData(data); tileOverlay.clearTileCache();
Usuwanie mapy termicznej
Aby usunąć mapę termiczną, musisz usunąć nakładkę z kafelkami:
Kotlin
tileOverlay?.remove()
Java
tileOverlay.remove();
Zobacz aplikację demonstracyjną
Innym przykładem implementacji mapy termicznej jest HeatmapsDemoActivity
w aplikacji demonstracyjnej, która udostępnia bibliotekę narzędziową. Z przewodnika po konfiguracji dowiesz się, jak uruchomić aplikację w wersji demonstracyjnej.