Caméra et vue

Sélectionnez une plate-forme : Android iOS JavaScript

Dans le SDK Maps pour Android, il est possible d'incliner et de faire pivoter les cartes avec des gestes simples, ce qui permet aux utilisateurs de choisir l'orientation qui leur convient le mieux. À n'importe quel niveau de zoom, vous pouvez effectuer un panoramique sur la carte ou modifier sa perspective avec une latence très faible grâce au format réduit des tuiles de carte vectorielles.

Exemples de code

Le dépôt ApiDemos sur GitHub inclut un exemple qui présente les fonctionnalités de la caméra :

Introduction

Comme Google Maps sur le Web, le SDK Maps pour Android représente la surface de la Terre (sphère) sur l'écran de votre appareil (surface plane) en utilisant une projection de Mercator. Vers l'est et vers l'ouest, la carte est répétée à l'infini car la Terre tourne sur elle-même. Vers le nord et le sud, la carte est limitée à environ 85 degrés nord et 85 degrés sud.

Remarque : La projection de Mercator a une largeur finie sur le plan longitudinal, mais une hauteur infinie sur le plan latitudinal. Nous "coupons" l'image de la carte de base en utilisant la projection de Mercator à environ +/- 85 degrés pour rendre carrée la carte qui en résulte et ainsi simplifier la logique de sélection des tuiles.

Le SDK Maps pour Android vous permet de changer le point de vue de l'utilisateur de la carte en modifiant la caméra de la carte.

Les modifications apportées à la caméra n'ont pas d'incidence sur les repères, les superpositions ni tout autre élément graphique que vous avez ajouté. Vous pouvez toutefois modifier ces éléments pour qu'ils s'intègrent mieux dans la nouvelle vue.

Écouter les gestes de l'utilisateur sur la carte vous permet de la modifier en réponse aux requêtes de l'utilisateur. Par exemple, la méthode de rappel OnMapClickListener.onMapClick() répond à un seul toucher sur la carte. Étant donné que la méthode reçoit la latitude et la longitude de l'emplacement du toucher, vous pouvez répondre en effectuant un panoramique ou un zoom sur ce point. Des méthodes similaires sont disponibles pour répondre aux appuis sur la bulle d'un repère ou à un geste de glissement sur un repère.

Vous pouvez également écouter les mouvements de la caméra. Votre application reçoit ainsi une notification lorsque la caméra commence à bouger, est en train de bouger ou arrête de bouger. Pour plus d'informations, consultez le guide des événements liés aux changements de caméra.

Position de la caméra

La vue de la carte est modélisée comme une caméra orientée vers le bas sur une surface plane. La position de la caméra (et par conséquent le rendu de la carte) est indiquée par les propriétés suivantes : position cible (latitude/longitude), orientation, inclinaison et zoom.

Schéma des propriétés de la caméra

Cible (zone géographique)

La cible de la caméra correspond à la position du centre de la carte, spécifiée en tant que coordonnées de latitude et longitude.

La latitude peut être comprise entre -85 et 85 degrés, inclus. Les valeurs supérieures ou inférieures à cette fourchette seront limitées à la valeur la plus proche dans cette fourchette. Par exemple, si vous spécifiez une latitude de 100, la valeur sera définie sur 85. La longitude est comprise entre -180 et 180 degrés, inclus. Les valeurs supérieures ou inférieures à cette fourchette seront converties pour être incluses dans la fourchette (-180, 180). Par exemple, les valeurs 480, 840 et 1200 seront toutes remplacées par 120 degrés.

Orientation

L'orientation de la caméra indique la direction de la boussole, mesurée en degrés depuis le nord géographique et correspondant au bord supérieur de la carte. Si vous tracez une ligne verticale du centre au bord supérieur de la carte, l'orientation correspond à la direction de la caméra (mesurée en degrés) par rapport au nord géographique.

La valeur d'orientation 0 signifie que le haut de la carte pointe vers le nord géographique. La valeur d'orientation 90 indique que le haut de la carte est orienté plein est (90 degrés sur une boussole). La valeur 180 signifie que le haut de la carte est orienté plein sud.

L'API Google Maps vous permet de modifier l'orientation d'une carte. Par exemple, un conducteur tourne souvent sa carte routière pour l'aligner dans le sens de la route, tandis qu'un randonneur utilisant une carte et une boussole oriente généralement la carte afin qu'une ligne verticale pointe vers le nord.

Inclinaison (angle de vue)

L'inclinaison définit la position de la caméra sur un arc juste au-dessus du point central de la carte, mesurée en degrés à partir du nadir (direction qui pointe juste en dessous de la caméra). La valeur 0 correspond à une caméra orientée à la verticale vers le bas. Une valeur supérieure à 0 correspond à une caméra inclinée vers l'horizon selon le nombre de degrés spécifié. Lorsque vous modifiez l'angle de vue, la carte apparaît en perspective, les éléments cartographiques lointains semblant plus petits, et les plus proches semblant plus grands, comme le montrent les illustrations ci-dessous.

