Repères

Les repères indiquent des emplacements uniques sur la carte. Pour personnaliser vos repères, vous pouvez modifier la couleur par défaut ou remplacer l'icône du repère par une image personnalisée. Les fenêtres d'informations vous permettent d'obtenir plus de contexte sur un repère.

Exemples de code

Le dépôt ApiDemos sur GitHub inclut un exemple qui présente différentes fonctionnalités des repères :

Java

Kotlin

Introduction

Les repères identifient des emplacements sur la carte. Le repère par défaut utilise une icône standard, commune à toute l'interface Google Maps. Il est possible de modifier la couleur, l'image ou le point d'ancrage de l'icône via l'API. Les repères sont des objets de type Marker et sont ajoutés à la carte avec la méthode GoogleMap.addMarker(markerOptions).

Les repères sont conçus pour être interactifs. Ils reçoivent des événements click par défaut et sont souvent utilisés avec des écouteurs d'événements qui permettent d'afficher des fenêtres d'informations. L'utilisateur peut modifier la position d'un repère en définissant sa propriété draggable sur true. Pour déplacer le repère, il suffit d'appuyer dessus de manière prolongée.

Par défaut, lorsqu'un utilisateur appuie sur un repère, la barre d'outils de la carte apparaît en bas à droite, ce qui lui permet d'accéder rapidement à l'application mobile Google Maps. Vous pouvez désactiver la barre d'outils. Pour plus d'informations, consultez le guide des commandes.

Premiers pas avec les repères

Cet épisode de Maps Live porte sur les principes de base à adopter pour ajouter des repères à votre carte via le SDK Maps pour Android.

Ajouter un repère

L'exemple suivant montre comment ajouter un repère à une carte. Le repère est créé aux coordonnées -33.852,151.211 (Sydney, Australie) et affiche la chaîne "Repère à Sydney" dans une fenêtre d'informations lorsque l'utilisateur clique dessus.

Java

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

Kotlin

override fun onMapReady(googleMap: GoogleMap) {
    // Add a marker in Sydney, Australia,
    // and move the map's camera to the same location.
    val sydney = LatLng(-33.852, 151.211)
    googleMap.addMarker(
        MarkerOptions()
            .position(sydney)
            .title("Marker in Sydney")
    )
    googleMap.moveCamera(CameraUpdateFactory.newLatLng(sydney))
}
      

Afficher des informations supplémentaires sur un repère

Il est souvent nécessaire d'afficher des informations supplémentaires sur un lieu lorsque l'utilisateur appuie sur un repère de la carte. Pour en savoir plus, consultez le guide sur les fenêtres d'informations.

Associer des données à un repère

Vous pouvez stocker un objet de données arbitraire avec un repère en utilisant la méthode Marker.setTag(), puis récupérer cet objet de données à l'aide de Marker.getTag(). L'exemple ci-dessous montre comment utiliser des balises pour comptabiliser le nombre de fois qu'un utilisateur a cliqué sur un repère :

Java

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

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

    private Marker markerPerth;
    private Marker markerSydney;
    private Marker markerBrisbane;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_markers);
        SupportMapFragment mapFragment =
            (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);
    }

    /** Called when the map is ready. */
    @Override
    public void onMapReady(GoogleMap map) {
        // Add some markers to the map, and add a data object to each marker.
        markerPerth = map.addMarker(new MarkerOptions()
            .position(PERTH)
            .title("Perth"));
        markerPerth.setTag(0);

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

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

        // Set a listener for marker click.
        map.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;
    }
}
      

Kotlin

/**
 * A demo class that stores and retrieves data objects with each marker.
 */
