[FIX] export_sivas: TEF-Platzhalter (0_BG*) ueber SivasnrTEF in echte Einzelteile aufloesen

0_BG* im Sivasnr-Rohwert ist kein echter Sivas-Code, sondern ein Blockname-
Platzhalter fuer mehrere reale TEF-Teile (z.B. 0_BG071090 = 0_B10071 +
0_B10090 + 0_B10090, siehe SivasnrTEF im Katalog). Bisher wurde der
Platzhalter selbst als Sivasnummer gezaehlt, wodurch u.a. 0_B10071 in der
Summierung fehlte.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-30 14:29:00 +02:00
parent 85438a9ee8
commit 71f52ca3d6
+44 -2
View File
@@ -163,6 +163,42 @@ def gefaellestrecke_signature(block):
) )
def expand_tef_components(sivasnr_parts, sivasnr_tef):
"""Ersetzt "0_BG*"-Platzhalter-Teile in sivasnr_parts durch die dahinter
liegenden echten TEF-Sivasnummern (Katalogfeld SivasnrTEF).
"0_BG*"-Werte im Sivasnr-Rohwert (z.B. "834372404+0_BG071090") sind KEINE
echten Sivasnummern, sondern reine Blocknamen-Platzhalter fuer eine TEF-
Baugruppe aus mehreren realen Teilen - "0_BG071090" steht z.B. fuer die
drei echten Teile "0_B10071"+"0_B10090"+"0_B10090" (siehe SivasnrTEF im
Katalog, omniflo_weichen.json/omniflo_boegen.json). Ohne diese Aufloesung
wuerde "0_BG071090" selbst als (nicht existente) Sivasnummer gezaehlt und
die echten Teile (u.a. 0_B10071) fehlten in der Summierung.
Reale TEF-Einzelteile, die bereits direkt im Sivasnr-Rohwert stehen
(Praefix "0_B", aber nicht "0_BG", z.B. "821104026+0_B10071"), sind schon
echte Sivasnummern und werden unveraendert uebernommen.
Bei mehreren "0_BG*"-Platzhaltern im selben Rohwert (TEF beidseitig) wird
SivasnrTEF zu gleichen Teilen aufgeteilt - der Katalog listet die Teile
je Seite hintereinander in SivasnrTEF.
"""
bg_count = sum(1 for p in sivasnr_parts if p.startswith("0_BG"))
if bg_count == 0:
return list(sivasnr_parts)
tef_parts = [p.strip() for p in str(sivasnr_tef or "").split("+") if p.strip()]
chunk_size = len(tef_parts) // bg_count if bg_count else 0
expanded = []
tef_index = 0
for part in sivasnr_parts:
if part.startswith("0_BG"):
expanded.extend(tef_parts[tef_index:tef_index + chunk_size])
tef_index += chunk_size
else:
expanded.append(part)
return expanded
def parse_float_list(csv_str): def parse_float_list(csv_str):
"""Kommagetrennten Attribut-String (z.B. L_GF_m) in Liste von floats.""" """Kommagetrennten Attribut-String (z.B. L_GF_m) in Liste von floats."""
out = [] out = []
@@ -356,7 +392,10 @@ def process_blocks(blocks, lookup):
if typ == "bogen": if typ == "bogen":
if has_tef and len(sivasnr_parts) > 1: if has_tef and len(sivasnr_parts) > 1:
# Multi-Komponenten: jede Komponente separat gruppieren # Multi-Komponenten: jede Komponente separat gruppieren
for i, comp_sivasnr in enumerate(sivasnr_parts): # ("0_BG*"-Platzhalter werden ueber SivasnrTEF in ihre
# echten Einzelteile aufgeloest, siehe expand_tef_components)
expanded_parts = expand_tef_components(sivasnr_parts, eintrag.get("SivasnrTEF"))
for i, comp_sivasnr in enumerate(expanded_parts):
comp_id = f"{block_id}.t{i+1}" comp_id = f"{block_id}.t{i+1}"
if comp_sivasnr not in bogen_groups: if comp_sivasnr not in bogen_groups:
bogen_groups[comp_sivasnr] = {"anzahl": 0, "ids": []} bogen_groups[comp_sivasnr] = {"anzahl": 0, "ids": []}
@@ -375,7 +414,10 @@ def process_blocks(blocks, lookup):
subtyp = classify_weiche(eintrag) subtyp = classify_weiche(eintrag)
if has_tef and len(sivasnr_parts) > 1: if has_tef and len(sivasnr_parts) > 1:
# Multi-Komponenten: jede Komponente separat gruppieren # Multi-Komponenten: jede Komponente separat gruppieren
for i, comp_sivasnr in enumerate(sivasnr_parts): # ("0_BG*"-Platzhalter werden ueber SivasnrTEF in ihre
# echten Einzelteile aufgeloest, siehe expand_tef_components)
expanded_parts = expand_tef_components(sivasnr_parts, eintrag.get("SivasnrTEF"))
for i, comp_sivasnr in enumerate(expanded_parts):
comp_id = f"{block_id}.t{i+1}" comp_id = f"{block_id}.t{i+1}"
if comp_sivasnr.startswith("0_B"): if comp_sivasnr.startswith("0_B"):
# TEF-Komponente (Bogen) in bogen_groups # TEF-Komponente (Bogen) in bogen_groups