mapbox-android-patterns

Par mapbox · mapbox-agent-skills

Modèles d'intégration officiels pour le SDK Mapbox Maps sur Android. Couvre l'installation, l'ajout de marqueurs, la localisation utilisateur, les données personnalisées, les styles, le contrôle de la caméra et les interactions avec les featureset. Basé sur la documentation officielle de Mapbox.

npx skills add https://github.com/mapbox/mapbox-agent-skills --skill mapbox-android-patterns

Modèles d'intégration Mapbox Android

Modèles officiels pour intégrer Mapbox Maps SDK v11 sur Android avec Kotlin, Jetpack Compose et le système View.

Utilisez cette skill quand :

  • Installation et configuration de Mapbox Maps SDK pour Android
  • Ajout de marqueurs et d'annotations aux cartes
  • Affichage de la localisation utilisateur et suivi avec la caméra
  • Ajout de données personnalisées (GeoJSON) aux cartes
  • Travail avec les styles de carte, la caméra ou l'interaction utilisateur
  • Gestion des interactions de features et des appuis

Ressources officielles :


Installation & Configuration

Prérequis

  • Android SDK 21+
  • Kotlin ou Java
  • Android Studio
  • Compte Mapbox gratuit

Étape 1 : Configurer le token d'accès

Créez app/res/values/mapbox_access_token.xml :

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools">
    <string name="mapbox_access_token" translatable="false"
        tools:ignore="UnusedResources">YOUR_MAPBOX_ACCESS_TOKEN</string>
</resources>

Obtenir votre token : Connectez-vous sur mapbox.com

Étape 2 : Ajouter le référentiel Maven

Dans settings.gradle.kts :

dependencyResolutionManagement {
    repositories {
        google()
        mavenCentral()
        maven {
            url = uri("https://api.mapbox.com/downloads/v2/releases/maven")
        }
    }
}

Étape 3 : Ajouter la dépendance

Dans le module build.gradle.kts :

android {
    defaultConfig {
        minSdk = 21
    }
}

dependencies {
    implementation("com.mapbox.maps:android:11.18.1")
}

Pour Jetpack Compose :

dependencies {
    implementation("com.mapbox.maps:android:11.18.1")
    implementation("com.mapbox.extension:maps-compose:11.18.1")
}

Initialisation de la carte

Modèle Jetpack Compose

Carte de base :

import androidx.compose.runtime.*
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.ui.Modifier
import com.mapbox.maps.extension.compose.*
import com.mapbox.maps.Style
import com.mapbox.geojson.Point

@Composable
fun MapScreen() {
    MapboxMap(
        modifier = Modifier.fillMaxSize()
    ) {
        // Initialiser la caméra via MapEffect (Style.STANDARD se charge par défaut)
        MapEffect(Unit) { mapView ->
            // Définir la position initiale de la caméra
            mapView.mapboxMap.setCamera(
                CameraOptions.Builder()
                    .center(Point.fromLngLat(-122.4194, 37.7749))
                    .zoom(12.0)
                    .build()
            )
        }
    }
}

Avec ornements :

MapboxMap(
    modifier = Modifier.fillMaxSize(),
    scaleBar = {
        ScaleBar(
            enabled = true,
            position = Alignment.BottomStart
        )
    },
    compass = {
        Compass(enabled = true)
    }
) {
    // Style.STANDARD se charge par défaut
}

Modèle système View

XML de layout (activity_map.xml) :

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.mapbox.maps.MapView
        android:id="@+id/mapView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

Activity :

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.mapbox.maps.MapView
import com.mapbox.maps.Style
import com.mapbox.geojson.Point

class MapActivity : AppCompatActivity() {
    private lateinit var mapView: MapView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_map)

        mapView = findViewById(R.id.mapView)

        mapView.mapboxMap.setCamera(
            CameraOptions.Builder()
                .center(Point.fromLngLat(-122.4194, 37.7749))
                .zoom(12.0)
                .build()
        )

        mapView.mapboxMap.loadStyle(Style.STANDARD)
    }

    override fun onStart() {
        super.onStart()
        mapView.onStart()
    }

    override fun onStop() {
        super.onStop()
        mapView.onStop()
    }

    override fun onDestroy() {
        super.onDestroy()
        mapView.onDestroy()
    }
}

Ajouter des marqueurs (annotations de points)

Les annotations de points sont la façon la plus courante de marquer des emplacements sur la carte.

Jetpack Compose :