class MarkerDemoActivity : AppCompatActivity(),
    OnMarkerClickListener, OnMapReadyCallback {
    private val PERTH = LatLng(-31.952854, 115.857342)
    private val SYDNEY = LatLng(-33.87365, 151.20689)
    private val BRISBANE = LatLng(-27.47093, 153.0235)

    private lateinit var markerPerth: Marker
    private lateinit var markerSydney: Marker
    private lateinit var markerBrisbane: Marker

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_markers)
        val mapFragment =
            supportFragmentManager.findFragmentById(R.id.map) as SupportMapFragment?
        mapFragment!!.getMapAsync(this)
    }

    /** Called when the map is ready.  */
    override fun onMapReady(map: GoogleMap) {
        // Add some markers to the map, and add a data object to each marker.
        markerPerth = map.addMarker(
            MarkerOptions()
                .position(PERTH)
                .title("Perth")
        )
        markerPerth.tag = 0
        markerSydney = map.addMarker(
            MarkerOptions()
                .position(SYDNEY)
                .title("Sydney")
        )
        markerSydney.tag = 0
        markerBrisbane = map.addMarker(
            MarkerOptions()
                .position(BRISBANE)
                .title("Brisbane")
        )
        markerBrisbane.tag = 0

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

    /** Called when the user clicks a marker.  */
    override fun onMarkerClick(marker: Marker): Boolean {

        // 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(
                this,
                "${marker.title} has been clicked $newClickCount 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
    }
}
      

Voici quelques exemples illustrant pourquoi il peut être utile de stocker et de récupérer des données à l'aide de repères :

  • Votre application prend en charge différents types de repères, et vous souhaitez les traiter différemment lorsque l'utilisateur clique dessus. Pour ce faire, vous pouvez stocker un String avec le repère indiquant son type.
  • Vous communiquez avec un système qui comporte des identifiants d'enregistrement uniques et dans lequel les repères représentent des enregistrements spécifiques.
  • Les données de repère indiquent la priorité à utiliser pour choisir le z-index d'un repère.

Rendre un repère déplaçable

Vous pouvez repositionner un repère une fois qu'il a été ajouté à la carte tant que sa propriété draggable est définie sur true. Appuyez de manière prolongée sur le repère pour activer le déplacement. Lorsque vous relâchez votre doigt de l'écran, le repère reste dans cette position.

Par défaut, les repères ne sont pas déplaçables. Vous devez définir explicitement le repère comme déplaçable soit avec MarkerOptions.draggable(boolean) avant de l'ajouter à la carte, soit avec Marker.setDraggable(boolean) une fois qu'il a été ajouté. Vous pouvez écouter les événements de déplacement sur le repère, comme indiqué dans Événements de déplacement de repère.

Le fragment ci-dessous ajoute un repère déplaçable à Perth, en Australie.

Java

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

Kotlin

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

Personnaliser un repère

Cette vidéo montre comment utiliser des repères pour visualiser des emplacements sur une carte.

Les repères peuvent définir une image personnalisée qui s'affiche à la place de l'icône par défaut. Définir une icône implique de paramétrer un certain nombre de propriétés qui déterminent le comportement visuel du repère.

Vous pouvez personnaliser les repères via les propriétés suivantes :

Position (obligatoire)
Valeur LatLng correspondant à la position du repère sur la carte. Il s'agit de la seule propriété obligatoire de l'objet Marker.
Anchor
Point sur l'image qui sera placé à la position LatLng du repère. La valeur par défaut correspond au milieu du bas de l'image.
Alpha
Définit l'opacité du repère. La valeur par défaut est 1.0.
Title
Chaîne qui s'affiche dans la fenêtre d'informations lorsque l'utilisateur appuie sur le repère.
Snippet
Texte supplémentaire affiché sous le titre.
Icon
Image bitmap affichée à la place de l'image du repère par défaut.
Draggable
Définissez cette propriété sur true pour autoriser l'utilisateur à déplacer le repère. La valeur par défaut est false.
Visible
Définissez cette propriété sur false pour rendre le repère invisible. La valeur par défaut est true.
Orientation "Flat" ou "Billboard"
Par défaut, les repères sont orientés par rapport à l'écran, et ne pivotent pas ou ne s'inclinent pas avec la caméra. Les repères plats ("flat") sont orientés par rapport à la surface de la Terre. Ils pivotent et s'inclinent avec la caméra. Les deux types de repères ne changent pas de taille en fonction du zoom. Utilisez GroundOverlays si vous souhaitez obtenir cet effet.
Rotation
Orientation du repère, spécifiée en degrés dans le sens des aiguilles d'une montre. La position par défaut change si le repère est plat. La position par défaut d'un repère plat est alignée sur le nord. Si le repère n'est pas plat, la position par défaut est à la verticale vers le haut, et la rotation est définie pour que le repère soit toujours face à la caméra.

