Narzędzie do grupowania znaczników na Androida w Mapach Google

Wybierz platformę: Android iOS JavaScript

Dzięki grupowaniu znaczników możesz umieścić na mapie dużą liczbę znaczników, nie powodując, że mapa będzie czytelna.

Wstęp

W tym filmie omawiamy stosowanie grupowania znaczników w sytuacji, gdy dane wymagają dużej liczby punktów danych na mapie.

Narzędzie do grupowania znaczników ułatwia zarządzanie wieloma znacznikami na różnych poziomach powiększenia. Znaczniki są w tym momencie w rzeczywistości „elementami” i zmieniają się po wyrenderowaniu. Ze względu na przejrzystość w tym dokumencie w całej części dokumentu będą one zatytułowane „znaczniki”.

Gdy użytkownik wyświetla mapę w dużym powiększeniu, poszczególne znaczniki są widoczne na mapie. Gdy użytkownik pomniejsza mapę, znaczniki zbierają się w klastry, aby ułatwić przeglądanie mapy. Narzędzie do grupowania znaczników jest częścią biblioteki narzędziowej pakietu Maps SDK na Androida. Jeśli nie masz jeszcze skonfigurowanej biblioteki, zapoznaj się z pozostałą częścią tej strony, postępując zgodnie z przewodnikiem po konfiguracji.

Mapa ze zgrupowanymi znacznikami
Znaczniki grupowane

Aby użyć narzędzia do grupowania znaczników, musisz dodać znaczniki jako obiekty ClusterItem do ClusterManager. ClusterManager przekazuje znaczniki do klastra Algorithm, który przekształca je w zestaw klastrów. ClusterRenderer zajmuje się renderowaniem, dodawanie i usuwanie klastrów oraz poszczególnych znaczników. Urządzenia ClusterRenderer i Algorithm można podłączyć i dostosować.

Biblioteka narzędziowa zawiera aplikację demonstracyjną z przykładowymi implementacjami narzędzia do grupowania znaczników. Pomoc dotyczącą uruchamiania aplikacji demonstracyjnej znajdziesz w przewodniku po konfiguracji. Aplikacja demonstracyjna zawiera te przykłady grupowania znaczników:

  • ClusteringDemoActivity: prosta aktywność pokazująca grupowanie znaczników.
  • BigClusteringDemoActivity: klaster zawierający 2000 znaczników.
  • CustomMarkerClusteringDemoActivity: tworzenie niestandardowego projektu dla znaczników klastrów.

Dodaj prosty klaster znaczników

Wykonaj opisane poniżej czynności, aby utworzyć prosty klaster składający się z 10 znaczników. Wynik będzie wyglądał tak, ale liczba wyświetlanych/grupowanych znaczników będzie zmieniać się w zależności od poziomu powiększenia:

Mapa z 10 grupami znaczników
Dziesięć znaczników w klastrze

Oto podsumowanie wymaganych kroków:

  1. Wdróż ClusterItem, aby wskazać znacznik na mapie. Element klastra zwraca pozycję znacznika jako obiektu LatLng oraz opcjonalny tytuł lub fragment.
  2. Dodaj nowy obiekt ClusterManager, aby pogrupować elementy (znaczniki) klastra według poziomu powiększenia.
  3. Ustaw OnCameraIdleListener() mapy na ClusterManager, ponieważ ClusterManager implementuje odbiornik.
  4. Jeśli chcesz dodać określoną funkcję w odpowiedzi na zdarzenie kliknięcia znacznika, ustaw OnMarkerClickListener() mapy na ClusterManager, ponieważ ClusterManager implementuje odbiornik.
  5. Umieść znaczniki na serwerze ClusterManager.

Więcej informacji o krokach: aby utworzyć nasz prosty klaster z 10 znacznikami, najpierw utwórz klasę MyItem z implementacją ClusterItem.

Kotlin



inner class MyItem(
    lat: Double,
    lng: Double,
    title: String,
    snippet: String
) : ClusterItem {

    private val position: LatLng
    private val title: String
    private val snippet: String

    override fun getPosition(): LatLng {
        return position
    }

    override fun getTitle(): String {
        return title
    }

    override fun getSnippet(): String {
        return snippet
    }

    override fun getZIndex(): Float {
        return 0f
    }

    init {
        position = LatLng(lat, lng)
        this.title = title
        this.snippet = snippet
    }
}

      

Java


public class MyItem implements ClusterItem {
    private final LatLng position;
    private final String title;
    private final String snippet;

    public MyItem(double lat, double lng, String title, String snippet) {
        position = new LatLng(lat, lng);
        this.title = title;
        this.snippet = snippet;
    }

    @Override
    public LatLng getPosition() {
        return position;
    }

    @Override
    public String getTitle() {
        return title;
    }

    @Override
    public String getSnippet() {
        return snippet;
    }

    @Nullable
    @Override
    public Float getZIndex() {
        return 0f;
    }
}

      

W aktywności na mapie dodaj ClusterManager i prześlij mu elementy klastra. Zwróć uwagę na argument typu <MyItem>, który deklaruje, że ClusterManager jest typu MyItem.

Kotlin



// Declare a variable for the cluster manager.
private lateinit var clusterManager: ClusterManager<MyItem>