Dans les images ci-dessous, l'angle de vue est de 0 degré. La première image correspond à un plan schématisé ; la position 1 correspond à la position de la caméra et la position 2 à la position actuelle de la carte. La carte qui en résulte est présentée juste en dessous.

Capture d'écran d'une carte avec une caméra placée à un angle de vue de 0 degrés, avec un niveau de zoom de 18.
Carte affichée avec l'angle de vue par défaut de la caméra
Schéma qui indique la position par défaut de la caméra, directement sur la position de la carte, à un angle de 0 degré.
Angle de vue par défaut de la caméra

Sur les images ci-dessous, l'angle de vue est de 45 degrés. Notez que la caméra se déplace à mi-chemin le long d'un arc entre une ligne verticale perpendiculaire (0 degré) et le sol (90 degrés), jusqu'à la position 3. La caméra pointe toujours vers le point central de la carte, mais la zone représentée par la ligne en position 4 est maintenant visible.

Capture d'écran d'une carte avec une caméra placée à un angle de vue de 45 degrés, avec un niveau de zoom de 18.
Carte affichée avec un angle de vue de 45 degrés
Schéma affichant l'angle de vue de la caméra défini sur 45 degrés, avec le niveau de zoom toujours défini sur 18.
Angle de vue de 45 degrés

Sur cette capture d'écran, la carte est toujours centrée sur le même point que sur la carte d'origine, mais d'autres éléments cartographiques ont été ajoutés en haut de la carte. À mesure que vous augmentez l'angle au-delà de 45 degrés, les éléments cartographiques situés entre la caméra et la position de la carte apparaissent proportionnellement plus grands, tandis que ceux situés au-delà de la position de la carte apparaissent proportionnellement plus petits, ce qui donne un effet tridimensionnel.

Zoom

Le niveau de zoom de la caméra détermine l'échelle de la carte. Plus le niveau de zoom est élevé, plus on peut voir de détails sur la carte ; et inversement, plus le niveau de zoom est faible, plus la partie du monde affichée à l'écran est grande. À un niveau de zoom 0, l'échelle de la carte est telle que le monde entier a une largeur d'environ 256 dp (pixels indépendants de la densité).

Augmenter le niveau de zoom de 1 double la largeur du monde à l'écran. Ainsi, à un niveau de zoom de N, la largeur du monde est environ de 256 * 2N dp. Par exemple, à un niveau de zoom de 2, le monde entier mesure environ 1 024 dp de large.

Le niveau de zoom doit correspondre à un nombre entier. La fourchette de niveaux de zoom autorisée par la carte dépend d'un certain nombre de facteurs, comme la cible, le type de carte et la taille de l'écran. Tout nombre en dehors de la fourchette sera converti vers la valeur valide la plus proche, qui peut correspondre au niveau de zoom minimal ou maximal. La liste suivante indique le niveau de détail approximatif que vous pouvez vous attendre à voir à chaque niveau de zoom :

  • 1 : Le monde
  • 5 : La masse continentale/Le continent
  • 10 : La ville
  • 15 : Les rues
  • 20 : Les immeubles
Les images suivantes montrent à quoi ressemblent les différents niveaux de zoom :
Capture d'écran d'une carte au niveau de zoom 5
Carte au niveau de zoom 5
Capture d'écran d'une carte au niveau de zoom 15
Carte au niveau de zoom 15
Capture d'écran d'une carte au niveau de zoom 20
Carte au niveau de zoom 20

Déplacer la caméra

L'API Google Maps vous permet de modifier la partie du monde visible sur la carte. Pour cela, vous devez changer la position de la caméra (au lieu de déplacer la carte).

Lorsque vous modifiez la caméra, vous avez la possibilité d'animer le mouvement de caméra qui en résulte. L'animation effectue une interpolation entre les attributs de caméra actuels et les nouveaux attributs. Vous pouvez également contrôler la durée de l'animation.

Pour modifier la position de la caméra, vous devez indiquer où vous souhaitez la déplacer à l'aide d'un CameraUpdate. L'API Google Maps vous permet de créer de nombreux types de CameraUpdate en utilisant CameraUpdateFactory. Les options suivantes sont disponibles :

Changer le niveau de zoom et définir le niveau de zoom minimal/maximal

CameraUpdateFactory.zoomIn() et CameraUpdateFactory.zoomOut() génèrent un CameraUpdate qui change le niveau de zoom de 1.0 tout en laissant les autres propriétés inchangées.

