Kamera und Ansicht

Die Karten im Maps SDK for Android können leicht geneigt und gedreht werden, sodass die Nutzer die Karte nach Bedarf anpassen können. Du kannst die Karte in jeder Zoomstufe schwenken oder die Perspektive dank des geringeren Speicherbedarfs der vektorbasierten Kartenkacheln mit sehr geringer Latenz wechseln.

Codebeispiele

Das ApiDemos-Repository auf GitHub enthält ein Beispiel, das die Kamerafunktionen veranschaulicht:

Einführung

Wie Google Maps im Internet stellt auch das Maps SDK for Android die Weltkugel mithilfe der Mercator-Projektion auf deinem Bildschirm als ebene Fläche dar. In östliche und westliche Richtung wiederholt sich die Karte unendlich, indem sich die Welt nahtlos um sich selbst dreht. In nördlicher und südlicher Richtung ist die Karte jeweils auf 85 Grad begrenzt.

Hinweis: Eine Mercator-Projektion hat eine begrenzte Breite nach Längengraden, aber eine unbegrenzte Höhe nach Breitengraden. Wir haben die Darstellung der Basiskarte unter Verwendung der Mercator-Projektion bei circa +/- 85 Grad abgeschnitten, damit sich eine rechteckige Kartenform ergibt und die Kachelauswahl einfacher programmiert werden kann.

Mit dem Maps SDK for Android kannst du die Nutzeransicht der Karte ändern, indem du die Kamera der Karte änderst.

Änderungen an der Kamera verändern die Markierungen, Overlays oder andere hinzugefügte Grafiken nicht, wobei du jedoch ggf. deine Ergänzungen verändern solltest, um sie besser an die neue Ansicht anzupassen.

Weil auf der Karte Reaktionen auf Nutzergesten möglich sind, kannst du die Karte entsprechend den jeweiligen Nutzeranfragen ändern. Beispielsweise antwortet die Callback-Methode OnMapClickListener.onMapClick() auf ein einfaches Tippen auf die Karte. Die Methode empfängt den Breiten- und Längengrad der Tippposition und du kannst daraufhin auf diesen Punkt schwenken oder zoomen. Ähnliche Methoden stehen für die Reaktion auf Tippen auf das Infofeld einer Markierung oder auf Ziehen einer Markierung zur Verfügung.

Außerdem kannst du mit einem Listener auf Kamerabewegungen warten, sodass deine App eine Benachrichtigung erhält, wenn die Kamerabewegung beginnt, die Kamera sich aktuell bewegt oder die Kamerabewegung endet. Weitere Informationen findest du in der Anleitung Ereignisse durch Kameraänderung.

3D-Gebäude auf der Karte

In der Nahansicht werden bei vielen Städten 3D-Gebäude dargestellt, wie du unten im Bild von Vancouver, Kanada, sehen kannst. Die 3D-Gebäude können mit GoogleMap.setBuildingsEnabled(false) deaktiviert werden.

Karte von Vancouver, Kanada

Kameraposition

Die Kartenansicht wird so modelliert, als wäre eine Kamera auf eine ebene Fläche ausgerichtet. Die Position der Kamera (und damit das Rendern der Karte) wird durch folgende Eigenschaften festgelegt: Ziel (Breiten-/Längengrad), Lage, Anzeigewinkel und Zoom.

Diagramm der Kameraeigenschaften

Ziel (Ort)

Das Kameraziel ist der Standort in der Kartenmitte, angegeben in Breiten- und Längengraden.

Lage (Ausrichtung)

Die Lage der Kamera ist die Richtung, in die eine vertikale Linie auf der Karte zeigt, gemessen in Grad im Uhrzeigersinn von Norden aus. Autofahrer drehen eine Straßenkarte häufig so, dass sie ihrer Fahrtrichtung entspricht, während Wanderer Karte und Kompass zumeist so halten, dass die vertikale Linie nach Norden zeigt. Mit der Google Maps API kannst du die Ausrichtung oder Lage einer Karte ändern. Eine Lage von 90 Grad führt beispielsweise dazu, dass auf einer Karte Osten oben ist.

Neigung (Blickwinkel)

