Markierungen

Mit Markierungen werden einzelne Standorte auf der Karte gekennzeichnet. Du kannst sie anpassen, indem du die Standardfarbe änderst oder das Markierungssymbol durch ein benutzerdefiniertes Bild ersetzt. Über Infofenster kann zusätzlicher Kontext für eine Markierung geliefert werden.

Codebeispiele

Das ApiDemos-Repository auf GitHub enthält ein Beispiel, das verschiedene Markierungsfunktionen zeigt:

Einführung

Mithilfe von Markierungen lassen sich Standorte auf einer Karte kennzeichnen. Für die Standardmarkierung wird ein Standardsymbol verwendet, das dem üblichen Google Maps-Design entspricht. Du kannst aber die Farbe des Symbols, das Bild oder den Ankerpunkt mithilfe der API ändern. Markierungen sind Objekte vom Typ Marker und werden über die Methode GoogleMap.addMarker(markerOptions) der Karte hinzugefügt.

Die Markierungen sind interaktiv konzipiert. Sie empfangen standardmäßig click-Ereignisse und werden häufig zusammen mit Ereignis-Listenern verwendet, um Infofenster aufzurufen. Wenn die Eigenschaft draggable auf true festgelegt wird, können Nutzer die Position der Markierung ändern. Durch langes Drücken wird die Funktion aktiviert, mit der du die Markierung verschieben kannst.

Standardmäßig wird beim Antippen einer Markierung die Kartensymbolleiste unten rechts auf der Karte angezeigt, damit der Nutzer schnell auf die mobile Google Maps App zugreifen kann. Du kannst die Symbolleiste deaktivieren. Weitere Informationen findest du im Leitfaden zu Steuerelementen.

Erste Schritte mit Markierungen

Diese Folge von Maps Live zeigt dir die Grundlagen, mit denen du Markierungen zu einer Karte mit dem Maps SDK for Android hinzufügst.

Markierung hinzufügen

Das folgende Beispiel zeigt, wie einer Karte eine Markierung hinzugefügt wird. Die Markierung wird an den Koordinaten 10,10 erstellt. Klickt der Nutzer darauf, erscheint der String "Hello world" in einem Infofenster.

@Override
public void onMapReady(GoogleMap map) {
    map.addMarker(new MarkerOptions()
        .position(new LatLng(10, 10))
        .title("Hello world"));
}

Zusätzliche Informationen zu einer Markierung anzeigen

Eine gängige Anforderung ist es, zusätzliche Informationen über einen Ort oder einen Standort anzuzeigen, wenn der Nutzer auf eine Markierung auf der Karte tippt. Weitere Informationen findest du in der Anleitung zu Infofenstern.

Daten mit einer Markierung verknüpfen

Du kannst ein beliebiges Datenobjekt unter Verwendung von Marker.setTag() mit einer Markierung speichern und das Datenobjekt mithilfe von Marker.getTag() abrufen, wie in diesem Codebeispiel veranschaulicht:

/**
 * A demo class that stores and retrieves data objects with each marker.
 */
public class MarkerDemoActivity extends FragmentActivity implements
        OnMarkerClickListener,
        OnMapReadyCallback {

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

    private Marker mPerth;
    private Marker mSydney;
    private Marker mBrisbane;

    private GoogleMap mMap;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.marker_demo);

        SupportMapFragment mapFragment =
                (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);
    }

    /** Called when the map is ready. */
    @Override
    public void onMapReady(GoogleMap map) {
        mMap = map;

        // Add some markers to the map, and add a data object to each marker.
        mPerth = mMap.addMarker(new MarkerOptions()
                .position(PERTH)
                .title("Perth"));
        mPerth.setTag(0);

        mSydney = mMap.addMarker(new MarkerOptions()
                .position(SYDNEY)
                .title("Sydney"));
        mSydney.setTag(0);

        mBrisbane = mMap.addMarker(new MarkerOptions()
                .position(BRISBANE)
                .title("Brisbane"));
        mBrisbane.setTag(0);

        // Set a listener for marker click.
        mMap.setOnMarkerClickListener(this);
    }

    /** Called when the user clicks a marker. */
    @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(this,
                           marker.getTitle() +
                           " has been clicked " + clickCount + " times.",
                           Toast.LENGTH_SHORT).show();
        }

        // Return false to indicate that we have not consumed the event and that we wish
        // for the default behavior to occur (which is for the camera to move such that the
        // marker is centered and for the marker's info window to open, if it has one).
        return false;
    }
}

