TRO-Fluss: je Typ eigenes Symbol im Diagramm, Weichenerkennung ueber Scanner

lib/tro_catalog.py: dot_shape_attrs()/SYMBOL_LABELS geben render_dot() eine
Graphviz-Form je TroSymbol (bisher nur fuer den CAD-Marker in tro_annotate.py
genutzt) - Farbe gruppiert weiterhin verwandte Typen, Form unterscheidet den
einzelnen Typ. Legende und Doku-Tabellen zeigen jetzt jeden Katalogtyp mit
Farbe+Symbol statt nur die 6 Farbgruppen.

lib/tro_flow.py: _find_switch_separators() bekommt einen zweiten Durchlauf,
der einen Separator mit eigenem Scanner (CAD-Merkmal "Naechster Separator")
als Weiche erkennt, wenn die reine Abstandsregel (SWITCH_PROXIMITY_MM) ihn
verfehlt - Rolle (Aus-/Einschleusung) wird aus einem bereits bestaetigten
Treffer auf derselben Kreisel-Bahn gelesen, keine neue feste mm-Schwelle.
Grund: bei HundM05 (5 Abzweige an einem Kreisel) lagen 3 der 5 echten
Weichen-Separatoren 727-1139mm von ihrem Ausschleuselement entfernt - ausserhalb
der auf einer aelteren Revision kalibrierten 500mm-Grenze - und wurden bisher
faelschlich als einfacher 1Sep statt 1Sep1Swi eingestuft.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Samer Ayadi
2026-09-18 16:12:13 +02:00
co-authored by Claude Sonnet 5
parent 60f855fff5
commit 72d0a21f65
2 changed files with 140 additions and 24 deletions
+60 -2
View File
@@ -77,6 +77,9 @@ __all__ = [
"set_tro",
"catalog",
"mermaid_classdefs",
"dot_shape_attrs",
"SYMBOL_LABELS",
"symbol_label",
]
# Stand der Dokumente, aus denen die Typdefinition uebernommen wurde
@@ -165,6 +168,53 @@ class TroSymbol:
)
# Graphviz-Knotenform je Symbol, fuer render_dot() in tro_flow.py. Peripheries
# zeichnet die Doppel-Varianten als zwei konzentrische Formen - dasselbe Bild,
# das draw_shape() in tro_annotate.py fuer den CAD-Marker als zwei ineinander
# liegende Polygone zeichnet. Namen sind Graphviz-Bordformen (dot -Tsvg).
_DOT_SHAPE: dict[str, dict[str, str]] = {
TroSymbol.CIRCLE: {"shape": "circle"},
TroSymbol.DOUBLE_CIRCLE: {"shape": "circle", "peripheries": "2"},
TroSymbol.TRIANGLE: {"shape": "triangle"},
TroSymbol.TRIANGLE_DOWN: {"shape": "invtriangle"},
TroSymbol.DOUBLE_TRIANGLE_DOWN: {"shape": "invtriangle", "peripheries": "2"},
TroSymbol.SQUARE: {"shape": "square"},
TroSymbol.DIAMOND: {"shape": "diamond"},
TroSymbol.PENTAGON: {"shape": "pentagon"},
TroSymbol.HEXAGON: {"shape": "hexagon"},
TroSymbol.RECT: {"shape": "box"},
TroSymbol.ARROW: {"shape": "rarrow"},
}
def dot_shape_attrs(symbol: str) -> dict[str, str]:
"""Graphviz-Knotenform (shape[, peripheries]) fuer ein TroSymbol; unbekannte
Symbole fallen auf die normale Box zurueck."""
return dict(_DOT_SHAPE.get(symbol, {"shape": "box"}))
# Klartext je Symbol - fuer die Legende in render_dot()/render_doc() (tro_flow.py),
# damit dort nicht nur die Farbgruppe, sondern auch die Form je Typ lesbar ist.
SYMBOL_LABELS: dict[str, str] = {
TroSymbol.CIRCLE: "Kreis",
TroSymbol.DOUBLE_CIRCLE: "Doppelkreis",
TroSymbol.TRIANGLE: "Dreieck (Spitze oben)",
TroSymbol.TRIANGLE_DOWN: "Dreieck (Spitze unten)",
TroSymbol.DOUBLE_TRIANGLE_DOWN: "Doppel-Dreieck (Spitze unten)",
TroSymbol.SQUARE: "Quadrat",
TroSymbol.DIAMOND: "Raute",
TroSymbol.PENTAGON: "Fuenfeck",
TroSymbol.HEXAGON: "Sechseck",
TroSymbol.RECT: "liegendes Rechteck",
TroSymbol.ARROW: "Pfeil",
}
def symbol_label(symbol: str) -> str:
"""Klartext eines Symbols; der Symbolname selbst, wenn kein Klartext hinterlegt ist."""
return SYMBOL_LABELS.get(symbol, symbol)
class TroStyle(BaseModel):
"""
Darstellung einer TRO-Typgruppe.
@@ -371,8 +421,12 @@ class TroDefinition(BaseModel):
return self.style.group
def get_dot_attrs(self) -> dict[str, str]:
"""Graphviz-Knotenattribute dieses Typs."""
return self.style.dot_attrs()
"""Graphviz-Knotenattribute dieses Typs: Fuell-/Randfarbe der Farbgruppe
plus die typ-eigene Form (siehe TroSymbol/dot_shape_attrs) - Farbe
gruppiert verwandte Typen, Form unterscheidet den einzelnen Typ."""
attrs = self.style.dot_attrs()
attrs.update(dot_shape_attrs(self.symbol))
return attrs
# -- set ---------------------------------------------------------------
#
@@ -432,6 +486,10 @@ class TroDefinition(BaseModel):
return "-"
return ", ".join(f"{self.items[i]}x {i}" for i in self.get_item_names())
def describe_symbol(self) -> str:
"""Symbol als Klartext, z. B. 'Dreieck (Spitze oben)'."""
return symbol_label(self.symbol)
# ---------------------------------------------------------------------------
# Statische Typdefinition