API Navigation

Navigation turn-by-turn, landmarks & voix

Boucle complète : session de navigation, enrichissement landmark, synthèse vocale, rerouting automatique, et mode hors-ligne.

Machine d'état de navigation

Tous les SDKs implémentent la même machine d'état pour la session de navigation :

     ┌────────┐    startNavigation()    ┌──────────────┐
     │  IDLE  │ ───────────────────────►│  NAVIGATING  │◄──────────┐
     └────────┘                         └──────┬───────┘           │
                                               │                   │
                                          deviation               route
                                          > 50m ?                received
                                               │                   │
                                        ┌──────▼───────┐   ┌──────┴───────┐
                                        │  OFF_ROUTE   │──►│  REROUTING   │
                                        └──────────────┘   └──────────────┘
                                                                   │
     ┌──────────┐     distance to                              failure?
     │ ARRIVED  │◄── destination                                   │
     └──────────┘     < 30m                               ┌──────▼───────┐
                                                           │    ERROR     │
                                                           └──────────────┘

Seuils GPS

  • Update : 1 GPS fix par seconde sur appareil
  • Off-route : > 50m de la polyline → reroute
  • Arrivée : < 30m de la destination → ARRIVED

Annonces vocales

  • 500m : « Dans 500 mètres, tournez à droite... »
  • 200m : « Préparez-vous à tourner à droite »
  • 30m : « Tournez à droite maintenant »

Démarrer une session de navigation

TypeScriptJavaScript SDK
import { AfriMapClient } from '@afrimap/sdk'const client = new AfriMapClient({ apiKey: 'afm_live_...' }) // 1. Calculer l'itinéraireconst { routes } = await client.routing.route({ origin: { lat: 5.3197, lng: -4.0167 }, destination: { lat: 5.3480, lng: -3.9904 }, mode: 'auto', language: 'fr', directions_type: 'maneuvers', }) // 2. Créer la session de navigationconst nav = await client.navigation.start({ route: routes[0], voice: 'fr', landmarks: true, // enrichir avec landmarks locaux tts_batch: true, // pré-synthétiser tous les clips audio }) // 3. nav.maneuvers contient les instructions enrichies// nav.audio_urls contient les URLs des clips pré-synthétisés
TerminalcURL - Endpoint direct
 curl -X POST https://api.afrimap.ci/v1/navigate \ -H "X-AfriMap-Key: afm_test_..." \ -H "Content-Type: application/json" \ -d '{ "origin": { "lat": 5.3197, "lng": -4.0167 }, "destination": { "lat": 5.3480, "lng": -3.9904 }, "mode": "auto", "language": "fr", "landmarks": true }'

Enrichissement par landmarks

Chaque manoeuvre est enrichie avec le landmark le plus proche (rayon 200m autour du point de virage). Cela produit des instructions que les gens comprennent naturellement :

Sans landmarks (Valhalla brut)

« Tournez à droite sur Boulevard Latrille »

Avec landmarks (AfriMap)

« Tournez à droite après la Mosquée de Cocody sur Boulevard Latrille »

JSONManoeuvre enrichie
 { "type": "turn", "modifier": "right", "instruction": "Tournez a droite sur Boulevard Latrille", "distance": 450, "duration": 65, "street_names": ["Boulevard Latrille"], "verbal_pre_transition_instruction": "Dans 200 metres, tournez a droite apres la Mosquee de Cocody", "landmark_nearby": { "name": "Mosquee de Cocody", "category": "mosque", "distance_m": 45, "bearing": "right" } }

Synthèse vocale

Deux approches pour la voix, selon votre besoin :

Recommandé

TTS natif (Phase 1)

Utilisez le moteur TTS de l'appareil (Android TextToSpeech / iOS AVSpeechSynthesizer). Zero coût, zero latence réseau.

  • Langues : fr, en (+ toute langue installée)
  • Latence : instantanée
  • Coût : gratuit
  • Hors-ligne : oui
Langues locales

Coqui XTTS v2 (Phase 3)

Service de synthèse vocale côté serveur. Supporte dioula et baoulé via modèles fine-tunés.

  • Langues : fr, en, dioula, baoulé
  • Latence : ~200ms (avec cache Redis)
  • Coût : infra serveur
  • Hors-ligne : pré-cache par route

Synthétiser un clip audio

TypeScriptRequête TTS
// Synthèse individuelleconst audio = await client.navigation.voice({ text: 'Tournez à droite après la Mosquée de Cocody', language: 'fr', format: 'mp3', }) // audio = Blob MP3// Batch : pré-synthétiser toutes les instructions d'un itinéraireconst batch = await client.navigation.voiceBatch({ texts: route.legs[0].maneuvers.map(m => m.verbal_pre_transition_instruction), language: 'fr', }) // batch.audio_urls = URLs des clips MP3 pré-générés

Rerouting automatique

Quand le GPS détecte que l'utilisateur est à > 50m de la polyline, le SDK déclenche automatiquement un recalcul d'itinéraire :

TypeScriptGestion du rerouting (SDK)
// Le SDK gère ça automatiquement, mais vous pouvez écouter : nav.on('reroute', (newRoute) => { console.log('Nouvel itinéraire calculé', newRoute.distance, 'm') // La carte se met à jour automatiquement// Les clips vocaux sont re-synthétisés }) nav.on('offRoute', () => { // L'utilisateur a dévié — rerouting en cours// Annonce vocale urgente : "Recalcul de l'itinéraire" })

