Znaczniki

Wybierz platformę: Android iOS JavaScript

Mapa z kilkoma znacznikami

Znaczniki identyfikują lokalizacje na mapie. Domyślny znacznik używa standardowej ikony, która jest typowa dla wyglądu i działania Map Google. Za pomocą interfejsu API można zmienić kolor, obraz lub punkt kotwiczenia ikony. Znaczniki są obiektami typu Marker i są dodawane do mapy za pomocą metody GoogleMap.addMarker(markerOptions).

Znaczniki są interaktywne. Domyślnie odbierają zdarzenia click i są często używane z detektorami zdarzeń do wyświetlania okien informacyjnych. Ustawienie właściwości znacznika draggable na true umożliwia użytkownikowi zmianę pozycji znacznika. Aby aktywować możliwość przesuwania znacznika, przytrzymaj go.

Domyślnie, gdy użytkownik kliknie znacznik, w prawym dolnym rogu mapy pojawi się pasek narzędzi mapy, który zapewnia szybki dostęp do aplikacji mobilnej Mapy Google. Możesz wyłączyć pasek narzędzi. Więcej informacji znajdziesz w przewodniku po elementach sterujących.

Dodawanie znacznika

Ten przykład pokazuje, jak dodać znacznik do mapy. Znacznik jest tworzony we współrzędnych -33.852,151.211 (Sydney, Australia) i po kliknięciu wyświetla w oknie informacyjnym ciąg znaków „Marker in Sydney”.

Kotlin

// Add a marker in Sydney, Australia,
// and move the map's camera to the same location.
val sydney = LatLng(-33.852, 151.211)
val marker = map.addMarker(
    MarkerOptions()
        .position(sydney)
        .title("Marker in Sydney")
)
marker?.let {
    val position = it.position
    val title = it.title
    val snippet = it.snippet
    val isDraggable = it.isDraggable
    val isFlat = it.isFlat
    val isVisible = it.isVisible
    val alpha = it.alpha
    val rotation = it.rotation
    val zIndex = it.zIndex
}
map.moveCamera(CameraUpdateFactory.newLatLng(sydney))

      

Java

// Add a marker in Sydney, Australia,
// and move the map's camera to the same location.
LatLng sydney = new LatLng(-33.852, 151.211);
Marker marker = map.addMarker(new MarkerOptions()
    .position(sydney)
    .title("Marker in Sydney"));
map.moveCamera(CameraUpdateFactory.newLatLng(sydney));

      

Wyświetlanie dodatkowych informacji o znaczniku

Często trzeba wyświetlać dodatkowe informacje o miejscu lub lokalizacji, gdy użytkownik kliknie znacznik na mapie. Więcej informacji znajdziesz w przewodniku po oknach informacyjnych.

Powiązanie danych ze znacznikiem

Za pomocą metody Marker.setTag() możesz przechowywać dowolny obiekt danych ze znacznikiem, a za pomocą metody Marker.getTag() możesz go pobrać. Poniższy przykład pokazuje, jak za pomocą tagów zliczać kliknięcia znacznika:

Kotlin

val PERTH = LatLng(-31.952854, 115.857342)
val SYDNEY = LatLng(-33.87365, 151.20689)
val BRISBANE = LatLng(-27.47093, 153.0235)

val markerPerth = map.addMarker(
    MarkerOptions()
        .position(PERTH)
        .title("Perth")
)
markerPerth?.tag = 0

val markerSydney = map.addMarker(
    MarkerOptions()
        .position(SYDNEY)
        .title("Sydney")
)
markerSydney?.tag = 0

val markerBrisbane = map.addMarker(
    MarkerOptions()
        .position(BRISBANE)
        .title("Brisbane")
)
markerBrisbane?.tag = 0

// Set a listener for marker click.
map.setOnMarkerClickListener { marker ->
    // Retrieve the data from the marker.
    val clickCount = marker.tag as? Int

    // Check if a click count was set, then display the click count.
    clickCount?.let {
        val newClickCount = it + 1
        marker.tag = newClickCount
        Toast.makeText(
            context,
            "${marker.title} has been clicked $newClickCount times.",
            Toast.LENGTH_SHORT
        ).show()
    }

    // Return false to indicate default behavior.
    false
}

      

Java