Nachfolgend sind einige Beispiele für Szenarien aufgeführt, in denen es nützlich ist, Daten mit Markierungen zu speichern und abzurufen:

  • Deine App deckt möglicherweise verschiedene Arten von Markierungen ab, die unterschiedlich behandelt werden sollen, wenn der Nutzer darauf klickt. Um das zu erreichen, kannst du zusammen mit der Markierung einen String speichern, der den Typ angibt.
  • Du verfügst möglicherweise über eine Schnittstelle mit einem System, in dem es eindeutige Datensatzbezeichner gibt, wobei die Markierungen spezifische Datensätze in diesem System darstellen.
  • Mithilfe von Markierungsdaten lässt sich eine Priorität angeben, die verwendet werden soll, wenn über den Z-Index einer Markierung entschieden wird.

Markierungen dragbar machen

Wenn die Eigenschaft draggable auf true gesetzt ist, lässt sich eine Markierung verschieben, nachdem sie einer Karte hinzugefügt wurde. Drücke lange auf die Markierung, um das Ziehen zu aktivieren. Wenn du den Finger vom Display nimmst, bleibt die Markierung an dieser Position.

In der Standardeinstellung sind Markierungen nicht dragbar. Du musst die Markierung explizit als dragbar festlegen: entweder mit MarkerOptions.draggable(boolean), bevor die Markierung der Karte hinzugefügt wird, oder mit Marker.setDraggable(boolean), nachdem sie der Karte hinzugefügt wurde. Du kannst die Markierung laut der Beschreibung unter Ziehereignisse für Markierungen auf Ereignisse beobachten.

Mit dem nachfolgenden Snippet wird eine dragbare Markierung an der Position von Perth, Australien, hinzugefügt.

static final LatLng PERTH = new LatLng(-31.90, 115.86);
Marker perth = mMap.addMarker(new MarkerOptions()
                          .position(PERTH)
                          .draggable(true));

Markierung anpassen

Im nachfolgenden Video siehst du, wie Markierungen verwendet werden können, um Standorte auf einer Karte darzustellen.

Für Markierungen kann ein benutzerdefiniertes Bild anstelle des Standardsymbols festgelegt werden. Bevor ein Symbol definiert werden kann, muss eine Reihe von Eigenschaften festgelegt werden, die die visuelle Funktionsweise der Markierung bestimmen.

Die Anpassung folgender Eigenschaften wird von Markierungen unterstützt:

Position (erforderlich)
Der Wert LatLng für die Position der Markierung auf der Karte. Das ist die einzige erforderliche Eigenschaft für das Objekt Marker.
Anker
Der Punkt auf dem Bild, der an der Position "LatLng" der Markierung platziert wird. In der Standardeinstellung ist das der Mittelpunkt am unteren Rand des Bilds.
Alpha
Hiermit wird die Durchlässigkeit der Markierung festgelegt. Die Standardeinstellung ist 1,0.
Titel
Eine Textzeile, die im Infofenster erscheint, sobald der Nutzer auf die Markierung tippt
Snippet
Zusätzlicher Text, der unterhalb des Titels erscheint
Symbol
Eine Bitmap, die anstelle des Standardbilds der Markierung erscheint
Dragbar
Lege die Option auf true fest, wenn du den Nutzern das Verschieben der Markierung gestatten möchtest. Die Standardeinstellung ist false.
Sichtbar
Lege die Option auf false fest, um die Markierung unsichtbar zu machen. Die Standardeinstellung ist true.
Flache oder Billboard-Ausrichtung
In der Standardeinstellung sind Markierungen am Bildschirm ausgerichtet und werden nicht mit der Kamera gedreht oder geneigt. Flache Markierungen sind an der Erdoberfläche ausgerichtet und drehen oder neigen sich mit der Kamera. Die Größe beider Markierungen wird nicht auf Basis des Zoomfaktors geändert. Verwende "GroundOverlays", wenn du diesen Effekt möchtest.
Rotation
Die Ausrichtung der Markierung, angegeben in Grad im Uhrzeigersinn. Die Standardposition ändert sich, wenn die Markierung flach ist. Eine flache Markierung ist standardmäßig nordwärts ausgerichtet. Wenn sie nicht flach ist, zeigt sie nach oben und ist so gedreht, dass sie immer der Kamera gegenüberliegt.

Mit dem Snippet unten wird eine einfache Markierung mit Standardsymbol erstellt.

static final LatLng MELBOURNE = new LatLng(-37.813, 144.962);
Marker melbourne = mMap.addMarker(new MarkerOptions()
                          .position(MELBOURNE));

Markierungsfarbe anpassen

