Routage et dist_excess¶
Cette page décrit l'étape optionnelle qui prépare puis applique un calcul routé
de dist_excess_m. Elle prolonge l'approche spatiale historique sans appeler
Google Maps par défaut.
Rôle analytique¶
dist_excess_m vise à mesurer une distance additionnelle dans la zone finale de
la leg voiture. Il compare :
- la longueur observée sur la portion finale de la leg voiture après entrée dans
le rayon de 1 000 m autour de la fin de leg, exportée sous
spatial_search_distance_m; - une distance routée de référence entre le point d'entrée dans ce rayon et la fin de la leg voiture.
Le calcul ne route donc pas la leg complète. La leg complète contient le trajet d'accès ordinaire à la destination. Le détour pertinent pour la recherche de stationnement est isolé sur la section finale située dans le rayon autour du stationnement supposé.
Avec le paramètre actuel destination_buffer_m: 1000, la distribution de
spatial_search_distance_m présente mécaniquement beaucoup de valeurs proches
ou supérieures à 1 km : quand la trace coupe le cercle, le point d'entrée est à
1 km à vol d'oiseau de la fin de leg, et la longueur parcourue sur la trace est
généralement supérieure ou égale à cette distance. Ce n'est pas un seuil minimal
de cruising. Les distances de cruising plus courtes ne sont pas filtrées par une
règle à 1 km ; elles ne sont simplement pas mesurées directement par cette
variable de fenêtre finale. Pour les impacts opérationnels, il faut donc
distinguer :
spatial_search_distance_m: longueur de trace dans la fenêtre finale ;dist_excess_positive_m: excès de distance par rapport au chemin routé de référence, plus proche d'une distance additionnelle.
Méthode historique reprise¶
Dans l'archive spatiale, le notebook WP2_WP3.ipynb procédait ainsi :
- extraire la dernière leg voiture avant l'activité de destination ;
- construire un buffer métrique autour de la destination, historiquement 1 000 m ;
- extraire la portion de leg après la dernière entrée dans ce buffer ;
- stocker le premier point de cette portion comme
point_entry_buffer; - appeler Google Directions entre
point_entry_bufferetdestinationen modedriving; - décoder la polyline retournée comme
shortest_path; - calculer
dist_excess = dist_buffer - shortest_path_length; - qualifier les cas
dist_excess > 200 mcomme suspects.
Le nouveau pipeline reprend les points 1 à 4 dans les étapes 22 et 23. Les colonnes préparées sont :
| Colonne actuelle | Rôle |
|---|---|
spatial_affected_geometry_wkb_2056 |
portion finale observée dans le rayon spatial |
spatial_entry_point_wkb_2056 |
origine du futur routage |
destination_wkb_2056 |
destination du futur routage |
spatial_search_distance_m |
longueur de portion observée depuis l'entrée dans le rayon final |
Implémentation actuelle¶
Le routage est désormais préparé par trois scripts optionnels :
PYTHONPATH=src .venv-parking-search/bin/python scripts/25_prepare_routing_candidates.py --config config/default.yaml
Cette commande écrit :
Output/data/routing_candidates.parquet;Output/reports/routing_candidates.csv;Output/data/routing_candidates_xyt_payload.jsonl;Output/reports/routing_candidates_summary.json.
Le fichier JSONL contient une requête par ligne, au format attendu par
xyt_routing :
{"route_id":"declic:...","origin":[6.14,46.20],"destination":[6.15,46.21],"mode":"car","weighting":"distance","geometry":true}
Une fois xyt_routing lancé localement, le routage peut être exécuté :
PYTHONPATH=src .venv-parking-search/bin/python scripts/26_route_dist_excess_xyt.py --config config/default.yaml
Par défaut, si Output/data/routing_results.parquet existe déjà et contient
tous les route_id préparés, le script recharge ce cache et ne renvoie aucune
requête au routeur. Pour forcer un nouveau calcul :
PYTHONPATH=src .venv-parking-search/bin/python scripts/26_route_dist_excess_xyt.py --config config/default.yaml --force
Puis les distances routées peuvent être fusionnées dans les sorties spatiales :
PYTHONPATH=src .venv-parking-search/bin/python scripts/27_apply_routing_dist_excess.py --config config/default.yaml
Cette dernière étape écrit notamment :
Output/data/routing_candidates_with_results.parquet;Output/data/routing_geometry_correspondence.parquet;Output/data/spatial_declic_candidates_routed.parquet;Output/data/pl23_spatial_candidates_routed.parquet;Output/maps/routing_geometry_comparison.html;Output/reports/routing_dist_excess_summary.json.
Par défaut, l'étape 27 refuse de fusionner un cache partiel. C'est volontaire :
un smoke test lancé avec --max-requests ne doit pas être interprété comme un
résultat final. Le paramètre routing.allow_partial_results: true existe
uniquement pour un diagnostic manuel.
Routeur recommandé¶
Le choix recommandé est xyt_routing local avec OSRM distance sur le graphe
régional ch_extended_200km. La version de réseau attendue pour cette
itération est osm-ch_extended_200km-1418d8a09b76af1b.
cd /Users/marc-ed/BAS-local/repos/xyt_routing
docker compose --profile road-ch-extended-200km up -d \
osrm-car-ch-extended-200km \
osrm-car-distance-ch-extended-200km
XYT_ROUTING_SERVICE_CONFIG=configs/service.ch_extended_200km.yaml .venv/bin/xyt-routing-api
Puis, depuis ce dépôt :
PYTHONPATH=src .venv-parking-search/bin/python scripts/26_route_dist_excess_xyt.py --config config/default.yaml
Les coordonnées envoyées sont toujours en [longitude, latitude], EPSG:4326.
Le paramètre routing.mode: car_ch_extended_200km force l'usage du graphe
régional transfrontalier. Le paramètre weighting: distance demande le graphe
voiture optimisé en distance lorsque celui-ci est disponible dans
xyt_routing.
Ce choix remplace l'ancien routage partitionné DACH/France. Une leg dont l'origine et la destination sont de part et d'autre de la frontière doit être routée sur un graphe unique ; concaténer une route DACH et une route France imposerait un point de passage arbitraire et ne garantirait pas le plus court chemin.
Pourquoi pas Google par défaut¶
Google Maps peut être utile pour un audit ponctuel ou pour comparer un résultat
commercial à OSRM local. L'API Routes dispose d'une option
requestedReferenceRoutes: ["SHORTER_DISTANCE"], qui demande une route plus
courte en distance pour l'ensemble du trajet. Cette option n'est pas équivalente
à un graphe routier local versionné :
- la facturation dépend des requêtes et des fonctionnalités activées ;
- le graphe routier et les règles de choix d'itinéraire ne sont pas versionnés dans le projet ;
- les résultats peuvent varier lorsque Google met à jour son réseau ou ses paramètres ;
- l'exécution dépend d'une clé API et d'un quota.
Le coût Google n'est pas proportionnel à la distance routée. Le coût dépend d'abord des événements facturables, des SKU et des fonctionnalités activées. Router le tronçon dans le buffer plutôt que la leg complète ne vise donc pas principalement à économiser des crédits ; c'est surtout le bon choix analytique pour isoler la recherche de stationnement.
Si Google est utilisé plus tard, il doit produire le même contrat de sortie :
route_id, routed_distance_m, routed_duration_seconds, routing_status,
error_code, error_message, version ou date du provider, et éventuellement
géométrie routée.
Sorties et interprétation¶
Après fusion, les principaux champs sont :
| Champ | Interprétation |
|---|---|
routed_distance_m |
distance routée de référence |
routed_duration_seconds |
durée routée de référence |
dist_excess_m |
spatial_search_distance_m - routed_distance_m |
dist_excess_positive_m |
partie positive de dist_excess_m |
spatial_suspicious_dist_excess |
dist_excess_m > suspicious_dist_excess_m |
spatial_candidate_routed |
règle conservatrice ou dist_excess suspect |
La table routing_geometry_correspondence.parquet sert au contrôle et à
l'export géométrique. Elle contient notamment :
| Champ | Interprétation |
|---|---|
route_id |
clé stable de correspondance routage |
leg_id |
identifiant de leg source |
source_dataset |
declic ou pl23 |
observed_geometry_wkb_2056 |
portion GPS observée dans le buffer, EPSG:2056 |
routed_geometry_geojson |
géométrie routée retournée par xyt_routing, EPSG:4326 |
routed_geometry_wkb_2056 |
même géométrie routée projetée en EPSG:2056 |
observed_geometry_length_m |
longueur métrique de la géométrie observée |
routed_geometry_length_m_2056 |
longueur métrique de la géométrie routée |
network_version |
version du graphe routier local |
La carte routing_geometry_comparison.html affiche un échantillon de cas avec :
- segment GPS observé dans le buffer ;
- route OSRM distance entre entrée buffer et destination ;
- point d'entrée buffer ;
- destination / fin de leg.
Un dist_excess_m négatif ou très faible n'implique pas nécessairement une
absence de recherche de place. Il peut aussi venir d'une géométrie observée
tronquée, d'un point d'entrée mal localisé, d'un routage non comparable ou d'un
stationnement avant la destination déclarée.
Statut¶
La préparation des paires de routage est implémentée et testée. Le run courant
utilise xyt_routing avec le graphe régional
osm-ch_extended_200km-1418d8a09b76af1b. Le cache complet contient 36 949
routes valides sur 36 950 paires préparées. L'échec résiduel et les valeurs
extrêmes de dist_excess_m doivent encore être audités avant de figer une Base
3 officielle.