TrustyData Docs
Site Tarifs Contact

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ètreRôleValeurs
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.polygone délimite qui entre dans la recherche ; il ne change pas l'ordre de resultats[], toujours classé sur distance_m.
  • L'enrichissement routier s'arrête à 25 résultats. Avec distances=true, les 25 premiers résultats de la page gagnent duree_s et distance_routiere_m (calculés dans le mode de la portée) ; au-delà, les deux champs valent null. 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

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.