Die Farbe des standardmäßigen Markierungsbilds lässt sich anpassen, indem das Objekt BitmapDescriptor an die icon()-Methode übergeben wird. Du kannst einen Satz vordefinierter Farben im Objekt BitmapDescriptorFactory nutzen oder über die Methode BitmapDescriptorFactory.defaultMarker(float hue) eine benutzerdefinierte Markierungsfarbe festlegen. Der Farbton ist ein Wert zwischen 0 und 360, der Punkte auf einem Farbrad darstellt.

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

Durchlässigkeit der Markierung anpassen

Du kannst die Durchlässigkeit einer Markierung mithilfe der Methode "MarkerOptions.alpha()" ändern. Der Alpha-Wert ist als Gleitkommazahl zwischen 0.0 und 1.0 anzugeben, wobei 0 vollständige Transparenz und 1 vollständige Deckkraft bedeutet.

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

Markierungsbild anpassen

Du kannst das Standardmarkierungsbild durch ein benutzerdefiniertes ersetzen. Dieses Bild wird häufig auch als Symbol bezeichnet. Benutzerdefinierte Symbole werden immer als BitmapDescriptor festgelegt und mithilfe einer der Methoden in der Klasse BitmapDescriptorFactory definiert.

fromAsset(String assetName)
Zum Erstellen einer benutzerdefinierten Markierung unter Verwendung des Namens eines Bitmapbilds im Assets-Verzeichnis
fromBitmap(Bitmap image)
Zum Erstellen einer benutzerdefinierten Markierung aus einem Bitmapbild
fromFile(String fileName)
Zum Erstellen eines benutzerdefinierten Symbols mit dem Namen einer Bitmapbilddatei im internen Speicher
fromPath(String absolutePath)
Zum Erstellen einer benutzerdefinierten Markierung aus einem absoluten Dateipfad eines Bitmapbilds
fromResource(int resourceId)
Zum Erstellen einer benutzerdefinierten Markierung mithilfe der Ressourcen-ID eines Bitmapbilds

Im nachfolgenden Snippet wird eine Markierung mit einem benutzerdefinierten Symbol erstellt.

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

Markierung flach darstellen

Markierungssymbole werden üblicherweise in Bezug auf den Bildschirm gezeichnet, d. h. durch Drehen, Neigen oder Zoomen der Karte ändert sich ihre Ausrichtung nicht. Du kannst die Ausrichtung einer Markierung so festlegen, dass sie flach auf der Erdoberfläche liegt. Markierungen, die so ausgerichtet werden, drehen sich, wenn die Karte gedreht wird, und ändern den Blickwinkel, wenn die Karte geneigt wird. Flache Markierungen behalten ihre Größe bei, wenn die Karte vergrößert oder verkleinert wird.

Um die Ausrichtung der Markierung zu ändern, setzt du ihre Eigenschaft flat auf true.

static final LatLng PERTH = new LatLng(-31.90, 115.86);
Marker perth = mMap.addMarker(new MarkerOptions()
                          .position(PERTH)
                          .flat(true));

Markierung drehen

Mit der Methode MarkersetRotation() kannst du festlegen, dass sich eine Markierung um ihren Ankerpunkt drehen soll. Die Drehung wird gradweise im Uhrzeigersinn von der Standardposition aus gemessen. Wenn die Markierung flach auf der Karte aufliegt, ist die Standardposition Norden. Wenn sie nicht flach ist, zeigt sie nach oben und ist so gedreht, dass sie immer der Kamera gegenüberliegt.

Im Beispiel unten wird die Markierung um 90° gedreht. Wenn du den Ankerpunkt auf 0.5,0.5 festlegst, wird sie um ihre Mitte statt um ihre Grundlinie gedreht.

static final LatLng PERTH = new LatLng(-31.90, 115.86);
Marker perth = mMap.addMarker(new MarkerOptions()
                          .position(PERTH)
                          .anchor(0.5,0.5)
                          .rotation(90.0));

Z-Index der Markierung

Der Z-Index gibt die Stapelreihenfolge dieser Markierung relativ zu anderen Markierungen auf der Karte an. Eine Markierung mit einem hohen Z-Index wird über solchen mit niedrigeren Z-Indizes gezeichnet. Der Standardwert für den Z-Index ist 0.

Lege den Z-Index für das Optionsobjekt der Markierung fest, indem du MarkerOptions.zIndex() aufrufst, wie im folgenden Code-Snippet dargestellt:

@Override
public void onMapReady(GoogleMap map) {
    map.addMarker(new MarkerOptions()
        .position(new LatLng(10, 10))
        .title("Marker z1")
        .zIndex(1.0f));
}

Du kannst auf den Z-Index der Markierung zugreifen, indem du Marker.getZIndex() aufrufst. Wenn du den Index ändern möchtest, rufe Marker.setZIndex() auf.

