Export: Gefällestrecke-Höhe, Gerüst-Defaults, Omniflo-Komponenten-Split

- Entfernt "Hoehe oben"/"Hoehe unten" aus Gefällestrecke JSON-Export
- "Hoehe in m" kommt jetzt konsistent aus MONTAGEHOEHE_m bei Kreisel/Variofoerderer/Gefällestrecke
- Setzt "Geruest fuer Einzelmodul" auf Default True (statt False) bei Kreisel, Eckrad, Variofoerderer, Gefällestrecke
  - Eckrad-Abfrage: Default = Yes, Logik korrigiert (war invertiert)
- JSON-Key-Reihenfolge optimiert:
  - Variofoerderer/ILS 2.0 Strecke: "Hoehe in m" zuerst
  - Gefällestrecke/ILS 2.0 Gefällestrecke: "Hoehe in m" und "Typ" zuerst
  - Kreisel: "Hoehe in m" zuerst
- Omniflo-Komponenten-Split: Teile mit "0_B"-Präfix werden als separate CSV-Zeilen ausgegeben
  - Multi-Komponenten-Sivasnr (z.B. "834372002+0_BG090090") splitten
  - IDs werden mit .t1, .t2, etc. ergänzt
  - 0_B-Komponenten als "TEF Bogen"/"TEF Weiche" klassifiziert

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-07-23 15:26:51 +02:00
parent 6b7f6e925d
commit 258608b77f
6 changed files with 60 additions and 30 deletions
+50 -20
View File
@@ -98,17 +98,13 @@ def build_gefaellestrecke_details(block):
"""Merkmale-Dict fuer eine einzelne ILS Gefaellestrecke (GF_N-Block)."""
attribs = block.get("attribs", {})
def mm_to_m(key):
return str(round(safe_float(attribs.get(key, "0")) / 1000.0, 2))
return {
"Hoehe oben": mm_to_m("HOEHE_VON_mm"),
"Hoehe unten": mm_to_m("HOEHE_BIS_mm"),
"Hoehe in m": attribs.get("MONTAGEHOEHE_m", "0"),
"Typ": attribs.get("TYP", "Gefaellestrecke"),
"Laenge in Meter": attribs.get("L_GF_m", ""),
"Winkel": attribs.get("GF_WINKEL", ""),
"Anzahl der Separatoren": attribs.get("ANZAHL_SEPARATOR", "0"),
"Anzahl der Scanner": attribs.get("ANZAHL_SCANNER", "0"),
"Typ": attribs.get("TYP", "Gefaellestrecke"),
"Geruest fuer Einzelmodul": attribs.get("GERUEST_EINZELMODUL", "0") == "1",
"Geruestoption fuer Einzelmodul": attribs.get("GERUEST_TYP", "Schoenenberger Geruest"),
}
@@ -197,9 +193,9 @@ def build_variofoerderer_details(block):
return safe_int(attribs.get(key, "0") or "0")
return {
"Hoehe in m": attribs.get("MONTAGEHOEHE_m", "0"),
"Anzahl Foerdergruppen": to_int("ANZAHL_VF"),
"Anzahl Gefaellegruppen": to_int("ANZAHL_GF"),
"Hoehe in m": attribs.get("MONTAGEHOEHE_m", "0"),
"GruppenteileGefaelle": {
"AnzahlGeraden": to_int("ANZAHL_GF"),
"Laenge in Meter": parse_float_list(attribs.get("L_GF_m", "")),
@@ -235,9 +231,8 @@ def build_kreisel_details(block):
"""Merkmale-Dict fuer einen ILS Kreisel."""
attribs = block.get("attribs", {})
abstand_m = str(round(safe_float(attribs.get("ABSTAND", "2300"), 2300.0) / 1000.0, 2))
hoehe_m = str(round(safe_float(attribs.get("HOEHE", "0"), 0.0) / 1000.0, 2))
return {
"Hoehe in m": hoehe_m,
"Hoehe in m": attribs.get("MONTAGEHOEHE_m", "0"),
"Kreiselart": attribs.get("KREISELART", "STANDARD"),
"Abstand (Kreiselachse A - Kreiselachse) in Meter": abstand_m,
"Anzahl der Separatoren": attribs.get("ANZAHL_SEPARATOR", attribs.get("N_SEPARATOREN", "2")),
@@ -338,21 +333,54 @@ def process_blocks(blocks, lookup):
# --- Omniflo Bogen oder Weiche (erkannt via Katalog) ---
if bname in lookup:
typ, eintrag = lookup[bname]
sivasnr = format_sivasnr(eintrag.get("Sivasnr", bname))
sivasnr_raw = eintrag.get("Sivasnr", bname)
sivasnr_parts = [p.strip() for p in str(sivasnr_raw).split("+")]
has_tef = any(p.startswith("0_B") for p in sivasnr_parts)
block_id = get_id(block)
if typ == "bogen":
if sivasnr not in bogen_groups:
bogen_groups[sivasnr] = {"anzahl": 0, "ids": []}
bogen_groups[sivasnr]["anzahl"] += 1
bogen_groups[sivasnr]["ids"].append(get_id(block))
if has_tef and len(sivasnr_parts) > 1:
# Multi-Komponenten: jede Komponente separat gruppieren
for i, comp_sivasnr in enumerate(sivasnr_parts):
comp_id = f"{block_id}.t{i+1}"
if comp_sivasnr not in bogen_groups:
bogen_groups[comp_sivasnr] = {"anzahl": 0, "ids": []}
bogen_groups[comp_sivasnr]["anzahl"] += 1
bogen_groups[comp_sivasnr]["ids"].append(comp_id)
else:
# Normal: alle als eine Komponente
sivasnr = format_sivasnr(sivasnr_raw)
if sivasnr not in bogen_groups:
bogen_groups[sivasnr] = {"anzahl": 0, "ids": []}
bogen_groups[sivasnr]["anzahl"] += 1
bogen_groups[sivasnr]["ids"].append(block_id)
counters["anzahl_boegen"] += 1
elif typ == "weiche":
if sivasnr not in weiche_groups:
weiche_groups[sivasnr] = {"anzahl": 0, "ids": []}
weiche_groups[sivasnr]["anzahl"] += 1
weiche_groups[sivasnr]["ids"].append(get_id(block))
subtyp = classify_weiche(eintrag)
if has_tef and len(sivasnr_parts) > 1:
# Multi-Komponenten: jede Komponente separat gruppieren
for i, comp_sivasnr in enumerate(sivasnr_parts):
comp_id = f"{block_id}.t{i+1}"
if comp_sivasnr.startswith("0_B"):
# TEF-Komponente (Bogen) in bogen_groups
if comp_sivasnr not in bogen_groups:
bogen_groups[comp_sivasnr] = {"anzahl": 0, "ids": []}
bogen_groups[comp_sivasnr]["anzahl"] += 1
bogen_groups[comp_sivasnr]["ids"].append(comp_id)
else:
# Weichen-Komponente in weiche_groups
if comp_sivasnr not in weiche_groups:
weiche_groups[comp_sivasnr] = {"anzahl": 0, "ids": []}
weiche_groups[comp_sivasnr]["anzahl"] += 1
weiche_groups[comp_sivasnr]["ids"].append(comp_id)
else:
# Normal: alle als eine Komponente
sivasnr = format_sivasnr(sivasnr_raw)
if sivasnr not in weiche_groups:
weiche_groups[sivasnr] = {"anzahl": 0, "ids": []}
weiche_groups[sivasnr]["anzahl"] += 1
weiche_groups[sivasnr]["ids"].append(block_id)
if subtyp == "einzelweiche":
counters["anzahl_einzelweichen"] += 1
elif subtyp in ("doppelweiche", "dreiwegeweiche"):
@@ -453,9 +481,10 @@ def process_blocks(blocks, lookup):
nr = 1
for sivasnr, g in bogen_groups.items():
teileart = "TEF Bogen" if str(sivasnr).startswith("0_B") else "Omniflo Bogen"
items.append({
"nr": nr,
"teileart": "Omniflo Bogen",
"teileart": teileart,
"sivasnr": sivasnr,
"sivasnr_quoted": False,
"bezeichnung": "",
@@ -468,9 +497,10 @@ def process_blocks(blocks, lookup):
nr += 1
for sivasnr, g in weiche_groups.items():
teileart = "TEF Weiche" if str(sivasnr).startswith("0_B") else "Omniflo Weiche"
items.append({
"nr": nr,
"teileart": "Omniflo Weiche",
"teileart": teileart,
"sivasnr": sivasnr,
"sivasnr_quoted": False,
"bezeichnung": "",