CameraUpdateFactory.zoomTo(float) génère un CameraUpdate qui remplace le niveau de zoom par la valeur donnée tout en laissant les autres propriétés inchangées.

CameraUpdateFactory.zoomBy(float) et CameraUpdateFactory.zoomBy(float, Point) génèrent un CameraUpdate qui augmente (ou diminue, si la valeur est négative) le niveau de zoom de la valeur donnée. Le second fixe le point donné sur l'écran afin qu'il reste à la même position (latitude/longitude) et dans ce cas, il peut déplacer la caméra pour y parvenir.

Il peut parfois s'avérer utile de définir un niveau de zoom minimal et/ou maximal idéal. Vous pouvez, par exemple, définir ce niveau de zoom pour contrôler l'expérience utilisateur si votre application affiche une zone définie autour d'un point d'intérêt, ou si vous utilisez une superposition de tuiles personnalisée avec un ensemble limité de niveaux de zoom.

Kotlin



private lateinit var map: GoogleMap

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

      

Java


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

      

Notez qu'en raison de certaines considérations techniques, il est possible que l'API ne permette pas aux utilisateurs d'effectuer un zoom trop faible ou trop élevé. Par exemple, une carte satellite ou en relief peut avoir un niveau de zoom maximal moins élevé que les tuiles de la carte de base.

Changer la position de la caméra

Il existe deux méthodes pour les changements de position courants. CameraUpdateFactory.newLatLng(LatLng) vous donne un CameraUpdate qui change la latitude et la longitude de la caméra, tout en conservant les autres propriétés. CameraUpdateFactory.newLatLngZoom(LatLng, float) génère un CameraUpdate qui modifie la latitude, la longitude et le zoom de la caméra tout en conservant les autres propriétés.

Pour plus de flexibilité dans le changement de position de la caméra, utilisez CameraUpdateFactory.newCameraPosition(CameraPosition). Il génère un CameraUpdate qui déplace la caméra à la position donnée. Vous pouvez obtenir un CameraPosition soit directement, en utilisant new CameraPosition(), soit avec un CameraPosition.Builder en utilisant new CameraPosition.Builder().

Panoramique (défilement)

CameraUpdateFactory.scrollBy(float, float) vous donne un CameraUpdate qui change la latitude et la longitude de la caméra de sorte que la carte se déplace en fonction du nombre de pixels spécifié. Une valeur x positive déplace la caméra vers la droite, de sorte que la carte semble avoir bougé vers la gauche. Une valeur y positive déplace la caméra vers le bas, de sorte que la carte semble avoir bougé vers le haut. Inversement, des valeurs x négatives déplacent la caméra vers la gauche, de sorte que la carte semble avoir bougé vers la droite, et des valeurs y négatives déplacent la caméra vers le haut. Le défilement est effectué par rapport à l'orientation actuelle de la caméra. Par exemple, si la caméra est orientée à 90 degrés, alors l'est est "haut".

Définir des limites

Définir les limites de la carte

Il peut parfois être utile de déplacer la caméra pour que la totalité d'une zone d'intérêt soit visible au plus haut niveau de zoom possible. Par exemple, si vous affichez toutes les stations-service dans un rayon de 5 km autour de la position actuelle de l'utilisateur, vous pouvez déplacer la caméra afin qu'elles soient toutes visibles sur l'écran. Pour ce faire, vous devez d'abord calculer la limite LatLngBounds qui doit être visible à l'écran. Vous pouvez ensuite utiliser CameraUpdateFactory.newLatLngBounds(LatLngBounds bounds, int padding) pour obtenir un CameraUpdate qui change la position de la caméra de sorte que la LatLngBounds tienne entièrement dans la carte, en tenant compte de la marge extérieure (en pixels) indiquée. Le CameraUpdate obtenu garantit que l'espace (en pixels) qui sépare la limite donnée et le bord de la carte est au moins égal à la marge extérieure indiquée. Notez que l'inclinaison et la direction de la carte seront toutes deux définies sur 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))

      

Java


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

      

Centrer la carte dans une zone donnée

Dans certains cas, vous pouvez vouloir centrer votre caméra à l'intérieur de certaines limites plutôt que d'inclure les bordures extrêmes. Imaginons par exemple que vous souhaitiez centrer la caméra sur un pays tout en conservant un zoom constant. Dans ce cas, vous pouvez utiliser une méthode similaire, en créant LatLngBounds et en utilisant CameraUpdateFactory.newLatLngZoom(LatLng latLng, float zoom) avec la méthode LatLngBounds.getCenter(). La méthode getCenter() renvoie le centre géographique de LatLngBounds.

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))

      

Java


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

      