Markierungen werden immer über Kachelebenen und andere Overlays ohne Markierungen (Gelände-Overlays, Polylinien, Polygone und andere Formen) gezeichnet, unabhängig vom Z-Index der anderen Overlays. Tatsächlich wird davon ausgegangen, dass sich Markierungen in einer separaten Z-Indexgruppe befinden, unabhängig von anderen Overlays.

Informationen zur Auswirkung des Z-Index auf Klickereignisse findest du weiter unten.

Ziehereignisse für Markierungen beobachten

Mit der Google Maps API kannst du Markierungsereignisse im Auge behalten und darauf reagieren. Dafür ist der entsprechende Listener für das Objekt GoogleMap einzurichten, zu dem die Markierungen gehören. Wenn das Ereignis an einer der Markierungen auf der Karte stattfindet, wird der Callback des Listeners durch das entsprechende Objekt Marker, das als Parameter weitergegeben wird, aktiviert. Zum Vergleich dieses Marker-Objekts mit deinem eigenen Verweis auf ein Marker-Objekt ist equals() und nicht == zu verwenden.

Die folgenden Ereignisse können beobachtet werden:

Klickereignisse für Markierungen

Du kannst Klickereignisse für eine Markierung mit dem OnMarkerClickListener im Auge behalten. Rufe GoogleMap.setOnMarkerClickListener(OnMarkerClickListener) auf, um diesen Listener auf der Karte festzulegen. Wenn ein Nutzer auf eine Markierung klickt, wird onMarkerClick(Marker) aufgerufen und die Markierung wird als Argument übergeben. Durch diese Methode wird ein boolescher Wert zurückgemeldet, der angibt, ob das Ereignis verarbeitet wurde. Das heißt, das Standardverhalten soll unterdrückt werden. Wenn es false zurückgibt, wird das Standardverhalten zusätzlich zu deinem benutzerdefinierten Verhalten verwendet. Das Standardverhalten für ein Klickereignis einer Markierung ist, das Infofenster aufzurufen (falls verfügbar) und die Kamera zu bewegen. Das führt dazu, dass die Markierung auf der Karte zentriert wird.

Auswirkung des Z-Index auf Klickereignisse:

  • Wenn ein Nutzer auf einen Cluster von Markierungen klickt, wird das Klickereignis für die Markierung mit dem höchsten Z-Index ausgelöst.
  • Pro Klick wird maximal ein Ereignis ausgelöst. Das heißt, der Klick wird nicht an die Markierungen oder andere Overlays mit niedrigeren Z-Index-Werten übergeben.
  • Wenn auf einen Cluster mit Markierungen geklickt wird, führt das dazu, dass nachfolgende Klicks den Cluster durchlaufen, wobei eine Markierung nach der anderen ausgewählt wird. Bei der Reihenfolge im Zyklus hat zuerst der Z-Index Priorität, dann die Nähe zum nächsten Klickpunkt.
  • Wenn der Nutzer auf eine Stelle außerhalb des Umkreises des Clusters klickt, wird der Cluster von der API neu berechnet und der Status des Klickzyklus wird zurückgesetzt, sodass er wieder am Anfang beginnt.
  • Das Klickereignis durchläuft Markierungscluster bis zu anderen Formen und Overlays, bevor der Zyklus noch einmal gestartet wird.
  • Tatsächlich wird davon ausgegangen, dass sich Markierungen in einer eigenen Z-Indexgruppe verglichen mit anderen Overlays oder Formen (Polylinien, Polygone, Kreise und/oder Gelände-Overlays) befinden, und zwar unabhängig von dem Z-Index der anderen. Wenn sich mehrere Markierungen, Overlays oder Formen überlagern, wird das Klickereignis zuerst durch den Markierungscluster geleitet. Anschließend wird es nacheinander für andere anklickbare Overlays oder Formen basierend auf ihren Z-Index-Werten ausgelöst.

Ziehereignisse für Markierungen

Mit einem OnMarkerDragListener kannst du Ziehereignisse für eine Markierung im Auge behalten. Rufe GoogleMap.setOnMarkerDragListener auf, um diesen Listener auf der Karte festzulegen. Zum Ziehen einer Markierung muss der Nutzer länger auf sie drücken. Wenn der Nutzer den Finger vom Display nimmt, bleibt die Markierung an dieser Position. Beim Ziehen einer Markierung wird zuerst onMarkerDragStart(Marker) aufgerufen. Während des Ziehens wird onMarkerDrag(Marker) ständig aufgerufen. Am Ende des Ziehvorgangs wird onMarkerDragEnd(Marker) aufgerufen. Du kannst die Position der Markierung jederzeit abrufen, indem du Marker.getPosition() aufrufst.