final LatLng PERTH = new LatLng(-31.952854, 115.857342);
final LatLng SYDNEY = new LatLng(-33.87365, 151.20689);
final LatLng BRISBANE = new LatLng(-27.47093, 153.0235);

Marker markerPerth = map.addMarker(new MarkerOptions()
    .position(PERTH)
    .title("Perth"));
markerPerth.setTag(0);

Marker markerSydney = map.addMarker(new MarkerOptions()
    .position(SYDNEY)
    .title("Sydney"));
markerSydney.setTag(0);

Marker markerBrisbane = map.addMarker(new MarkerOptions()
    .position(BRISBANE)
    .title("Brisbane"));
markerBrisbane.setTag(0);

// Set a listener for marker click.
map.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
    @Override
    public boolean onMarkerClick(final Marker marker) {
        // Retrieve the data from the marker.
        Integer clickCount = (Integer) marker.getTag();

        // Check if a click count was set, then display the click count.
        if (clickCount != null) {
            clickCount = clickCount + 1;
            marker.setTag(clickCount);
            Toast.makeText(context,
                marker.getTitle() + " has been clicked " + clickCount + " times.",
                Toast.LENGTH_SHORT).show();
        }

        // Return false to indicate default behavior should occur.
        return false;
    }
});

      

Oto kilka przykładów sytuacji, w których warto przechowywać i pobierać dane za pomocą znaczników:

  • Twoja aplikacja może obsługiwać różne typy znaczników i chcesz je inaczej traktować, gdy użytkownik je kliknie. Aby to zrobić, możesz zapisać ze znacznikiem ciąg znaków String wskazujący jego typ.
  • Możesz korzystać z systemu, który ma unikalne identyfikatory rekordów, a znaczniki reprezentują konkretne rekordy w tym systemie.
  • Dane znacznika mogą wskazywać priorytet, który ma być używany podczas określania indeksu z znacznika.

Ustawianie znacznika jako przeciągalnego

Po dodaniu znacznika do mapy możesz zmienić jego położenie, o ile jego właściwość draggable jest ustawiona na true. Aby włączyć przeciąganie, przytrzymaj znacznik. Gdy odsuniesz palec od ekranu, znacznik pozostanie w tym miejscu.

Znaczniki nie są domyślnie przeciągalne. Musisz wyraźnie ustawić znacznik jako przeciągalny za pomocą metody MarkerOptions.draggable(boolean) przed dodaniem go do mapy lub za pomocą metody Marker.setDraggable(boolean) po dodaniu go do mapy. Możesz nasłuchiwać zdarzeń przeciągania znacznika, jak opisano w sekcji Zdarzenia przeciągania znacznika.

Poniższy fragment kodu dodaje przeciągalny znacznik w Perth w Australii.

Kotlin

val perthLocation = LatLng(-31.90, 115.86)
val perth = map.addMarker(
    MarkerOptions()
        .position(perthLocation)
        .draggable(true)
)
map.moveCamera(com.google.android.gms.maps.CameraUpdateFactory.newLatLngZoom(perthLocation, 10f))

      

Java

final LatLng perthLocation = new LatLng(-31.90, 115.86);
Marker perth = map.addMarker(
    new MarkerOptions()
        .position(perthLocation)
        .draggable(true));
map.moveCamera(com.google.android.gms.maps.CameraUpdateFactory.newLatLngZoom(perthLocation, 10f));

      

Dostosowywanie znacznika

Ten film pokazuje, jak używać znaczników do wizualizacji lokalizacji na mapie.

Znaczniki mogą definiować niestandardowy obraz, który ma być wyświetlany zamiast ikony domyślnej. Definiowanie ikony polega na ustawieniu kilku właściwości, które wpływają na wizualne zachowanie znacznika.

Znaczniki można dostosowywać za pomocą tych właściwości:

