Aller au contenu principal

POST /v1/match

Vue d'ensemble​

Le map matching prend une séquence de coordonnées GPS (par ex. issues d'un traceur de véhicule ou d'une application de fitness) et la recale sur l'itinéraire le plus probable du réseau routier réel. Le résultat est une géométrie propre, alignée sur les routes, avec des estimations de distance et de durée.

Requête​

POST https://api.geocodeme.net/v1/match
Content-Type: application/json

Headers requis :

  • X-Api-Key: gm_YOUR_API_KEY
  • Content-Type: application/json

Corps de la requête​

ChampTypeRequisDéfautDescription
coordinatesarrayOuiaucunTableau de paires [longitude, latitude] (min 2, max 100 points)
timestampsarrayNonaucunTableau de timestamps UNIX (secondes) ; doit avoir la même longueur que coordinates
radiusesarrayNonaucunRayon de recherche en mètres par point de coordonnée (défaut : 5 m par point)
profilestringNoncarProfil de routage : car, bike, foot, truck ou moto, soumis au plan (voir plus bas)
geometriesstringNongeojsonFormat de la géométrie de sortie : geojson, polyline ou polyline6
overviewstringNonfullNiveau de détail de l'aperçu de l'itinéraire : full, simplified ou false
attributesarrayNonaucunEnrichit la réponse de segments par tronçon : street_names, speed_limit, road_class (sans surcoût en crédits)
use_tollsbooleanNonaucunPréférer (true) ou éviter (false) les péages, profils motorisés uniquement (400 sur bike/foot)
truck_height / truck_width / truck_weightnumberNonaucunGabarit du véhicule (m / m / tonnes), exige profile: "truck" (400 sinon)

Coût : 1 crédit, plus 1 par bloc de 25 points entamé au-delà des 25 premiers (25 points → 1 crédit, 26 → 2, 100 → 4). Voir Crédits & quotas.

Gating par plan : car est disponible sur tous les plans ; bike et foot exigent Startup ou plus ; truck et moto exigent Growth ou plus. Un profil hors plan renvoie 403 PLAN_UPGRADE_REQUIRED, sans jamais consommer de crédit. Avec attributes, la réponse porte un tableau segments (length_meters + les attributs demandés) ; si l'enrichissement est temporairement indisponible, segments vaut null et confidence 0.0 ; la géométrie recalée, elle, n'est pas affectée.

attention

Les coordonnées sont dans l'ordre [longitude, latitude] (standard GeoJSON), et non [lat, lon]. C'est l'inverse des paramètres de requête de /v1/geocode et /v1/reverse.

Limites du nombre de coordonnées

Le tableau coordinates doit contenir au moins 2 et au plus 100 points. L'API renvoie une erreur INVALID_PARAMETER si le tableau est en dehors de cette plage. Pour un point unique, utilisez plutôt /v1/nearest.

info

Le paramètre de requête format n'est pas pris en charge sur cet endpoint. Le format de la géométrie est contrôlé par le champ geometries du corps de la requête (geojson, polyline ou polyline6).

Exemples de code​

curl -X POST \
-H "X-Api-Key: gm_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"coordinates": [
[2.3522, 48.8566],
[2.3488, 48.8534],
[2.3470, 48.8521]
],
"profile": "car",
"geometries": "geojson"
}' \
"https://api.geocodeme.net/v1/match"

Réponse​

info

Toutes les réponses incluent les headers de limitation de débit (X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Monthly-Remaining, etc.).

Avec geometries=geojson (défaut) :

{
"matched_coordinates": [
[2.3522, 48.8566],
[2.3510, 48.8555],
[2.3495, 48.8540],
[2.3488, 48.8534],
[2.3475, 48.8525],
[2.3470, 48.8521]
],
"geometry_polyline": null,
"confidence": 0.95,
"distance_meters": 620.4,
"duration_seconds": 78.2,
"attribution": "Route data (c) OpenStreetMap contributors",
"meta": {
"took_ms": 62,
"cache_hit": false
}
}

Avec geometries=polyline (ou polyline6), la géométrie est renvoyée sous forme de chaîne encodée à la place :

{
"matched_coordinates": null,
"geometry_polyline": "u`fiHiuqM^`BhAtEjBdI",
"confidence": 0.95,
"distance_meters": 620.4,
"duration_seconds": 78.2,
"attribution": "Route data (c) OpenStreetMap contributors",
"meta": {
"took_ms": 62,
"cache_hit": false
}
}

Schéma​