MapboxMap(modifier = Modifier.fillMaxSize()) {
    MapEffect(Unit) { mapView ->
        // Charger d'abord le style
        mapView.mapboxMap.loadStyle(Style.STANDARD)

        // Créer le gestionnaire d'annotations et ajouter les marqueurs
        val annotationManager = mapView.annotations.createPointAnnotationManager()
        val pointAnnotation = PointAnnotationOptions()
            .withPoint(Point.fromLngLat(-122.4194, 37.7749))
            .withIconImage("custom-marker")
        annotationManager.create(pointAnnotation)
    }
}

// Note : Compose n'a pas de composant PointAnnotation déclaratif
// Les marqueurs doivent être ajoutés de façon impérative via MapEffect

Système View :

// Créer le gestionnaire d'annotations (une seule fois, réutiliser pour les mises à jour)
val pointAnnotationManager = mapView.annotations.createPointAnnotationManager()

// Créer le marqueur
val pointAnnotation = PointAnnotationOptions()
    .withPoint(Point.fromLngLat(-122.4194, 37.7749))
    .withIconImage("custom-marker")

pointAnnotationManager.create(pointAnnotation)

Marqueurs multiples :

val locations = listOf(
    Point.fromLngLat(-122.4194, 37.7749),
    Point.fromLngLat(-122.4094, 37.7849),
    Point.fromLngLat(-122.4294, 37.7649)
)

val annotations = locations.map { point ->
    PointAnnotationOptions()
        .withPoint(point)
        .withIconImage("marker")
}

pointAnnotationManager.create(annotations)

Afficher la localisation utilisateur (affichage)

Étape 1 : Ajouter les permissions à AndroidManifest.xml :

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

Étape 2 : Demander les permissions et afficher la localisation :

// Demander d'abord les permissions (utiliser ActivityResultContracts)

// Afficher le puck de localisation
mapView.location.updateSettings {
    enabled = true
    puckBearingEnabled = true
}

Bonnes pratiques de performance

Réutiliser les gestionnaires d'annotations

// Ne pas créer de nouveaux gestionnaires à chaque fois
// val manager = mapView.annotations.createPointAnnotationManager() // à chaque appel

// Créer une fois, réutiliser
val pointAnnotationManager = mapView.annotations.createPointAnnotationManager()

fun updateMarkers() {
    pointAnnotationManager.deleteAll()
    pointAnnotationManager.create(markers)
}

Mises à jour par lot des annotations

// Créer toutes à la fois
pointAnnotationManager.create(allAnnotations)

// Ne pas créer une par une dans une boucle

Gestion du cycle de vie

// Toujours appeler les méthodes du cycle de vie
override fun onStart() {
    super.onStart()
    mapView.onStart()
}

override fun onStop() {
    super.onStop()
    mapView.onStop()
}

override fun onDestroy() {
    super.onDestroy()
    mapView.onDestroy()
}

Utiliser le style standard

// Le style Standard est optimisé et recommandé
Style.STANDARD

// Utiliser d'autres styles uniquement si nécessaire pour des cas d'usage spécifiques
Style.STANDARD_SATELLITE // Imagerie satellite

Dépannage

La carte ne s'affiche pas

Vérifiez :

  1. Token dans mapbox_access_token.xml
  2. Token valide (testez sur mapbox.com)
  3. Référentiel Maven configuré
  4. Dépendance ajoutée correctement
  5. Permission Internet dans le manifest

Le style ne se charge pas

mapView.mapboxMap.subscribeStyleLoaded { _ ->
    Log.d("Map", "Style loaded successfully")
    // Ajouter les couches et les sources ici
}

Problèmes de performance

  • Utiliser Style.STANDARD (recommandé et optimisé)
  • Limiter les annotations visibles à la zone d'affichage
  • Réutiliser les gestionnaires d'annotations
  • Éviter les rechargements fréquents du style
  • Appeler les méthodes du cycle de vie (onStart, onStop, onDestroy)
  • Mettre à jour les annotations par lot

Fichiers de référence

Charger ces références quand vous avez besoin de modèles détaillés pour des sujets spécifiques :

  • references/compose.md -- Jetpack Compose : dépendances, configuration du token, MapboxMap, annotations avec clic, GeoJSON, MapEffect
  • references/annotations.md -- Modèles d'annotations Circle, Polyline et Polygon
  • references/location-tracking.md -- Suivi de la caméra avec la localisation utilisateur + obtenir la localisation actuelle une seule fois
  • references/custom-data.md -- Sources et couches GeoJSON : lignes, polygones, points, mise à jour/suppression
  • references/camera-styles.md -- Contrôle de la caméra (définir, animer, adapter) + styles de carte (intégrés et personnalisés)
  • references/interactions.md -- Interactions avec les features, appuis sur les couches personnalisées, appui long, gestes

Ressources supplémentaires

Skills similaires