|
Simulateur Ferroviaire
Reconstruction et visualisation d'un réseau ferroviaire à partir de données GeoJSON — Win32 / WebView2 / Leaflet
|
Le module Elements constitue le modèle de domaine du simulateur. Il fournit la hiérarchie de classes représentant les objets physiques de l'infrastructure ferroviaire — sections de voie et aiguillages — dans leur état opérationnel courant.
Ces classes sont produites par le pipeline GeoParser, stockées dans TopologyData et consommées par le module PCC et le rendu WebView.
La hiérarchie est délibérément plate : deux niveaux d'abstraction suffisent pour couvrir l'ensemble de l'infrastructure cible.
Element est la racine abstraite. Elle impose deux contrats minimaux :
getId()** — identifiant unique sous la forme "s/N" (straight) ou "sw/N" (switch), attribué par le pipeline lors de la Phase 6.getType()** — discriminant ElementType::STRAIGHT ou ElementType::SWITCH, utilisé pour éviter le dynamic_cast dans le code de rendu critique.La copie est interdite (risque de slicing). Le déplacement est autorisé pour les constructions par make_unique et les insertions en vecteur.
Tous les éléments partagent un unique Logger m_logger("Elements") déclaré statique dans Element. Cela garantit qu'un seul fichier Logs/Elements.log est créé, même en présence de centaines d'instances. Le mutex interne au Logger assure la thread-safety.
ShuntingElement étend Element avec la notion d'état opérationnel :
| ShuntingState | Signification |
|---|---|
FREE | Élément libre, opérationnel (défaut) |
OCCUPIED | Un véhicule est présent sur l'élément |
INACTIVE | Hors service — panne ou maintenance |
Les accesseurs de commodité isFree(), isOccupied(), isInactive() évitent les comparaisons répétitives avec l'enum.
L'état est mutable en runtime par l'opérateur (clic Leaflet sur un aiguillage) ou par la simulation. Les mutations passent par setState().
Note de conception : Le destructeur virtuel de
ShuntingElementsupprimerait la génération implicite des opérateurs de déplacement en C++17. Ils sont donc réexplicitement déclarés= defaultpour maintenir la déplaçabilité requise parstd::unique_ptretstd::vector.
StraightBlock représente une section de voie droite (tronçon entre deux nœuds frontières, ou entre deux sous-blocs de subdivision).
Chaque straight porte deux polylignes parallèles :
| Collection | Système | Usage |
|---|---|---|
pointsWGS84 | WGS-84 (lat/lon) | Rendu Leaflet via TopologyRenderer |
pointsUTM | UTM zone 30N (x=est, y=nord, mètres) | Calculs métriques pipeline |
Les deux collections ont toujours la même taille et les mêmes indices : pointsWGS84[i] et pointsUTM[i] désignent le même point physique.
getLengthMeters() retourne la longueur Haversine calculée sur WGS-84. getLengthUTM() retourne la longueur euclidienne calculée sur UTM.
Quand maxSegmentLength est dépassé, le pipeline subdivise un straight en N sous-blocs. Les sous-blocs sont chaînés par des pointeurs non-propriétaires :
Ces pointeurs sont posés par Phase6_BlockExtractor::registerStraight avant la résolution de Phase 8. Seuls les sous-blocs de tête et de queue ont des endpoints avec un frontierNodeId valide.
getNeighbourNext() / getNeighbourPrev() retournent les blocs adjacents (straight ou switch) après résolution par Phase8_RepositoryTransfer. getPCCNeighbours() expose les deux sans distinguer next/prev — utilisé par PCCGraphBuilder pour construire les arêtes STRAIGHT.
SwitchBlock représente un aiguillage ferroviaire à 3 branches.
Le point de jonction (junctionWGS84 / junctionUTM) est la position physique de l'aiguillage sur la carte.
Chaque branche est identifiée par l'ID du bloc adjacent (rootId, normalId, deviationId) et par un pointeur résolu (root, normal, deviation) vers le ShuntingElement correspondant.
ActiveBranch indique la voie ouverte :
| Valeur | Signification | Couleur TCO |
|---|---|---|
NORMAL | Voie directe — position repos | Trait horizontal plein |
DEVIATION | Voie déviée — position basculée | Branche oblique active |
toggleActiveBranch(propagate) inverse l'état et propage aux partenaires double-aiguille si propagate == true.
Les tips CDC (Centre De Contre) sont les extrémités des stubs de l'aiguillage sur le schéma TCO. Ils sont interpolés par Phase7_SwitchProcessor à distance switchSideSize de la jonction, en direction de chaque branche :
| Accesseur | Branche |
|---|---|
getTipOnRoot() / getTipOnRootUTM() | Branche root |
getTipOnNormal() / getTipOnNormalUTM() | Branche normale |
getTipOnDeviation() / getTipOnDeviationUTM() | Branche déviée |
Un switch peut absorber le segment de liaison de son partenaire :
L'absorption est stockée dans doubleOnNormal ou doubleOnDeviation (ID du partenaire) et dans absorbedNormalCoords / absorbedDeviationCoords (polyligne WGS-84 absorbée pour le rendu Leaflet).
isDouble() retourne true si l'une des deux absorptions est renseignée.
Un switch est orienté après exécution de Phase7_SwitchProcessor. isOriented() conditionne le rendu des branches dans TCORenderer et TopologyRenderer.
| Classe / enum | Fichier | Rôle |
|---|---|---|
| Element | Modules/Elements/Element.h | Base abstraite |
| ElementType | Modules/Elements/Element.h | Discriminant SWITCH/STRAIGHT |
| ShuntingElement | Modules/Elements/ShuntingElements/ShuntingElement.h | Ajoute getState() |
| ShuntingState | Modules/Elements/ShuntingElements/ShuntingElement.h | FREE/OCCUPIED/INACTIVE |
| StraightBlock | Modules/Elements/ShuntingElements/StraightBlock.h | Section de voie |
| SwitchBlock | Modules/Elements/ShuntingElements/SwitchBlock.h | Aiguillage 3 branches |
| ActiveBranch | Modules/Elements/ShuntingElements/SwitchBlock.h | NORMAL/DEVIATION |