L'extrait ci-dessous crée un repère simple, avec l'icône par défaut.

Java

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

Kotlin

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

Personnaliser la couleur du repère

Vous pouvez personnaliser la couleur de l'image par défaut du repère en transmettant un objet BitmapDescriptor à la méthode icon(). Vous pouvez utiliser un ensemble de couleurs prédéfinies dans l'objet BitmapDescriptorFactory ou définir une couleur de repère personnalisée avec la méthode BitmapDescriptorFactory.defaultMarker(float hue). La teinte est une valeur comprise entre 0 et 360, représentant des points sur une roue chromatique.

Java

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

Kotlin

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

Personnaliser l'opacité du repère

Vous pouvez contrôler l'opacité du repère via la méthode MarkerOptions.alpha(). Alpha doit être spécifié sous la forme d'une valeur flottante comprise entre 0.0 et 1.0, où 0 est totalement transparent et 1 totalement opaque.

Java

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

Kotlin

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

Personnaliser l'image du repère

Vous pouvez remplacer l'image par défaut du repère par une image personnalisée, souvent appelée icône. Les icônes personnalisées sont toujours paramétrées en tant que BitmapDescriptor et définies via l'une des méthodes de la classe BitmapDescriptorFactory.

fromAsset(String assetName)
Crée un repère personnalisé en utilisant le nom d'une image bitmap dans l'annuaire d'éléments.
fromBitmap(Bitmap image)
Crée un repère personnalisé à partir d'une image bitmap.
fromFile(String fileName)
Crée une icône personnalisée en utilisant le nom d'un fichier image bitmap enregistré dans la mémoire de stockage interne.
fromPath(String absolutePath)
Crée un repère personnalisé à partir du chemin d'accès absolu à une image bitmap.
fromResource(int resourceId)
Crée un repère personnalisé en utilisant l'ID de ressource d'une image bitmap.

L'extrait ci-dessous crée un repère avec une icône personnalisée.

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

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

Aplatir un repère

Les icônes de repère sont normalement dessinées par rapport à l'écran. Une rotation, une inclinaison ou un zoom sur la carte ne changent pas l'orientation du repère. Vous pouvez définir l'orientation d'un repère pour qu'elle soit plane par rapport à la terre. Les repères orientés de cette manière pivotent lorsque l'utilisateur fait pivoter la carte, et changent de perspective lorsque la carte est inclinée. Les repères plats conservent leurs dimensions lorsque l'utilisateur effectue un zoom avant ou arrière sur la carte.

Pour modifier l'orientation du repère, définissez la propriété flat du repère sur true.

Java

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

Kotlin

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

Faire pivoter un repère

Vous pouvez faire pivoter un repère autour de son point d'ancrage via la méthode MarkersetRotation(). La rotation se mesure en degrés dans le sens des aiguilles d'une montre à partir de la position par défaut. Lorsque le repère est plat sur la carte, la position par défaut est le nord. Si le repère n'est pas plat, la position par défaut est à la verticale vers le haut, et la rotation est définie pour que le repère soit toujours face à la caméra.

L'exemple ci-dessous fait pivoter le repère de 90°. Si vous définissez le point d'ancrage sur 0.5,0.5, le repère pivotera sur son centre, et non sur sa base.

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

Kotlin

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

Z-index du repère

Le z-index indique l'ordre d'empilement d'un repère par rapport aux autres repères de la carte. Un repère associé à un z-index élevé apparaît au-dessus des repères dont le z-index est moins élevé. La valeur par défaut du z-index est 0.

Définissez le z-index sur l'objet options du repère en appelant MarkerOptions.zIndex(), comme illustré dans l'extrait de code suivant :

