feat(data): inclure les trains SNCF (TER/TGV) autour de Grenoble #15
Labels
No labels
bug
duplicate
enhancement
help wanted
invalid
question
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
CyrilLeblanc/gresit#15
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Contexte
L'app n'affiche aucun train SNCF aujourd'hui, par construction : le générateur de données statiques (
scripts/generate_transit_data.py) filtre les routes surURBAN_PREFIXES = {"SEM", "GSV", "SE2", "MCO", "TPV"}et prune ensuite toute ligne sans géométrie (lignes 415-426). Les 20 routes SNCF de l'API M réso (préfixeSNC:) sont donc doublement exclues — alors qu'elles desservent Grenoble (Grenoble Gare / Gières / Échirolles…) et que leurs horaires temps réel fonctionnent sur la même API que les bus.Faits vérifiés le 2026-08-23 (ne pas re-vérifier) :
routers/default/index/routesexpose 20 routesSNC:*: TGV Paris-Grenoble (621A,770A), TER Lyon (K6), Chambéry (C1,C31), Valence/Genève (K11,K21), Saint-Marcellin (C6,C11), Gap/Briançon (P24,P25), etc.clusters/SNC:OCE87747006/stoptimes(Grenoble Gare) renvoie des patterns SNC avecrealtime=True(TGV INOUI, TER INTER). Le pipeline ETA existant (repository →GetEtas→EtaGrouper) fonctionne donc sans modification de fond.lines/json?codes=SNC_*ne renvoie AUCUNE géométrie pour les lignes SNCF (testéSNC_K6,SNC:C1,SNC_K21→ 0 feature). C'est le vrai blocker : le pruning du générateur supprimerait ces lignes même sans le filtre de préfixe.ficheHoraires/json?route=SNC:K6fonctionne et donne les arrêts ordonnés par direction avec positions (ex. direction 0 : Grenoble → Voiron → La Tour-du-Pin…). Une géométrie de substitution (polyligne reliant les arrêts dans l'ordre) est donc constructible.SNC:OCE<code>(nomenclature SNCF « OCE »), ex.SNC:OCE87747006(Grenoble), avec des enfants physiques du typeSNC:OCETGVINOUI-87747006/SNC:OCETRAINTER-87747006(un enfant par type de service).Comportement attendu
scripts/generate_transit_data.py) inclut les routesSNC:*:URBAN_PREFIXES ∪ {"SNC"};lines/jsonne renvoie pas de géométrie pour une ligne (cas SNCF), construire une géométrie de substitution : un segment unique reliant les positions des arrêts du premierficheHorairesdisponible, dans l'ordre (résolution ~stations, pas du tracé réel — acceptable pour une ligne ferroviaire dont on montre la desserte) ;scripts/validate_transit_data.py) : les seuils minimaux (≥150 lignes…) restent valables ; les compteurs ±15 % vont sauter au premier run avec les SNCF incluses (+20 lignes ≈ +11 % — dans la tolérance) ; vérifier que les checks structurels passent (les stops SNCF auront leurs enfantsclusterStopsvia l'endpoint routes/{id}/stops, déjà le cas dans le flow existant).shortNameSNCF du typeK6,C1,P24se prêtent au badge, mais la confusion avec les ChronoC1urbains est réelle — voir « Pistes ») ;ALWAYS_VISIBLE_IDS(trop longue portée — n'afficher que sur demande / zoom adapté) ;Bearings.ktfonctionne sur les séquences — les séquences SNCF existeront (ficheHoraires par direction), le bearing s'en déduira naturellement.Pistes d'implémentation
fetch_direction_stopsdéjà présent (il retourne lat/lon par arrêt ordonné). Marquer ces géométries (ex. champsynthetic: truedans le JSONgeometries) pour permettre à l'app de styliser différemment (trait pointillé ?) et au validateur de les compter séparément."version": 3; champgeneratedAtinchangé. L'app litignoreUnknownKeys = true— champsyntheticoptionnel côté Kotlin.lineName = routeId.substringAfter(":")donneraitOCE87747006-adjacent pour les groupes — non : pour les groupes SNCF, le nom affiché doit venir dushortNamede la ligne (K6, C31…), déjà le comportement vialines[routeId]. VérifierlineSortKeypour un tri lisible des trains (peut-être un groupe distinct « Trains » en tête de feuille d'arrêt).C1: la ligne SNCFSNC:C1(Grenoble-Chambéry) vs le Chrono urbainSEM:C1. Les IDs restent distincts (SNC:C1≠SEM:C1) donc pas de collision technique, mais l'affichage doit lever l'ambiguïté visuelle (préfixe TER / icône train / couleur SNCF vs couleur M réso).names_match+ 200 m pourrait fusionner certains couples — observer le comportement au premier import).Critères d'acceptation
SNC:*avec géométries (réelle ou substitution), séquences par direction, stops etclusterStops.validate_transit_data.pypasse sur le JSON étendu (structurel + drift vs version précédente, en tenant compte du saut attendu de compteurs).C1SNCF n'est confondu avec le ChronoC1à l'affichage (libellé ou style distinct).clusterStopset le drawer d'arrêt ne casse pas sur un enfant au nom long (SNC:OCETGVINOUI-…)../gradlew assembleDebugpasse ; pas de régression sur les lignes urbaines existantes (compteurs identiques ±0 hors ajout SNCF).Notes / captures (optionnel)
SNC:OCE87747006stoptimes OK (realtime=True),ficheHorairesOK pourSNC:K6,lines/jsonvide pour tous les codes SNCF testés.routes/{id}/stopsdes routes SNC renvoie les arrêts aveccluster→ le mécanisme existant d'enfants physiques s'applique tel quel.