Położenie (wymagane)
Wartość LatLng określająca położenie znacznika na mapie. Jest to jedyna wymagana właściwość obiektu Marker.
Kotwica
Punkt na obrazie, który zostanie umieszczony w pozycji LatLng znacznika. Domyślnie jest to środek dolnej części obrazu.
Alfa
Ustawia przezroczystość znacznika. Domyślna wartość to 1.0.
Tytuł
Ciąg znaków wyświetlany w oknie informacyjnym, gdy użytkownik kliknie znacznik.
Krótki opis
Dodatkowy tekst wyświetlany pod tytułem.
Ikona
Bitmapa wyświetlana zamiast domyślnego obrazu znacznika.
Element przeciągalny
Ustaw na true jeśli chcesz zezwolić użytkownikowi na przesuwanie znacznika. Domyślna wartość to false.
Widoczne
Ustaw na false, aby znacznik był niewidoczny. Domyślna wartość to true.
Orientacja płaska lub billboardowa
Domyślnie znaczniki używają orientacji billboardowej, co oznacza, że są rysowane w orientacji względem ekranu urządzenia, a nie powierzchni mapy. Obracanie, przechylanie lub powiększanie mapy nie zmienia orientacji znacznika. Możesz ustawić orientację znacznika tak, aby był płaski względem ziemi. Płaskie znaczniki obracają się, gdy mapa jest obracana, i zmieniają perspektywę, gdy mapa jest przechylana. Podobnie jak w przypadku znaczników billboardowych, płaskie znaczniki zachowują swój rozmiar, gdy mapa jest powiększana lub pomniejszana.
Obrót
Orientacja znacznika określona w stopniach zgodnie z ruchem wskazówek zegara. Pozycja domyślna zmienia się, jeśli znacznik jest płaski. Domyślna pozycja płaskiego znacznika jest wyrównana do północy. Gdy znacznik nie jest płaski, pozycja domyślna jest skierowana do góry, a obrót jest taki, że znacznik jest zawsze skierowany w stronę kamery.

Poniższy fragment kodu tworzy prosty znacznik z ikoną domyślną.

Kotlin

val melbourneLocation = LatLng(-37.813, 144.962)
val melbourne = map.addMarker(
    MarkerOptions()
        .position(melbourneLocation)
)

      

Java

final LatLng melbourneLocation = new LatLng(-37.813, 144.962);
Marker melbourne = map.addMarker(
    new MarkerOptions()
        .position(melbourneLocation));

      

Dostosowywanie koloru znacznika

Możesz dostosować kolor domyślnego obrazu znacznika, przekazując obiekt BitmapDescriptor do metody icon(). Możesz użyć zestawu predefiniowanych kolorów w obiekcieBitmapDescriptorFactory lub ustawić niestandardowy kolor znacznika za pomocą metody BitmapDescriptorFactory.defaultMarker(float hue). Odcień to wartość z zakresu od 0 do 360, która reprezentuje punkty na kole kolorów.

Kotlin

val melbourneLocation = LatLng(-37.813, 144.962)
val melbourne = map.addMarker(
    MarkerOptions()
        .position(melbourneLocation)
        .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE))
)

      

Java

final LatLng melbourneLocation = new LatLng(-37.813, 144.962);
Marker melbourne = map.addMarker(
    new MarkerOptions()
        .position(melbourneLocation)
        .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE)));

      

Dostosowywanie przezroczystości znacznika

Przezroczystość znacznika możesz kontrolować za pomocą metody MarkerOptions.alpha(). Wartość alfa powinna być określona jako liczba zmiennoprzecinkowa z zakresu od 0,0 do 1,0, gdzie 0 oznacza pełną przezroczystość, a 1 – pełną nieprzezroczystość.

Kotlin

val melbourneLocation = LatLng(-37.813, 144.962)
val melbourne = map.addMarker(
    MarkerOptions()
        .position(melbourneLocation)
        .alpha(0.7f)
)

      

Java

final LatLng melbourneLocation = new LatLng(-37.813, 144.962);
Marker melbourne = map.addMarker(new MarkerOptions()
    .position(melbourneLocation)
    .alpha(0.7f));

      

Dostosowywanie obrazu znacznika

Możesz zastąpić domyślny obraz znacznika niestandardowym obrazem, często nazywanym ikoną. Ikony niestandardowe są zawsze ustawiane jako BitmapDescriptor i definiowane za pomocą jednej z metod w BitmapDescriptorFactory klasie.