Une surcharge de la méthode newLatLngBounds(boundary, width, height, padding) vous permet d'indiquer la largeur et la hauteur en pixels d'un rectangle dans le but qu'elles correspondent aux dimensions de la carte. Le rectangle est positionné de telle sorte que son centre est identique à celui de la vue de la carte (afin que si les dimensions spécifiées sont les mêmes que celles de la vue de la carte, le rectangle coïncide avec la vue de la carte). Le CameraUpdate obtenu déplacera la caméra de sorte que les LatLngBounds indiquées soient centrées sur l'écran au sein du rectangle donné au plus haut niveau de zoom possible, en tenant compte de la marge extérieure nécessaire.

Remarque : N'utilisez la méthode plus simple newLatLngBounds(boundary, padding) pour générer un CameraUpdate que si cela permet de déplacer la caméra une fois que la mise en page de la carte est effectuée. Au cours de la mise en page, l'API calcule les limites d'affichage de la carte qui sont nécessaires pour projeter correctement le cadre de délimitation. En comparaison, vous pouvez utiliser le CameraUpdate renvoyé par la méthode plus complexe newLatLngBounds(boundary, width, height, padding) à tout moment, même avant que la mise en page de la carte soit terminée, car l'API calcule les limites d'affichage à partir des arguments que vous transmettez.

Limiter le panoramique à une zone donnée

Dans les scénarios ci-dessus, vous définissez les limites de la carte, mais les utilisateurs peuvent ensuite faire défiler la carte ou effectuer un panoramique au-delà de ces limites. Vous pouvez toutefois fixer des limites au centre lat/lng du point focal de la carte (la cible de la caméra) pour que les utilisateurs puissent uniquement faire défiler la carte ou effectuer un panoramique à l'intérieur de ces limites. Par exemple, cela peut s'avérer utile pour une application de vente dans un centre commercial ou un aéroport, afin que les utilisateurs ne puissent pas faire défiler la carte ni effectuer un panoramique au-delà des limites définies.

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)

      

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);

      

Le schéma ci-dessous illustre le scénario suivant : la cible de la caméra est limitée à une zone légèrement plus grande que la fenêtre d'affichage. L'utilisateur peut faire défiler la carte ou effectuer un panoramique, sous réserve que la cible de la caméra reste dans la zone délimitée. La croix représente la cible de la caméra :

Schéma affichant un LatLngBounds supérieur à la fenêtre d'affichage

La carte remplit toujours la fenêtre d'affichage, même si cela se traduit par l'affichage de zones qui se trouvent en dehors des limites définies. Par exemple, si vous positionnez la cible de la caméra à un angle de la zone délimitée, la zone située au-delà de l'angle est visible dans la fenêtre d'affichage, mais les utilisateurs ne peuvent pas faire défiler la carte jusque dans cette zone. Le schéma suivant illustre ce scénario. La croix représente la cible de la caméra :

Schéma illustrant la cible de la caméra positionnée dans l'angle inférieur droit de LatLngBounds

Dans le schéma suivant, la cible de la caméra est particulièrement réduite, ce qui offre à l'utilisateur peu de liberté pour faire défiler la carte ou effectuer un panoramique. La croix représente la cible de la caméra :

Schéma illustrant un LatLngBounds de caméra inférieur à la fenêtre d'affichage

Mettre à jour la vue de la caméra

Pour appliquer un CameraUpdate à la carte, vous pouvez soit déplacer la caméra instantanément, soit l'animer doucement. Pour déplacer la caméra instantanément avec le CameraUpdate donné, vous pouvez appeler GoogleMap.moveCamera(CameraUpdate).

Pour rendre l'expérience utilisateur plus agréable, surtout pour les déplacements courts, vous pouvez animer ce changement. Pour ce faire, au lieu d'appeler GoogleMap.moveCamera, appelez GoogleMap.animateCamera. La carte se déplacera lentement vers les nouveaux attributs. La forme la plus détaillée de cette méthode, GoogleMap.animateCamera(cameraUpdate, duration, callback), offre trois arguments :

cameraUpdate
CameraUpdate décrit où déplacer la caméra.
callback
Objet qui implémente GoogleMap.CancellableCallback. Cette interface généralisée pour la gestion des tâches définit deux méthodes "onCancel()" et "onFinished()". Pour l'animation, les méthodes sont appelées dans les cas suivants :
onFinish()
Méthode appelée si l'animation arrive à la fin sans interruption.
onCancel()

Méthode appelée si l'animation est interrompue en appelant stopAnimation() ou en initiant un nouveau mouvement de caméra.

Cela peut aussi se produire si vous appelez GoogleMap.stopAnimation().

duration
Durée souhaitée de l'animation, en millisecondes, sous forme de int.

Les extraits de code suivants illustrent quelques-unes des méthodes les plus utilisées pour déplacer la caméra.

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))

      

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));