Java

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

Kotlin

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

Vous pouvez accéder au z-index du repère en appelant Marker.getZIndex() et le modifier en appelant Marker.setZIndex().

Les repères sont toujours affichés au-dessus des calques de tuiles et des autres superpositions non constituées de repères (superpositions au sol, polylignes, polygones et autres formes), quel que soit le z-index des autres superpositions. Les repères sont en effet considérés comme appartenant à un groupe z-index distinct par rapport aux autres superpositions.

Découvrez l'impact du z-index sur les événements de clic ci-dessous.

Gérer les événements de repère

L'API Maps vous permet d'écouter des événements de repère et d'y répondre. Pour écouter ces événements, définissez l'écouteur correspondant sur l'objet GoogleMap auquel les repères appartiennent. Lorsque l'événement se produit sur l'un des repères de la carte, le rappel de l'écouteur est appelé avec l'objet Marker correspondant transmis en tant que paramètre. Pour comparer cet objet Marker contenant votre propre référence à un objet Marker, vous devez utiliser equals() et non ==.

Vous pouvez écouter les événements suivants :

Événements de clic sur le repère

Vous pouvez utiliser un OnMarkerClickListener pour écouter les événements de clic sur le repère. Pour définir cet écouteur sur la carte, appelez GoogleMap.setOnMarkerClickListener(OnMarkerClickListener). Lorsqu'un utilisateur clique sur un repère, onMarkerClick(Marker) est appelé et le repère est transmis en tant qu'argument. Cette méthode renvoie une valeur booléenne qui indique si vous avez consommé l'événement (pour supprimer le comportement par défaut, par exemple). Si elle renvoie false, le comportement par défaut se produit en plus de votre comportement personnalisé. Le comportement par défaut pour un événement de clic sur un repère est d'afficher sa fenêtre d'informations si elle est disponible et de déplacer la caméra de sorte que le repère soit centré sur la carte.

Effet du z-index sur les événements de clic :

  • Lorsqu'un utilisateur clique sur un groupe de repères, l'événement de clic est déclenché pour le repère associé au z-index le plus élevé.
  • Un seul événement peut être déclenché par clic. En d'autres termes, le clic n'est pas répercuté sur les repères ni sur d'autres superpositions ayant des valeurs z-index moins élevées.
  • Lorsque l'utilisateur clique sur un groupe de repères, les clics suivants sélectionnent tour à tour tous les autres repères du groupe. L'ordre dépend d'abord de la valeur z-index, puis de la proximité avec le point sur lequel l'utilisateur a cliqué.
  • Si l'utilisateur ne clique pas à proximité du groupe, l'API recalcule le groupe et réinitialise le cycle de clics pour qu'il recommence du début.
  • L'événement de clic passe des groupes de repères aux autres formes et superpositions avant de revenir au début du cycle.
  • Les repères sont en effet considérés comme appartenant à un groupe z-index distinct par rapport aux autres superpositions ou formes (polylignes, polygones, cercles et/ou superpositions au sol), quel que soit le z-index des autres superpositions. Si plusieurs repères, superpositions ou formes sont superposés les uns aux autres, l'événement de clic passe d'abord d'un repère à l'autre dans le groupe de repères, puis il est déclenché pour les autres superpositions ou formes en fonction de leur valeur z-index.

Événements de déplacement du repère

Vous pouvez utiliser un OnMarkerDragListener pour écouter les événements de déplacement de repère. Pour définir cet écouteur sur la carte, appelez GoogleMap.setOnMarkerDragListener. Pour faire glisser un repère, l'utilisateur doit appuyer dessus de façon prolongée. Lorsqu'il retire son doigt de l'écran, le repère reste dans cette position. Lorsqu'un repère est déplacé, onMarkerDragStart(Marker) est appelé initialement. Pendant le déplacement du repère, onMarkerDrag(Marker) est appelé en continu. À la fin du déplacement, onMarkerDragEnd(Marker) est appelé. Vous pouvez obtenir la position du repère à tout moment en appelant Marker.getPosition().