Repères

Les repères indiquent des points géographiques uniques sur la carte. Vous pouvez personnaliser vos repères en changeant la couleur par défaut, ou en remplaçant l'icône du repère par une image personnalisée. Les fenêtres d'informations peuvent fournir plus de contexte sur un repère.

Exemples de code

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

Java

Kotlin

Introduction

Les repères identifient des points géographiques 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. En définissant la propriété draggable d'un repère sur true, l'utilisateur peut modifier la position du repère. Pour déplacer le repère, il suffit d'appuyer de manière prolongée dessus.

Par défaut, lorsqu'un utilisateur appuie sur un repère, la barre d'outils de la carte apparaît en bas à droite de celle-ci, 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 aborde les aspects fondamentaux de l'ajout de repères à votre carte à l'aide du 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 courant de vouloir afficher des informations supplémentaires sur un lieu lorsque l'utilisateur appuie sur un repère sur la carte. Consultez le guide des 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 comptabiliser le nombre de fois où un utilisateur a cliqué sur un repère à l'aide de tags :

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 de scénarios dans lesquels il est utile de stocker et de récupérer des données à l'aide de repères :

  • Votre application peut prendre 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 pour indiquer son type.
  • Vous pouvez être en interface avec un système qui présente des identifiants d'enregistrement uniques et dans lequel les repères représentent des enregistrements spécifiques.
  • Les données de repère peuvent indiquer une priorité à utiliser lors du choix de la propriété 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 explicitement définir 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é à la carte. Vous pouvez écouter les événements de déplacement sur le repère, comme décrit 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 différentes façons d'utiliser des repères pour visualiser des points géographiques 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 définir un certain nombre de propriétés qui déterminent le comportement visuel du repère.

Les repères peuvent être personnalisés par le biais des 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
Le 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 si vous souhaitez 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 telle que le repère est toujours face à la caméra.

Le fragment 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

Il est possible de 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 avec 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 à l'aide de 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 d'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 permet de créer 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 dimension 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 avec 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 telle que le repère est 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

La propriété z-index indique l'ordre d'empilement d'un repère par rapport aux autres repères sur la carte. Un repère avec une propriété z-index élevée apparaît au-dessus des repères ayant une propriété z-index moins élevée. La valeur par défaut de la propriété 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 à la propriété z-index du repère en appelant Marker.getZIndex() et la 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), et ce quelle que soit la propriété 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 de la propriété 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 et de répondre à des événements de repère. Pour écouter ces événements, vous devez définir 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.

Incidence de la propriété 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 ayant la valeur z-index la plus élevée.
  • 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 ou 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), et ce quelle que soit la propriété z-index des autres superpositions. Si plusieurs repères, superpositions ou formes sont superposées les un(e)s sur les 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é au départ. Pendant le déplacement du repère, onMarkerDrag(Marker) est appelé en contenu. À la fin du déplacement, onMarkerDragEnd(Marker) est appelé. Vous pouvez obtenir la position du repère à tout moment en appelant Marker.getPosition().