ChampTypeDescription
matched_coordinatesarray | nullItinéraire recalé sous forme de paires [[longitude, latitude], ...], renseigné quand geometries=geojson, null sinon
geometry_polylinestring | nullChaîne polyline encodée, renseignée quand geometries=polyline ou polyline6, null sinon
confidencefloatConfiance de l'appariement entre 0 et 1
distance_metersfloatDistance totale de l'itinéraire recalé en mètres
duration_secondsfloatDurée de trajet en secondes. Estimée d'après le réseau routier, ou, si vous envoyez timestamps, lue dans ceux-ci : le temps écoulé entre votre premier et votre dernier point apparié, arrêts compris
attributionstringToujours "Route data (c) OpenStreetMap contributors"
meta.took_msintegerTemps de traitement serveur en millisecondes
meta.cache_hitbooleanIndique si la réponse a été servie depuis le cache
remarque

Avec overview=false, matched_coordinates et geometry_polyline valent tous deux null ; seuls la confiance, la distance et la durée sont renvoyées.

Traces comportant des coupures​

Certaines traces ne peuvent pas être appariées comme un trajet continu. Le cas courant est le demi-tour : la route ne peut pas être raccordée à elle-même en sens inverse, le moteur parcourt donc la trace en plusieurs morceaux. Les allers-retours et les boucles comportent ainsi au moins une coupure.

La réponse décrit malgré tout la trace entière. matched_coordinates et geometry_polyline la couvrent d'un bout à l'autre, reliés par une ligne droite au droit de chaque coupure, et distance_meters compte tous les morceaux. Seuls les index de segments portent la trace de la couture, comme décrit ci-dessous.

Pour savoir où sont les coupures, repérez les ruptures dans les index de segments : un segment dont le from_index n'est pas le to_index précédent ouvre un nouveau morceau.

Segments (attributes)​

Lorsque attributes est demandé, la réponse porte un tableau segments, une entrée par tronçon de route apparié :

{
"segments": [
{
"street_names": ["Quai Perrache"],
"road_class": "primary",
"length_meters": 650.0,
"speed_limit_kph": null,
"from_index": 0,
"to_index": 12
},
{
"street_names": ["A7", "E15"],
"road_class": "motorway",
"length_meters": 4300.0,
"speed_limit_kph": 130,
"from_index": 12,
"to_index": 47
}
]
}
ChampTypeDescription
length_metersfloatLongueur du tronçon en mètres
street_namesarray | nullNoms de rue, si street_names a été demandé
speed_limit_kphinteger | nullVitesse limite, si speed_limit a été demandé et est connue
road_classstring | nullClasse de route, si road_class a été demandé
from_indexinteger | nullIndex du premier sommet du tronçon dans la géométrie renvoyée par cette réponse
to_indexinteger | nullIndex du dernier sommet du tronçon dans la même géométrie

from_index et to_index situent le tronçon sur la géométrie renvoyée dans la même réponse, décodée. Les deux bornes sont inclusives : deux segments consécutifs partagent donc normalement leur sommet de jonction, soit segments[i].to_index == segments[i+1].from_index. Le premier segment commence à 0, le dernier se termine à len(geometry) - 1.

Seule exception, une coupure (voir plus haut) : là où la trace n'a pas pu être appariée d'un bout à l'autre, le segment suivant démarre un sommet plus loin (segments[i+1].from_index == segments[i].to_index + 1). Parcourez le tableau avec from_index plutôt qu'en supposant le to_index précédent.

Les deux champs sont omis quand la position ne peut pas être garantie

La géométrie et les attributs proviennent de deux appels moteur distincts. Lorsque leurs formes ne peuvent pas être prouvées identiques, from_index et to_index sont omis plutôt qu'approximés : un index désignant une forme qui n'a pas été servie nommerait le mauvais tronçon de route tout en paraissant parfaitement valide. Ils sont également absents avec overview=false, puisqu'aucune géométrie n'est renvoyée.

Traitez leur absence comme « position inconnue » et repliez-vous en conséquence. Ne reconstruisez jamais une position en cumulant length_meters : cette valeur vaut 0 quand la donnée manque, le résultat serait faux sans que rien ne le signale.

Réponses d'erreur​

{
"error": {
"code": "INVALID_PARAMETER",
"message": "Parameter 'coordinates' must contain between 2 and 100 coordinate pairs",
"field": "coordinates"
}
}
astuce

Tous les endpoints sont également soumis aux erreurs INVALID_API_KEY (401) et RATE_LIMIT_EXCEEDED / QUOTA_EXCEEDED (429). Consultez Codes d'erreur pour la référence complète.