fromAsset(String assetName)
Tworzy niestandardowy znacznik na podstawie nazwy obrazu bitmapowego w katalogu zasobów.
fromBitmap(Bitmap image)
Tworzy niestandardowy znacznik na podstawie obrazu bitmapowego.
fromFile(String fileName)
Tworzy niestandardową ikonę na podstawie nazwy pliku obrazu bitmapowego znajdującego się w pamięci wewnętrznej.
fromPath(String absolutePath)
Tworzy niestandardowy znacznik na podstawie bezwzględnej ścieżki pliku obrazu bitmapowego.
fromResource(int resourceId)
Tworzy niestandardowy znacznik na podstawie identyfikatora zasobu obrazu bitmapowego.

Poniższy fragment kodu tworzy znacznik z ikoną niestandardową.

Kotlin

val melbourneLocation = LatLng(-37.813, 144.962)
val melbourne = map.addMarker(
    MarkerOptions()
        .position(melbourneLocation)
        .title("Melbourne")
        .snippet("Population: 4,137,400")
        .icon(BitmapDescriptorFactory.fromResource(R.drawable.arrow))
)

      

Java

final LatLng melbourneLocation = new LatLng(-37.813, 144.962);
Marker melbourne = map.addMarker(
    new MarkerOptions()
        .position(melbourneLocation)
        .title("Melbourne")
        .snippet("Population: 4,137,400")
        .icon(BitmapDescriptorFactory.fromResource(R.drawable.arrow)));

      

Spłaszczanie znacznika

Ikony znaczników są zwykle rysowane względem ekranu. Obracanie, przechylanie lub powiększanie mapy nie zmienia orientacji znacznika. Możesz ustawić orientację znacznika tak, aby był płaski względem ziemi. Znaczniki zorientowane w ten sposób będą się obracać, gdy mapa jest obracana, i zmieniać perspektywę, gdy mapa jest przechylana. Płaskie znaczniki zachowują swój rozmiar, gdy mapa jest powiększana lub pomniejszana.

Aby zmienić orientację znacznika, ustaw jego właściwość flat na true.

Kotlin

val perthLocation = LatLng(-31.90, 115.86)
val perth = map.addMarker(
    MarkerOptions()
        .position(perthLocation)
        .flat(true)
)

      

Java

final LatLng perthLocation = new LatLng(-31.90, 115.86);
Marker perth = map.addMarker(
    new MarkerOptions()
        .position(perthLocation)
        .flat(true));

      

Obracanie znacznika

Możesz obracać znacznik wokół jego punktu kotwiczenia za pomocą metody Marker.setRotation(). Obrót jest mierzony w stopniach zgodnie z ruchem wskazówek zegara od pozycji domyślnej. Gdy znacznik jest płaski na mapie, pozycja domyślna to północ. Gdy znacznik nie jest płaski, pozycja domyślna jest skierowana do góry, a obrót jest taki, że znacznik jest zawsze skierowany w stronę kamery.

W przykładzie poniżej znacznik jest obracany o 90°. Ustawienie punktu kotwiczenia na 0.5,0.5 powoduje, że znacznik jest obracany wokół środka, a nie podstawy.

Kotlin

val perthLocation = LatLng(-31.90, 115.86)
val perth = map.addMarker(
    MarkerOptions()
        .position(perthLocation)
        .anchor(0.5f, 0.5f)
        .rotation(90.0f)
)

      

Java

final LatLng perthLocation = new LatLng(-31.90, 115.86);
Marker perth = map.addMarker(
    new MarkerOptions()
        .position(perthLocation)
        .anchor(0.5f,0.5f)
        .rotation(90.0f));

      

Indeks z znacznika

Indeks z określa kolejność stosu tego znacznika względem innych znaczników na mapie. Znacznik z wysokim indeksem z jest rysowany na wierzchu znaczników z niższymi indeksami z. Domyślna wartość indeksu z to 0.

Ustaw indeks z w obiekcie opcji znacznika, wywołując metodę MarkerOptions.zIndex(), jak pokazano w tym fragmencie kodu:

Kotlin

map.addMarker(
    MarkerOptions()
        .position(LatLng(10.0, 10.0))
        .title("Marker z1")
        .zIndex(1.0f)
)

      

Java

map.addMarker(new MarkerOptions()
    .position(new LatLng(10, 10))
    .title("Marker z1")
    .zIndex(1.0f));

      

Możesz uzyskać dostęp do indeksu z znacznika, wywołując metodę Marker.getZIndex(), i zmienić go, wywołując metodę Marker.setZIndex().