Détection off-route

Le point GPS est projeté perpendiculairement sur la polyline. Si la distance haversine entre le point GPS et la projection est > 50m, l'état passe à OFF_ROUTE. Le SDK attend 2 fixes consécutifs hors-route avant de déclencher le rerouting (pour éviter les faux positifs en tunnel).

Caméra de navigation

Pendant la navigation active, la carte adopte un mode « driver view » :

60°

Pitch (inclinaison)

16

Zoom

1s

Transition fluide

Le bearing (direction) suit le heading GPS du conducteur pour que la carte soit toujours orientée dans la direction du mouvement.

Langues disponibles

Consultez /v1/navigate/languages pour le statut en direct de chaque langue :

LangueCodeMoteurStatut
FrançaisfrEdge TTS + Coqui XTTSProduction
AnglaisenEdge TTSProduction
DiouladioulaCoqui XTTS v2 (fine-tuné)En cours
BaoulébaouleCoqui XTTS v2 (fine-tuné)En cours

Endpoints

POST/v1/navigate

Full turn-by-turn navigation session

Bundles `/v1/route` + landmark enrichment + voice-ready instruction variants into a single call tuned for the client navigation state machine described in NAVIGATION.md §4.

Corps de la requête

Schéma : NavigateRequest

JSONExemple
{
  "origin": {
    "lat": 5.3197,
    "lng": -4.0167
  },
  "destination": {
    "lat": 5.348,
    "lng": -3.9904
  },
  "mode": "auto",
  "language": "fr",
  "enrich_landmarks": true
}

Réponses

  • 200Navigation session payload.

Exemples de code

curl -X POST https://api.afrimap.ci/v1/navigate \
  -H "X-AfriMap-Key: $AFM_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "origin":      { "lat": 5.3197, "lng": -4.0167 },
    "destination": { "lat": 5.3480, "lng": -3.9904 },
    "mode": "auto", "language": "fr",
    "enrich_landmarks": true
  }'

Testez-le

Essayer en direct

POST /v1/navigate

Collez une clé sandbox afm_test_…. La requête part directement de votre navigateur vers le gateway, aucun proxy côté portail.

POST http://localhost:8090/v1/navigate
POST/v1/navigate/enrich

Attach landmark hints to existing maneuvers

Takes a list of Valhalla maneuvers (each with `begin_shape_index`) and returns the same list enriched with nearby landmarks within 200 m of each turn point — e.g. "Turn right at the orange mosque".

Corps de la requête

Schéma : object

Réponses

  • 200Enriched maneuvers.

Exemples de code

curl -X POST https://api.afrimap.ci/v1/navigate/enrich \
  -H "X-AfriMap-Key: $AFM_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "maneuvers": [...], "polyline": "e|w_B}..." }'
POST/v1/navigate/voice

Synthesize a single voice prompt

Returns a pointer to a cached audio clip (MP3 or Opus) for the given text + language. French uses Edge TTS; Dioula/Baoulé use a fine-tuned Coqui XTTS model — see `/v1/navigate/languages` for production status.

Corps de la requête

Schéma : VoiceRequest

JSONExemple
{
  "text": "Tournez à droite dans 200 mètres.",
  "language": "fr"
}

Réponses

  • 200Voice response.

    VoiceResponse

Exemples de code

curl -X POST https://api.afrimap.ci/v1/navigate/voice \
  -H "X-AfriMap-Key: $AFM_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "text": "Tournez à droite dans 200 mètres.", "language": "fr" }'

Testez-le

Essayer en direct

POST /v1/navigate/voice

Collez une clé sandbox afm_test_…. La requête part directement de votre navigateur vers le gateway, aucun proxy côté portail.

POST http://localhost:8090/v1/navigate/voice
POST/v1/navigate/voice/batch

Pre-cache every voice prompt for a route

Pre-warms the TTS cache for a whole navigation session in one call so offline navigation works through a network drop. Typical payload: one `VoiceRequest` per maneuver (pre / alert / post).

Corps de la requête

Schéma : object

Réponses

  • 200Array of VoiceResponse in input order.

Exemples de code

curl -X POST https://api.afrimap.ci/v1/navigate/voice/batch \
  -H "X-AfriMap-Key: $AFM_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "prompts": [
    { "text": "Dans 200 mètres, tournez à droite.", "language": "fr" },
    { "text": "Tournez à droite.", "language": "fr" }
  ]}'
GET/v1/navigate/languages

Supported voice languages

Réponses

  • 200Production + coming-soon language codes with backends.

    object

Exemples de code

curl https://api.afrimap.ci/v1/navigate/languages \
  -H "X-AfriMap-Key: $AFM_KEY"

Testez-le

Essayer en direct

GET /v1/navigate/languages

Collez une clé sandbox afm_test_…. La requête part directement de votre navigateur vers le gateway, aucun proxy côté portail.

GET http://localhost:8090/v1/navigate/languages
GET/v1/navigate/audio/{hash}

Stream a pre-synthesized audio clip

Serves the cached audio blob referenced by `VoiceResponse.hash`. Supports HTTP `Range` for partial streaming.

Paramètres

NomEmplacementTypeDescription
hash requiredpathstring

Réponses

  • 200Audio blob (MP3 or Opus).