Die Neigung definiert die Kameraposition auf einem Bogen, der vom Mittelpunkt der Karte zur Erdoberfläche verläuft, gemessen im Gradabstand vom Nadir (Richtung von der Kamera direkt nach unten). Wenn du den Blickwinkel änderst, wird die Karte perspektivisch dargestellt, d. h. weit entfernte Objekte erscheinen kleiner und nahe Objekte größer. Das wird anhand der folgenden Abbildungen verdeutlicht.

In den untenstehenden Bildern beträgt der Blickwinkel 0 Grad. Das ist im ersten Bild schematisch dargestellt: Position 1 ist die Kameraposition und Position 2 die aktuelle Kartenposition. Die daraus resultierende Karte ist nachfolgend dargestellt.

Screenshot einer Karte, bei der die Kamera in einem Blickwinkel von 45 Grad mit Zoomstufe 18 positioniert ist
Karte aus dem Standardblickwinkel der Kamera
Diagramm zur Darstellung der Standardposition der Kamera: direkt über der Kartenposition, in einem Winkel von 0 Grad
Standardblickwinkel der Kamera

In den nachfolgenden Bildern beträgt der Anzeigewinkel 45 Grad. Hinweis: Die Kamera wird hierbei nicht um 45 Grad geneigt. Sie bewegt sich stattdessen auf halber Strecke entlang eines Bogens zwischen Zenit (0 Grad) und Boden (90 Grad) auf Position 3. Die Kamera zeigt immer noch auf den Kartenmittelpunkt, allerdings ist jetzt der Bereich sichtbar, der von der Linie an Position 4 dargestellt wird.

Screenshot einer Karte, bei der die Kamera in einem Blickwinkel von 45 Grad mit Zoomfaktor 18 positioniert ist
Karte unter einem Blickwinkel von 45 Grad
Diagramm zur Darstellung eines Kamerablickwinkels von 45 Grad weiterhin mit Zoomstufe 18
Kamerablickwinkel von 45 Grad

Die Karte im Screenshot ist zwar weiterhin auf den gleichen Punkt zentriert wie die ursprüngliche Karte, allerdings sind jetzt oben auf der Karte mehr Objekte zu sehen. Wenn du den Winkel auf über 45 Grad vergrößerst, erscheinen Objekte zwischen Kamera und Kartenposition proportional größer, während Objekte jenseits der Kartenposition kleiner dargestellt werden. Hierdurch entsteht ein dreidimensionaler Effekt.

Zoom

Die Zoomstufe der Kamera bestimmt die Skalierung der Karte. Bei größeren Zoomstufen sind auf dem Bildschirm mehr Details zu sehen, bei kleineren Zoomstufen erhältst du einen größeren Überblick. Bei Zoomstufe 0 hat die Karte einen Maßstab, bei dem die gesamte Erde eine Breite von circa 256 dp (dichteunabhängige Pixel) hat.

Wenn man die Zoomstufe um 1 erhöht, verdoppelt sich die Breite der Erde auf dem Bildschirm. Beträgt die Breite der Erde bei Zoomstufe N also circa 256 * 2N dp, ist sie bei Zoomstufe 2 demzufolge circa 1.024 dp breit. Die Zoomstufe muss nicht als ganze Zahl angegeben werden. Der für eine Karte zulässige Zoomstufenbereich hängt von einer Reihe von Faktoren ab, z. B. Ort, Kartentyp und Bildschirmgröße. Jede Zahl außerhalb des Bereichs wird in den nächsten gültigen Wert konvertiert. Das kann entweder die minimale Zoomstufe oder die maximale Zoomstufe sein. Die folgende Liste enthält die ungefähre Detailebene, die du bei der jeweiligen Zoomstufe wahrscheinlich sehen kannst:

  • 1: Welt
  • 5: Landmasse/Kontinent
  • 10: Stadt
  • 15: Straßen
  • 20: Gebäude

Die folgenden Bilder zeigen die visuelle Darstellung bei unterschiedlichen Zoomstufen.

Screenshot einer Karte mit Zoomstufe 5
Karte mit Zoomstufe 5
Screenshot einer Karte mit Zoomstufe 15
Karte mit Zoomstufe 15
Screenshot einer Karte mit Zoomstufe 20
Karte mit Zoomstufe 20