Znaczniki są zawsze rysowane nad warstwami kafelków i innymi nakładkami innymi niż znaczniki (nakładki na ziemię, polilinie, wielokąty i inne kształty) niezależnie od indeksu z innych nakładek. Znaczniki są traktowane jako należące do oddzielnej grupy indeksów z w porównaniu z innymi nakładkami.

Poniżej znajdziesz informacje o wpływie indeksu z na zdarzenia kliknięcia.

Obsługa zdarzeń znacznika

Interfejs API Map Google umożliwia nasłuchiwanie zdarzeń znacznika i reagowanie na nie. Aby nasłuchiwać tych zdarzeń, musisz ustawić odpowiedni detektor w obiekcie GoogleMap, do którego należą znaczniki. Gdy zdarzenie wystąpi na jednym ze znaczników na mapie, wywołanie zwrotne detektora zostanie wywołane z odpowiednim obiektem Marker przekazanym jako parametr. Aby porównać ten obiekt Marker z własnym odniesieniem do obiektu Marker, musisz użyć metody equals() zamiast operatora ==.

Możesz nasłuchiwać tych zdarzeń:

Zdarzenia kliknięcia znacznika

Aby nasłuchiwać zdarzeń kliknięcia znacznika, możesz użyć interfejsu OnMarkerClickListener do nasłuchiwania zdarzeń kliknięcia znacznika. Aby ustawić ten detektor na mapie, wywołaj metodę GoogleMap.setOnMarkerClickListener(OnMarkerClickListener). Gdy użytkownik kliknie znacznik, zostanie wywołana metoda onMarkerClick(Marker), a znacznik zostanie przekazany jako argument. Ta metoda zwraca wartość logiczną wskazującą, czy zdarzenie zostało przez Ciebie wykorzystane (tzn. czy chcesz pominąć domyślne działanie). Jeśli zwróci false, oprócz Twojego niestandardowego działania zostanie wykonane działanie domyślne. Domyślne działanie w przypadku zdarzenia kliknięcia znacznika polega na wyświetleniu jego okna informacyjnego (jeśli jest dostępne) i przesunięciu kamery tak, aby znacznik był wyśrodkowany na mapie.

Wpływ indeksu z na zdarzenia kliknięcia:

  • Gdy użytkownik kliknie klaster znaczników, zdarzenie kliknięcia zostanie wywołane dla znacznika z najwyższym indeksem z.
  • Na kliknięcie wywoływane jest co najwyżej 1 zdarzenie. Innymi słowy, kliknięcie nie jest przekazywane do znaczników ani innych nakładek z niższymi wartościami indeksu z.
  • Kliknięcie klastra znaczników powoduje, że kolejne kliknięcia przechodzą przez klaster, wybierając każdy znacznik po kolei. Kolejność cyklu najpierw określa indeks z, a potem odległość od punktu kliknięcia.
  • Jeśli użytkownik kliknie poza obszarem klastra, interfejs API ponownie obliczy klaster i zresetuje stan cyklu kliknięć, aby rozpocząć go od początku.
  • Znaczniki są traktowane jako należące do oddzielnej grupy indeksów z w porównaniu z innymi nakładkami lub kształtami (polilinie, wielokąty, okręgi i/lub nakładki na ziemię) niezależnie od indeksu z innych nakładek. Jeśli kilka znaczników, nakładek lub kształtów jest nałożonych na siebie, zdarzenie kliknięcia jest najpierw przekazywane przez klaster znaczników.

Zdarzenia przeciągania znacznika

Aby nasłuchiwać zdarzeń przeciągania znacznika, możesz użyć interfejsu OnMarkerDragListener. Aby ustawić ten detektor na mapie, wywołaj metodę GoogleMap.setOnMarkerDragListener. Aby przeciągnąć znacznik, użytkownik musi go przytrzymać. Gdy użytkownik odsunie palec od ekranu, znacznik pozostanie w tym miejscu. Gdy znacznik jest przeciągany, początkowo wywoływana jest metoda onMarkerDragStart(Marker). Podczas przeciągania znacznika stale wywoływana jest metoda onMarkerDrag(Marker). Na końcu przeciągania wywoływana jest metoda onMarkerDragEnd(Marker). Położenie znacznika możesz uzyskać w dowolnym momencie, wywołując metodę Marker.getPosition().