Calculer une zone de chalandise
Une zone de chalandise réelle n'est pas un disque : la Seine, une
voie ferrée ou un massif changent ce qu'on atteint en quinze
minutes bien plus qu'un rayon en kilomètres ne peut le dire. Ce
guide montre comment demander à GET /locations/search
le contour réellement atteignable en voiture, à pied ou à vélo
depuis l'un de vos sites, puis comment enrichir chaque adresse qui
s'y trouve avec GET /address/view/{id}. Les sites que
vous interrogez viennent de votre propre référentiel ;
s'il n'existe pas encore, créez-le d'abord avec le guide
Mes lieux.
Les trois paramètres qui font une isochrone
Par défaut, /locations/search trie vos sites autour
d'un point avec rayon, un disque en kilomètres à vol
d'oiseau. Pour obtenir une zone de chalandise réelle, remplacez-le
par trois paramètres :
| Paramètre | Rôle | Valeurs |
|---|---|---|
duree |
Durée de trajet en minutes — le rayon de temps, pas de distance | Entier, 1 à 30 |
mode |
Mode de déplacement de l'isochrone ; n'a de sens qu'avec duree |
auto (défaut) · pieton · velo |
polygone |
Demande le contour GeoJSON de la zone dans la réponse | Booléen, défaut false |
duree et rayon sont exclusifs
l'un de l'autre : les envoyer ensemble, ou n'envoyer
aucun des deux, est refusé en 422
(portee_ambigue) — de même qu'un mode
fourni sans duree (mode_sans_duree).
Aucune portée par défaut n'est prêtée d'office : un rayon supposé
serait indiscernable d'un rayon voulu.
Plan Growth
duree (et donc le mode de trajet et le polygone qui
en découlent) demande le plan
Growth. La
recherche par rayon reste accessible dès
Starter.
Un appel, une réponse
Le centre se donne par lat+lon, ou par
adresse — une adresse complète, mais aussi un simple
nom de commune. Voici la zone de chalandise à quinze minutes en
voiture autour de Lyon, contour compris :
curl "https://api.trustydata.app/services/v1/locations/search?referentiel=boutiques&adresse=Lyon&duree=15&mode=auto&polygone=true&limit=5" \
-H "Authorization: Bearer VOTRE_CLE_API"
{
"resultats": [
{
"id_externe": "LYON-BELLECOUR",
"nom_public": "Boulangerie Bellecour",
"ligne_voie": "12 Place Bellecour",
"code_postal": "69002",
"commune": "Lyon",
"latitude": 45.757814,
"longitude": 4.832011,
"distance_m": 241.7,
"ouverture": { "statut": "ouvert", "prochaine_fermeture": "2026-09-05T19:30:00+02:00" },
"statut": "actif",
"geocodage_statut": "non_requis"
}
],
"pagination": { "limit": 5, "offset": 0, "next_offset": null, "total_estime": 1 },
"point_central": {
"lat": 45.75776,
"lon": 4.83201,
"adresse_resolue": "Lyon",
"precision": "commune",
"commune": "Lyon",
"code_insee": "69382"
},
"portee": {
"type": "isochrone",
"duree_min": 15,
"mode": "auto",
"polygone": { "type": "Polygon", "coordinates": [ [ [4.79, 45.72], [4.91, 45.73], "…" ] ] }
},
"attribution": "Données cartographiques © les contributeurs OpenStreetMap, sous licence ODbL — https://www.openstreetmap.org/copyright"
}
Trois blocs à retenir. point_central dit où la
recherche a réellement porté — ici precision: "commune",
parce que la saisie ne désignait ni voie ni numéro : le centre est
celui de la commune, à quelques kilomètres près sur une grande
ville. portee.polygone porte le contour, présent
seulement parce que polygone=true a été demandé (ici
tronqué pour la lisibilité — un vrai contour compte des dizaines de
points). Et chaque entrée de resultats[] garde sa
distance_m à vol d'oiseau : c'est elle qui a classé la
liste, pas le contour, qui ne sert qu'à délimiter qui entre dans la
recherche.
attribution n'apparaît que parce que le moteur
d'itinéraire a été sollicité (une duree, ou
distances=true sur un rayon) : la mention
OpenStreetMap/ODbL est alors obligatoire partout où
le résultat est affiché — voir Attribution OSM.
Lire le contour
portee.polygone est un objet GeoJSON standard —
Polygon ou MultiPolygon selon la forme de
la zone atteignable — en coordonnées WGS84
(longitude, latitude, dans cet ordre). C'est le format que
consomment nativement Leaflet, Mapbox GL ou MapLibre pour tracer un
calque : pas de reprojection à faire.
const zone = reponse.portee.polygone;
L.geoJSON(zone, { style: { color: 'seagreen', weight: 2, fillOpacity: 0.1 } })
.addTo(carte);
Le contour pèse 10 à 20 Ko selon la complexité de
la zone — c'est pour cela qu'il n'est jamais renvoyé par défaut :
une intégration qui ne veut que la liste des sites (un widget « le
plus proche de vous ») n'a pas à le transporter. Ne demandez
polygone=true que sur l'appel qui affiche
effectivement une carte.
Enrichir — par adresse
Le contour délimite une zone ; il ne dit rien de qui y habite.
Pour qualifier ce que vous voyez sur la carte — une adresse
candidate à un nouveau site, un point de passage identifié dans la
zone — appelez GET /address/view/{id} sur
l'adresse précise qui vous intéresse, pas sur la
zone :
curl "https://api.trustydata.app/services/v1/address/view/69382_1080_00012" \
-H "Authorization: Bearer VOTRE_CLE_API"
La richesse de la réponse dépend du plan de votre clé, comme pour
tout endpoint /address/* : le plan
Discovery rend
déjà l'adresse restituée ; le plan
Starter ajoute
la position (WGS84 et Lambert 93) ; le plan
Growth ajoute le
bloc geocoding, dont geocoding.code_iris —
l'identifiant de la zone IRIS INSEE qui contient l'adresse ; le plan
Business ajoute
statistical_grid, la maille de 200 m de la grille
Filosofi (INSEE) dans laquelle tombe cette adresse précise, avec son
nombre d'habitants et de ménages.
L'API ne calcule pas la population d'une zone.
statistical_grid décrit la maille de 200 m d'une
adresse, appelée une par une — jamais l'agrégat
d'un contour d'isochrone ni d'un rayon. Additionner les mailles
des adresses que vous avez enrichies donnerait un chiffre, mais
ce chiffre serait le vôtre, construit par vos soins avec les
précautions de dénombrement qui s'imposent (mailles à cheval sur
le contour, doubles comptes) — pas une valeur rendue par
TrustyData.
Ce que le contour ne dit pas
-
Pas d'agrégation. Ni population, ni revenu, ni
nombre de ménages « de la zone » : voir l'avertissement
ci-dessus. Chaque chiffre statistique sort d'une adresse
individuelle via
/address/view/{id}. -
Le tri des résultats reste à vol d'oiseau.
portee.polygonedélimite qui entre dans la recherche ; il ne change pas l'ordre deresultats[], toujours classé surdistance_m. -
L'enrichissement routier s'arrête à 25 résultats.
Avec
distances=true, les 25 premiers résultats de la page gagnentduree_setdistance_routiere_m(calculés dans lemodede la portée) ; au-delà, les deux champs valentnull. C'est un enrichissement de la page rendue, pas un second tri : voir Mes lieux pour le détail des bornes et de la pagination.
Aller plus loin
- Démo — Zone de chalandise — tester en direct sans écrire de code
- Cas d'usage — Zone de chalandise
- Article — Calculer une zone de chalandise
- Référence complète —
GET /locations/searchen détail, tous les paramètres - Mes lieux — créer et alimenter le référentiel de sites interrogé ici
- Attribution OSM — la mention à afficher dès qu'une
dureeentre en jeu
Sources des données mobilisées par ce guide : le référentiel BAN officiel (IGN) et l'INSEE (IRIS, grille Filosofi) pour les adresses ; OpenStreetMap, sous licence ODbL, pour le réseau routier qui dessine l'isochrone.