Hinweis: Aufgrund von Bildschirmgröße und -dichte unterstützen einige Geräte eventuell die niedrigste Zoomstufe nicht. Verwende GoogleMap.getMinimumZoomLevel() für die minimale Zoomstufe der Karte. Wenn du die gesamte Welt im Darstellungsbereich anzeigen musst, ist es möglicherweise besser, den Lite-Modus zu verwenden.

Kamera bewegen

Mit der Google Maps API kannst du festlegen, welcher Teil der Welt auf der Karte sichtbar ist. Das geschieht, indem du die Kameraposition änderst. Die Karte wird dabei nicht verschoben.

Beim Ändern der Kameraposition kannst du die resultierende Kamerabewegung animiert darstellen. Die Animation wird zwischen den aktuellen und den neuen Kameraattributen interpoliert. Du kannst auch die Dauer der Animation festlegen.

Wenn du die Kameraposition ändern möchtest, musst du mit einem CameraUpdate angeben, wohin die Kamera bewegt werden soll. Mit der Google Maps API kannst du viele verschiedene CameraUpdate mitCameraUpdateFactory erstellen. Folgende Optionen sind verfügbar:

Zoomstufe ändern und minimale/maximale Zoomstufe festlegen

CameraUpdateFactory.zoomIn() und CameraUpdateFactory.zoomOut() stellen ein CameraUpdate-Objekt bereit, das die aktuelle Zoomstufe um 1,0 ändert, während alle andere Eigenschaften beibehalten werden.

Mit CameraUpdateFactory.zoomTo(float) wird ein CameraUpdate-Objekt bereitgestellt, das die Zoomstufe in den angegebenen Wert ändert und alle anderen Attribute beibehält.

CameraUpdateFactory.zoomBy(float) und CameraUpdateFactory.zoomBy(float, Point) stellen ein CameraUpdate Objekt bereit, das die aktuelle Zoomstufe erhöht bzw. verringert (bei einem negativen Wert) und die Position des angegebenen Punkts auf dem Bildschirm beibehält. Dieser Wert fixiert den vorgegebenen Punkt auf dem Bildschirm, sodass dessen Position (Breiten-/Längengrad) unverändert bleibt. Um das zu erreichen, wird ggf. die Position der Kamera verändert.

Unter Umständen ist es hilfreich, eine bevorzugte minimale und/oder maximale Vergrößerungsstufe festzulegen, beispielsweise zur Steuerung der Nutzererfahrung, wenn in deiner App ein festgelegter Bereich um einen POI herum angezeigt wird oder wenn du ein benutzerdefiniertes Kachel-Overlay mit einer eingeschränkten Gruppe von Zoomstufen verwendest.

Java

private GoogleMap map;
    map.setMinZoomPreference(6.0f);
    map.setMaxZoomPreference(14.0f);
      

Kotlin

private lateinit var map: GoogleMap

    map.setMinZoomPreference(6.0f)
    map.setMaxZoomPreference(14.0f)
      

Möglicherweise gibt es technische Gesichtspunkte, die verhindern, dass die API Nutzern die Verwendung von sehr niedrigen oder hohen Zoomstufen ermöglicht. So kann eine Satelliten- oder Geländekarte beispielsweise eine geringere maximale Zoomstufe haben als die Kacheln der Basiskarte.

Kameraposition ändern

Es gibt zwei Praxismethoden, um allgemeine Positionsänderungen vorzunehmen. Mit CameraUpdateFactory.newLatLng(LatLng) erhältst du ein CameraUpdate, das den Breiten- und Längengrad ändert und alle anderen Eigenschaften beibehält. Mit CameraUpdateFactory.newLatLngZoom(LatLng, float) erhältst du ein CameraUpdate, das den Breiten- und Längengrad, die Zoomstufe der Kamera und alle anderen Eigenschaften beibehält.

Nutze für volle Flexibilität beim Ändern der Kameraposition den Befehl CameraUpdateFactory.newCameraPosition(CameraPosition). Damit erhältst du ein CameraUpdate-Objekt, mit dem die Kamera an die jeweilige Position bewegt wird. CameraPosition kann entweder direkt mit new CameraPosition() oder mit einem CameraPosition.Builder mit new CameraPosition.Builder() abgerufen werden.