private fun setUpClusterer() {
    // Position the map.
    map.moveCamera(CameraUpdateFactory.newLatLngZoom(LatLng(51.503186, -0.126446), 10f))

    // Initialize the manager with the context and the map.
    // (Activity extends context, so we can pass 'this' in the constructor.)
    clusterManager = ClusterManager(context, map)

    // Point the map's listeners at the listeners implemented by the cluster
    // manager.
    map.setOnCameraIdleListener(clusterManager)
    map.setOnMarkerClickListener(clusterManager)

    // Add cluster items (markers) to the cluster manager.
    addItems()
}

private fun addItems() {

    // Set some lat/lng coordinates to start with.
    var lat = 51.5145160
    var lng = -0.1270060

    // Add ten cluster items in close proximity, for purposes of this example.
    for (i in 0..9) {
        val offset = i / 60.0
        lat += offset
        lng += offset
        val offsetItem =
            MyItem(lat, lng, "Title $i", "Snippet $i")
        clusterManager.addItem(offsetItem)
    }
}

      

Java


// Declare a variable for the cluster manager.
private ClusterManager<MyItem> clusterManager;

private void setUpClusterer() {
    // Position the map.
    map.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(51.503186, -0.126446), 10));

    // Initialize the manager with the context and the map.
    // (Activity extends context, so we can pass 'this' in the constructor.)
    clusterManager = new ClusterManager<MyItem>(context, map);

    // Point the map's listeners at the listeners implemented by the cluster
    // manager.
    map.setOnCameraIdleListener(clusterManager);
    map.setOnMarkerClickListener(clusterManager);

    // Add cluster items (markers) to the cluster manager.
    addItems();
}

private void addItems() {

    // Set some lat/lng coordinates to start with.
    double lat = 51.5145160;
    double lng = -0.1270060;

    // Add ten cluster items in close proximity, for purposes of this example.
    for (int i = 0; i < 10; i++) {
        double offset = i / 60d;
        lat = lat + offset;
        lng = lng + offset;
        MyItem offsetItem = new MyItem(lat, lng, "Title " + i, "Snippet " + i);
        clusterManager.addItem(offsetItem);
    }
}

      

Możesz też wyłączyć animacje grupowania podczas powiększania i pomniejszania. Jeśli animacja jest wyłączona, znaczniki są ustawiane na odpowiednich pozycjach, zamiast przenosić się do i z klastrów. Aby wyłączyć animacje, użyj w polu ClusterManager parametru setAnimation(), jak pokazano poniżej:

Kotlin



clusterManager.setAnimation(false)

      

Java


clusterManager.setAnimation(false);

      

Dodawanie okna informacyjnego dla pojedynczego znacznika grupowego

Aby dodać okno informacyjne dla określonych znaczników klastra, dodaj ciągi tytułu i fragmentu kodu do konstruktora swojej implementacji ClusterItem.

Poniższy przykład pokazuje w metodzie addItems() znacznik z oknem informacyjnym, ustawiając tytuł i krótki opis:

Kotlin



// Set the lat/long coordinates for the marker.
val lat = 51.5009
val lng = -0.122

// Set the title and snippet strings.
val title = "This is the title"
val snippet = "and this is the snippet."

// Create a cluster item for the marker and set the title and snippet using the constructor.
val infoWindowItem = MyItem(lat, lng, title, snippet)

// Add the cluster item (marker) to the cluster manager.
clusterManager.addItem(infoWindowItem)

      

Java


// Set the lat/long coordinates for the marker.
double lat = 51.5009;
double lng = -0.122;

// Set the title and snippet strings.
String title = "This is the title";
String snippet = "and this is the snippet.";

// Create a cluster item for the marker and set the title and snippet using the constructor.
MyItem infoWindowItem = new MyItem(lat, lng, title, snippet);

// Add the cluster item (marker) to the cluster manager.
clusterManager.addItem(infoWindowItem);

      

Dostosowywanie klastrów znaczników

Konstruktor ClusterManager tworzy DefaultClusterRenderer i NonHierarchicalDistanceBasedAlgorithm. Możesz zmienić ClusterRenderer i Algorithm za pomocą metod setAlgorithm(Algorithm<T> algorithm) i setRenderer(ClusterRenderer<T> view) właściwości ClusterManager.

Aby dostosować renderowanie klastrów, możesz zastosować ClusterRenderer. DefaultClusterRenderer to dobry wybór na początek. Dzięki podklasyfikacji DefaultClusterRenderer możesz zastąpić ustawienia domyślne.

Szczegółowy przykład dostosowania znajdziesz w CustomMarkerClusteringDemoActivity w aplikacji demonstracyjnej, która zawiera bibliotekę narzędziową.

Mapa z niestandardowymi znacznikami klastrami
Niestandardowe znaczniki klastrów

CustomMarkerClusteringDemoActivity definiuje własny element klastra (Person) i renderuje go, rozszerzając DefaultClusterRenderer jako PersonRenderer.

Demonstracja pokazuje też, jak wdrożyć interfejs ClusterManager.OnClusterClickListener<Person>, aby wyświetlać więcej informacji o osobie po kliknięciu klastra. W podobny sposób możesz też zaimplementować ClusterManager.OnClusterItemClickListener<Person>.

Pomoc dotyczącą uruchamiania aplikacji demonstracyjnej znajdziesz w przewodniku po konfiguracji.