Kreisel-Separatorliste (list_trackids) im CSV-Export ergaenzt
Kreisel bekommen wie VF_n/GF_n ein Merkmal mit der Reihenfolge aller Separator-/BTMT-Beladung-/BTMT-Entladung-TeileIds entlang der Bahn, sortiert nach Winkel um die Kreiselachse (Start bei 0 Grad in Drehrichtung DREHRICHTUNG) - nutzt dieselbe Umlauf-Logik, die bisher nur die "Nachbarn"-Spalte gespeist hat. Merkmal-Schluessel einheitlich auf "list_trackids" umbenannt (vorher "Separatorlist" bei VF/GF). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
+70
-14
@@ -130,6 +130,7 @@ from export_neighbors import (
|
||||
SENSOR_TEILEARTEN,
|
||||
WEICHE_TEILEART,
|
||||
GF_VF_TEILEARTEN,
|
||||
KREISEL_UMLAUF_TEILEARTEN,
|
||||
)
|
||||
|
||||
BLOCKPATTERNS = load_patterns()
|
||||
@@ -234,7 +235,7 @@ def build_variofoerderer_merkmale(block):
|
||||
export_raw.json-Dateien (z.B. tests/reference/export_raw.json) und noch
|
||||
nicht neu aufgebaute Bloecke in der Zeichnung weiterhin Werte liefern.
|
||||
|
||||
Das Merkmal "Separatorlist" (Reihenfolge der Separator-TeileIds entlang
|
||||
Das Merkmal "list_trackids" (Reihenfolge der Separator-TeileIds entlang
|
||||
der Strecke) steht hier NICHT drin - es kommt erst nach der sepliste-
|
||||
Aufloesung dazu (siehe write_separatorliste_merkmale in process_blocks),
|
||||
weil an dieser Stelle die x/y-Koordinaten aus der sepliste-XDATA noch
|
||||
@@ -778,15 +779,17 @@ def resolve_umlauf_und_sepliste_nachbarn(items, kreisel_umlauf, sep_kette,
|
||||
"""
|
||||
# Gemeinsamer Lookup fuer BEIDE Schluesselarten, die in kreisel_umlauf und
|
||||
# sep_kette als punkt_key/vorgaenger/nachfolger auftreten koennen: freie
|
||||
# Separatoren (TeileId), Kreisel-Kreisel-Weichen (weiche_by_key) UND
|
||||
# sepliste-Zeilen (sep_kette_by_key, Schluessel "<strecke_id>#<lfdnr>").
|
||||
# Ein Umlauf-Punkt kann naemlich ein AS/ES-Ende sein (sep_kette-Schluessel)
|
||||
# und ein sep_kette-Vorgaenger/Nachfolger kann das freie Kreiselende gar
|
||||
# nicht sein (das loest ausschliesslich compute_kreisel_umlauf auf) - erst
|
||||
# der gemeinsame Lookup deckt alle Kombinationen ab.
|
||||
separator_by_id = {it.get("teileid", ""): it for it in items
|
||||
if it.get("teileart", "") == "ILS 2.0 Separator"}
|
||||
alle_schluessel = {**sep_kette_by_key, **weiche_by_key, **separator_by_id}
|
||||
# Punkte (Separator/BTMT Beladung/BTMT Entladung, TeileId - siehe
|
||||
# KREISEL_UMLAUF_TEILEARTEN), Kreisel-Kreisel-Weichen
|
||||
# (weiche_by_key) UND sepliste-Zeilen (sep_kette_by_key, Schluessel
|
||||
# "<strecke_id>#<lfdnr>"). Ein Umlauf-Punkt kann naemlich ein AS/ES-Ende
|
||||
# sein (sep_kette-Schluessel) und ein sep_kette-Vorgaenger/Nachfolger kann
|
||||
# das freie Kreiselende gar nicht sein (das loest ausschliesslich
|
||||
# compute_kreisel_umlauf auf) - erst der gemeinsame Lookup deckt alle
|
||||
# Kombinationen ab.
|
||||
freipunkt_by_id = {it.get("teileid", ""): it for it in items
|
||||
if it.get("teileart", "") in KREISEL_UMLAUF_TEILEARTEN}
|
||||
alle_schluessel = {**sep_kette_by_key, **weiche_by_key, **freipunkt_by_id}
|
||||
|
||||
# Freie Separatoren, Weichen UND die AS/ES-Enden andockender Ketten
|
||||
# bekommen ihre "Nachbarn"-Spalte aus dem Kreisel-Umlauf.
|
||||
@@ -827,7 +830,7 @@ def resolve_umlauf_und_sepliste_nachbarn(items, kreisel_umlauf, sep_kette,
|
||||
|
||||
def write_separatorliste_merkmale(items, sep_kette_by_key, dbg=None):
|
||||
"""Traegt in jede Strecke (VF_n/GF_n mit "sepliste") das Merkmal
|
||||
"Separatorlist" ein: die TeileIds ihrer Separatoren in Baureihenfolge,
|
||||
"list_trackids" ein: die TeileIds ihrer Separatoren in Baureihenfolge,
|
||||
kommagetrennt (analog zu "Zuordnung"/"Nachbarn"), z.B. "0052, 0053, 0054".
|
||||
|
||||
Quelle ist die rohe "sepliste" des Items (AS/SEP/ES mit x/y, bereits in
|
||||
@@ -857,12 +860,57 @@ def write_separatorliste_merkmale(items, sep_kette_by_key, dbg=None):
|
||||
sep_item = sep_kette_by_key.get(key)
|
||||
if sep_item is None:
|
||||
if dbg:
|
||||
dbg(f" Separatorlist {key}: kein aufgeloestes Separator-Item "
|
||||
dbg(f" list_trackids {key}: kein aufgeloestes Separator-Item "
|
||||
f"- uebersprungen")
|
||||
continue
|
||||
separator_ids.append(sep_item.get("teileid", ""))
|
||||
if separator_ids:
|
||||
item["merkmale"]["Separatorlist"] = ", ".join(separator_ids)
|
||||
item["merkmale"]["list_trackids"] = ", ".join(separator_ids)
|
||||
|
||||
|
||||
def write_kreisel_separatorliste_merkmale(items, kreisel_umlauf, sep_kette_by_key,
|
||||
weiche_by_key, dbg=None):
|
||||
"""Traegt in jeden Kreisel ("ILS 2.0 Kreisel") das Merkmal "list_trackids"
|
||||
ein (gleicher Schluessel wie bei VF_n/GF_n, siehe write_separatorliste_
|
||||
merkmale): die TeileIds aller auf ihm liegenden freien Punkte (Separator,
|
||||
BTMT Beladung/Entladung - siehe KREISEL_UMLAUF_TEILEARTEN),
|
||||
andockenden AS/ES-Streckenenden und Kreisel-Kreisel-Weichen, in
|
||||
Umlaufreihenfolge ab Winkel 0 Grad (siehe compute_kreisel_umlauf - die
|
||||
Liste beginnt dort bereits bei 0 Grad in Drehrichtung DREHRICHTUNG),
|
||||
kommagetrennt.
|
||||
|
||||
Quelle ist kreisel_umlauf (export_neighbors.compute_kreisel_umlauf), das
|
||||
fuer jeden Kreisel bereits alle Punkte (freie Punkte, AS/ES-Enden,
|
||||
Kreisel-Kreisel-Weichen) nach Winkel um die Kreiselachse sortiert hat -
|
||||
hier werden nur noch deren rohe Schluessel (TeileId direkt, sep_kette-
|
||||
Schluessel oder Weichen-"key") auf die TeileId des jeweils zugehoerigen
|
||||
Items aufgeloest. Derselbe Lookup wie in
|
||||
resolve_umlauf_und_sepliste_nachbarn, daher muss diese Funktion NACH
|
||||
map_separator_kette_items/build_kreisel_weiche_items/
|
||||
build_strecke_schleus_items laufen (deren TeileIds stehen erst dann fest).
|
||||
"""
|
||||
freipunkt_by_id = {it.get("teileid", ""): it for it in items
|
||||
if it.get("teileart", "") in KREISEL_UMLAUF_TEILEARTEN}
|
||||
alle_schluessel = {**sep_kette_by_key, **weiche_by_key, **freipunkt_by_id}
|
||||
|
||||
kreisel_by_id = {it.get("teileid", ""): it for it in items
|
||||
if it.get("teileart", "") == "ILS 2.0 Kreisel"}
|
||||
|
||||
for tid, punkte in (kreisel_umlauf or {}).items():
|
||||
kreisel_item = kreisel_by_id.get(tid)
|
||||
if kreisel_item is None or not punkte:
|
||||
continue
|
||||
teileids = []
|
||||
for punkt_key, _vorgaenger, _nachfolger in punkte:
|
||||
item = alle_schluessel.get(punkt_key)
|
||||
if item is None:
|
||||
if dbg:
|
||||
dbg(f" list_trackids Kreisel {tid}: kein Item fuer "
|
||||
f"Umlauf-Punkt {punkt_key!r} - uebersprungen")
|
||||
continue
|
||||
teileids.append(item.get("teileid", ""))
|
||||
if teileids:
|
||||
kreisel_item["merkmale"]["list_trackids"] = ", ".join(teileids)
|
||||
|
||||
|
||||
def process_blocks(blocks, lookup, dbg=None):
|
||||
@@ -1262,13 +1310,21 @@ def process_blocks(blocks, lookup, dbg=None):
|
||||
map_separator_kette_items(
|
||||
items, sep_kette, sep_kette_by_key=sep_kette_by_key, dbg=dbg)
|
||||
|
||||
# Merkmal "Separatorlist" je Strecke (Reihenfolge der SEP-TeileIds aus der
|
||||
# Merkmal "list_trackids" je Strecke (Reihenfolge der SEP-TeileIds aus der
|
||||
# sepliste, x/y bereits oben auf das reale Separator-Item aufgeloest).
|
||||
write_separatorliste_merkmale(items, sep_kette_by_key, dbg=dbg)
|
||||
|
||||
resolve_umlauf_und_sepliste_nachbarn(
|
||||
items, kreisel_umlauf, sep_kette, sep_kette_by_key, weiche_by_key)
|
||||
|
||||
# Merkmal "list_trackids" je Kreisel: dieselben Umlauf-Punkte (freie
|
||||
# Separatoren, AS/ES-Enden, Kreisel-Kreisel-Weichen), die oben schon die
|
||||
# "Nachbarn"-Spalte gespeist haben, jetzt als eine einzige, bei 0 Grad
|
||||
# beginnende Reihenfolge auf den Kreisel selbst geschrieben (analog zu
|
||||
# write_separatorliste_merkmale bei VF_n/GF_n).
|
||||
write_kreisel_separatorliste_merkmale(
|
||||
items, kreisel_umlauf, sep_kette_by_key, weiche_by_key, dbg=dbg)
|
||||
|
||||
# Nach dem Sammelheimen aller Zeilen: sortiert nach TeileId ausgeben, damit
|
||||
# Elementnummer (erste Spalte) und TeileId nach Moeglichkeit uebereinstimmen
|
||||
# (siehe format_csv_line/Elementnummer-Neuvergabe unten). Numerische IDs
|
||||
|
||||
Reference in New Issue
Block a user