Schwenken (scrollen)

CameraUpdateFactory.scrollBy(float, float) stellt ein CameraUpdate bereit, das den Breiten- und Längengrad der Kamera so ändert, dass die Karte um die angegebene Anzahl von Pixeln verschoben wird. Ein positiver X-Wert führt dazu, dass die Kamera nach rechts bewegt wird, sodass der Eindruck entsteht, die Karte wäre nach links verschoben worden. Ein positiver Y-Wert führt dazu, dass die Kamera nach unten bewegt wird, sodass der Eindruck entsteht, die Karte wäre nach oben verschoben worden. Umgekehrt führt ein negativer X-Wert dazu, dass die Kamera nach links bewegt wird, sodass der Eindruck erweckt wird, die Karte wäre nach rechts verschoben worden. Der Bildlauf ist relativ zur aktuellen Ausrichtung der Kamera. Bei einer Kameraposition von 90 Grad ist beispielsweise Osten „oben“.

Grenzen einstellen

Grenzen der Karte festlegen

Unter Umständen ist es sinnvoll, die Kamera so zu bewegen, dass ein gesamter Bereich von Interesse mit der größtmöglichen Zoomstufe dargestellt wird. Wenn du zum Beispiel alle Tankstellen im Umkreis von fünf Kilometern von der aktuellen Nutzerposition eingeblendet hast, empfiehlt es sich, die Kamera so zu bewegen, dass alle Tankstellen auf dem Bildschirm zu sehen sind. Berechne dazu zuerst den Wert LatLngBounds, der auf dem Bildschirm sichtbar sein soll. Du kannst dann CameraUpdateFactory.newLatLngBounds(LatLngBounds bounds, int padding) verwenden, um ein CameraUpdate zu erhalten, mit dem die Kameraposition so geändert wird, dass die angegebenen LatLngBounds ganz in die Karte passen, wobei der vorgegebene Abstand (in Pixeln) berücksichtigt wird. Du erhältst ein CameraUpdate, das bewirkt, dass die Lücke (in Pixeln) zwischen den vorgegebenen Grenzen und dem Rand der Karte mindestens dem festgelegten Abstand entspricht. Neigung und Lage der Karte werden jeweils auf 0 festgelegt.

Java

LatLngBounds australiaBounds = new LatLngBounds(
    new LatLng(-44, 113), // SW bounds
    new LatLng(-10, 154)  // NE bounds
);
map.moveCamera(CameraUpdateFactory.newLatLngBounds(australiaBounds, 0));
      

Kotlin

val australiaBounds = LatLngBounds(
    LatLng((-44.0), 113.0),  // SW bounds
    LatLng((-10.0), 154.0) // NE bounds
)
map.moveCamera(CameraUpdateFactory.newLatLngBounds(australiaBounds, 0))
      

Karte in einem Bereich zentrieren

Unter Umständen ist es wünschenswert, die Kamera innerhalb eines Rahmens zu zentrieren, anstatt die äußeren Ränder einzubeziehen. Die Kamera lässt sich beispielsweise auf ein Land zentrieren, während gleichzeitig eine konstante Zoomstufe beibehalten wird. In diesem Fall kannst du eine ähnliche Methode verwenden, indem du ein LatLngBounds erstellst und CameraUpdateFactory.newLatLngZoom(LatLng latLng, float zoom) mit der Methode LatLngBounds.getCenter() verwendest. Die Methode „getCenter()“ liefert den geografischen Mittelpunkt von LatLngBounds.

Java

LatLngBounds australiaBounds = new LatLngBounds(
    new LatLng(-44, 113), // SW bounds
    new LatLng(-10, 154)  // NE bounds
);
map.moveCamera(CameraUpdateFactory.newLatLngZoom(australiaBounds.getCenter(), 10));
      

Kotlin

val australiaBounds = LatLngBounds(
    LatLng((-44.0), 113.0),  // SW bounds
    LatLng((-10.0), 154.0) // NE bounds
)
map.moveCamera(CameraUpdateFactory.newLatLngZoom(australiaBounds.center, 10f))
      

