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 référentiel ApiDemos sur GitHub inclut un exemple qui illustre différentes fonctionnalités des repères :

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. Un appui de manière prolongée active la possibilité de déplacer le repère.

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éé au niveau des coordonnées 10,10 et affiche la chaîne "Hello world" dans une fenêtre d'informations lorsque l'internaute clique dessus.

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

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 une carte. Consultez le guide des fenêtres d'informations.

Associer des données à un repère

Vous pouvez stocker un objet de données arbitraires avec un repère en utilisant Marker.setTag(), puis récupérer l'objet de données en utilisant Marker.getTag(), comme illustré dans cet exemple de code :

/**
 * 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;
    }
}

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.

static final LatLng PERTH = new LatLng(-31.90, 115.86);
Marker perth = mMap.addMarker(new MarkerOptions()
                          .position(PERTH)
                          .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.

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

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.

static final LatLng MELBOURNE = new LatLng(-37.813, 144.962);
Marker melbourne = mMap.addMarker(new MarkerOptions()
                          .position(MELBOURNE)
                          .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.

static final LatLng MELBOURNE = new LatLng(-37.813, 144.962);
Marker melbourne = mMap.addMarker(new MarkerOptions()
                          .position(MELBOURNE)
                          .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 crée un repère avec une icône personnalisée.

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

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.

static final LatLng PERTH = new LatLng(-31.90, 115.86);
Marker perth = mMap.addMarker(new MarkerOptions()
                          .position(PERTH)
                          .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°. En réglant le point d'ancrage sur 0.5,0.5, le repère pivote sur son centre, et non sur sa base.

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

@Override
public void onMapReady(GoogleMap map) {
    map.addMarker(new MarkerOptions()
        .position(new LatLng(10, 10))
        .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'incidence 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().