Bei einer Überladung der Methode newLatLngBounds(boundary, width, height, padding) kannst du eine Breite und Höhe in Pixeln für ein Rechteck angeben, das den Maßen der Karte entspricht. Dieses Rechteck wird so positioniert, dass sein Mittelpunkt mit dem der Kartenansicht übereinstimmt (damit für den Fall, dass die angegebenen Maße mit denen der Kartenansicht übereinstimmen, das Rechteck mit der Kartenansicht übereinstimmt). Mit dem generierten CameraUpdate wird die Kamera so bewegt, dass der vorgegebene Rahmen LatLngBounds innerhalb des angegebenen Rechtecks unter Berücksichtigung des erforderlichen Abstands mit der größtmöglichen Zoomstufe auf dem Bildschirm zentriert wird.

Hinweis: Verwende die einfachere Methode newLatLngBounds(boundary, padding) zum Generieren von CameraUpdate nur dann, wenn sie für das Bewegen der Kamera nach Layoutänderungen an der Karte verwendet werden soll. Während der Layoutänderungen berechnet die API die Darstellungsgrenzen der Karte, die für eine korrekte Konfiguration des Markierungsrahmens benötigt werden. Im Gegensatz dazu kannst du das von der komplexeren Methode newLatLngBounds(boundary, width, height, padding) zurückgegebene CameraUpdate jederzeit verwenden – auch vor Layoutänderungen an der Karte –, weil die API die Darstellungsgrenzen aus den von dir übermittelten Argumenten berechnet.

Schwenken des Nutzers auf einen bestimmten Bereich beschränken

In den Szenarien oben legst du die Grenzen der Karte fest. Der Nutzer kann jedoch außerhalb dieser Grenzen scrollen oder schwenken. Du kannst aber auch die Breiten- und Längengradgrenzwerte des Kartenfokus (Kameraziels) einschränken, sodass Nutzer nur innerhalb dieser Grenzen scrollen und schwenken können. Beispiel: Eine Einzelhandels-App für ein Einkaufszentrum oder einen Flughafen kann die Karte auf bestimmte Grenzen beschränken und ermöglicht Nutzern das Scrollen und Schwenken innerhalb dieser Grenzen.

Java

// Create a LatLngBounds that includes the city of Adelaide in Australia.
LatLngBounds adelaideBounds = new LatLngBounds(
    new LatLng(-35.0, 138.58), // SW bounds
    new LatLng(-34.9, 138.61)  // NE bounds
);

// Constrain the camera target to the Adelaide bounds.
map.setLatLngBoundsForCameraTarget(adelaideBounds);
      

Kotlin

// Create a LatLngBounds that includes the city of Adelaide in Australia.
val adelaideBounds = LatLngBounds(
    LatLng(-35.0, 138.58),  // SW bounds
    LatLng(-34.9, 138.61) // NE bounds
)

// Constrain the camera target to the Adelaide bounds.
map.setLatLngBoundsForCameraTarget(adelaideBounds)
      

Im folgenden Diagramm wird ein Szenario veranschaulicht, in dem das Kameraziel auf einen Bereich beschränkt ist, der etwas größer als der Darstellungsbereich ist. Unter der Voraussetzung, dass das Kameraziel innerhalb des begrenzten Bereichs bleibt, ist der Nutzer in der Lage, zu scrollen und zu schwenken. Das Kreuz stellt das Kameraziel dar:

Diagramm mit einer LatLngBounds-Kamera, die größer als der Darstellungsbereich ist

Die Karte füllt den Darstellungsbereich immer aus, auch wenn das dazu führt, dass im Darstellungsbereich Bereiche außerhalb der festgelegten Grenzen angezeigt werden. Beispiel: Wenn du das Kameraziel in einer Ecke des begrenzten Bereichs positionierst, ist der Bereich jenseits der Ecke im Darstellungsbereich sichtbar. Nutzer können in diesen Bereich jedoch nicht weiter scrollen. Dieses Szenario wird im folgenden Diagramm veranschaulicht. Das Kreuz stellt das Kameraziel dar:

Diagramm, bei dem das Kameraziel in der unteren rechten Ecke der Kamera positioniert ist.

Im folgenden Diagramm weist das Kameraziel sehr beschränkte Grenzen auf und bietet dem Nutzer nur wenige Möglichkeiten zum Scrollen oder Schwenken. Das Kreuz stellt das Kameraziel dar:

Diagramm mit einer LatLngBounds-Kamera, die kleiner als der Darstellungsbereich ist

Kameraansicht aktualisieren

Um ein CameraUpdate für die Karte zu übernehmen, kannst du die Kamera entweder direkt neu positionieren oder sanft bewegen. Wenn du die Kamera sofort mit dem vorgegebenen CameraUpdate bewegen möchtest, kannst du GoogleMap.moveCamera(CameraUpdate) aufrufen.

Für eine angenehmere Nutzererfahrung, insbesondere bei kurzen Kamerafahrten, kannst du die Änderung animieren. Verwende hierzu anstelle von GoogleMap.moveCamera den Aufruf GoogleMap.animateCamera. Die Karte wird sanft zu den neuen Attributen verschoben. Für die detaillierteste Form dieser Methode, GoogleMap.animateCamera(cameraUpdate, duration, callback), stehen drei Argumente zur Verfügung:

cameraUpdate
CameraUpdate Gibt an, wohin die Kamera bewegt werden soll.
callback
Ein Objekt, das GoogleMap.CancellableCallback implementiert. Diese allgemeine Schnittstelle zum Verarbeiten von Aufgaben definiert zwei Methoden: „onCancel()“ und „onFinished()“. Zur Animation werden die Methoden unter folgenden Bedingungen aufgerufen:
onFinish()
Wird aufgerufen, wenn die Animation ohne Unterbrechung bis zum Ende ausgeführt wird.
onCancel()

Wird aufgerufen, wenn die Animation über die Aktivierung von stopAnimation() oder das Starten einer neuen Kamerabewegung unterbrochen wird.

Der Fehler kann auch auftreten, wenn du GoogleMap.stopAnimation() aufrufst.

duration
Gewünschte Dauer der Animation in Millisekunden, eine Ganzzahl int

Die folgenden Code-Snippets veranschaulichen einige der üblichen Vorgehensweisen zum Bewegen der Kamera.

Java

LatLng sydney = new LatLng(-33.88,151.21);
LatLng mountainView = new LatLng(37.4, -122.1);

// Move the camera instantly to Sydney with a zoom of 15.
map.moveCamera(CameraUpdateFactory.newLatLngZoom(sydney, 15));

// Zoom in, animating the camera.
map.animateCamera(CameraUpdateFactory.zoomIn());

// Zoom out to zoom level 10, animating with a duration of 2 seconds.
map.animateCamera(CameraUpdateFactory.zoomTo(10), 2000, null);

// Construct a CameraPosition focusing on Mountain View and animate the camera to that position.
CameraPosition cameraPosition = new CameraPosition.Builder()
    .target(mountainView )      // Sets the center of the map to Mountain View
    .zoom(17)                   // Sets the zoom
    .bearing(90)                // Sets the orientation of the camera to east
    .tilt(30)                   // Sets the tilt of the camera to 30 degrees
    .build();                   // Creates a CameraPosition from the builder
map.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
      

Kotlin

val sydney = LatLng(-33.88, 151.21)
val mountainView = LatLng(37.4, -122.1)

// Move the camera instantly to Sydney with a zoom of 15.
map.moveCamera(CameraUpdateFactory.newLatLngZoom(sydney, 15f))

// Zoom in, animating the camera.
map.animateCamera(CameraUpdateFactory.zoomIn())

// Zoom out to zoom level 10, animating with a duration of 2 seconds.
map.animateCamera(CameraUpdateFactory.zoomTo(10f), 2000, null)

// Construct a CameraPosition focusing on Mountain View and animate the camera to that position.
val cameraPosition = CameraPosition.Builder()
    .target(mountainView) // Sets the center of the map to Mountain View
    .zoom(17f)            // Sets the zoom
    .bearing(90f)         // Sets the orientation of the camera to east
    .tilt(30f)            // Sets the tilt of the camera to 30 degrees
    .build()              // Creates a CameraPosition from the builder
map.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition))