Sivas-Export: Spalte Hoehe[m] entfernt

Die Hoehe-Angabe steht bereits pro Element in der details-JSON-Spalte
(z.B. "Hoehe in m" aus dem MONTAGEHOEHE_m-Attribut bei VarioFoerderer/
Linienzug), die separate Top-Level-Spalte war redundant.
This commit is contained in:
2026-07-22 13:01:24 +02:00
parent 193b0dea04
commit 57badf0556
2 changed files with 8 additions and 38 deletions
+7 -37
View File
@@ -4,7 +4,7 @@
export_sivas.py - Erzeugt Sivas-Export-CSV mit gruppierten Zeilen und Summierungszeilen. export_sivas.py - Erzeugt Sivas-Export-CSV mit gruppierten Zeilen und Summierungszeilen.
Neues CSV-Format: Neues CSV-Format:
Nr;TeileArt;SivasNummer;Bezeichnung;Dispogruppe;Anzahl;Laenge[mm];Hoehe[m];IDs;details Nr;TeileArt;SivasNummer;Bezeichnung;Dispogruppe;Anzahl;Laenge[mm];IDs;details
- Bezeichnung: Wert des Attributs "Bezeichnung" (Kreisel/Eckrad/VF/GF/Strecke). - Bezeichnung: Wert des Attributs "Bezeichnung" (Kreisel/Eckrad/VF/GF/Strecke).
Bei gruppierten Zeilen (mehrere Bloecke je Zeile) kommasepariert. Bei gruppierten Zeilen (mehrere Bloecke je Zeile) kommasepariert.
@@ -80,13 +80,6 @@ def classify_weiche(eintrag):
return "einzelweiche" return "einzelweiche"
def get_hoehe_mm(block):
"""Liest HOEHE aus Block-Attributen. Fallback: Z-Koordinate."""
attribs = block.get("attribs", {})
v = attribs.get("HOEHE") or str(int(block.get("z", 0) or 0)) or "2000"
return v
def get_id(block): def get_id(block):
"""Liest das eindeutige ID-Attribut eines Blocks (von ssg-id-check-all vergeben).""" """Liest das eindeutige ID-Attribut eines Blocks (von ssg-id-check-all vergeben)."""
return block.get("attribs", {}).get("ID", "") return block.get("attribs", {}).get("ID", "")
@@ -101,17 +94,6 @@ def format_sivasnr(sivasnr):
return ", ".join(p.strip() for p in str(sivasnr).split("+") if p.strip()) return ", ".join(p.strip() for p in str(sivasnr).split("+") if p.strip())
def format_hoehe_m(hoehe_mm_str):
"""Konvertiert mm-String nach m mit deutschem Dezimaltrennzeichen."""
try:
m = float(hoehe_mm_str) / 1000.0
if m == int(m):
return str(int(m))
return f"{m:.1f}".replace(".", ",")
except (ValueError, TypeError):
return ""
def build_gefaellestrecke_details(block): def build_gefaellestrecke_details(block):
"""Merkmale-Dict fuer eine einzelne ILS Gefaellestrecke (GF_N-Block).""" """Merkmale-Dict fuer eine einzelne ILS Gefaellestrecke (GF_N-Block)."""
attribs = block.get("attribs", {}) attribs = block.get("attribs", {})
@@ -286,10 +268,10 @@ def process_blocks(blocks, lookup):
items - Liste der CSV-Zeilen als Dicts items - Liste der CSV-Zeilen als Dicts
counters - Zaehler fuer ILS-Automation-Summierungszeile counters - Zaehler fuer ILS-Automation-Summierungszeile
""" """
# Gruppen: sivasnr_str -> {anzahl, hoehe_mm, ids} # Gruppen: sivasnr_str -> {anzahl, ids}
bogen_groups = {} # sivasnr -> dict bogen_groups = {} # sivasnr -> dict
weiche_groups = {} # sivasnr -> dict weiche_groups = {} # sivasnr -> dict
# Gerade: artinr_str -> {anzahl, laenge_mm_total, hoehe_mm, ids} # Gerade: artinr_str -> {anzahl, laenge_mm_total, ids}
gerade_groups = {} gerade_groups = {}
kreisel_list = [] # Liste von blocks kreisel_list = [] # Liste von blocks
eckrad_ids = [] # IDs aller Eckrad-Bloecke eckrad_ids = [] # IDs aller Eckrad-Bloecke
@@ -340,18 +322,17 @@ def process_blocks(blocks, lookup):
if bname in lookup: if bname in lookup:
typ, eintrag = lookup[bname] typ, eintrag = lookup[bname]
sivasnr = format_sivasnr(eintrag.get("Sivasnr", bname)) sivasnr = format_sivasnr(eintrag.get("Sivasnr", bname))
hoehe = get_hoehe_mm(block)
if typ == "bogen": if typ == "bogen":
if sivasnr not in bogen_groups: if sivasnr not in bogen_groups:
bogen_groups[sivasnr] = {"anzahl": 0, "hoehe_mm": hoehe, "ids": []} bogen_groups[sivasnr] = {"anzahl": 0, "ids": []}
bogen_groups[sivasnr]["anzahl"] += 1 bogen_groups[sivasnr]["anzahl"] += 1
bogen_groups[sivasnr]["ids"].append(get_id(block)) bogen_groups[sivasnr]["ids"].append(get_id(block))
counters["anzahl_boegen"] += 1 counters["anzahl_boegen"] += 1
elif typ == "weiche": elif typ == "weiche":
if sivasnr not in weiche_groups: if sivasnr not in weiche_groups:
weiche_groups[sivasnr] = {"anzahl": 0, "hoehe_mm": hoehe, "ids": []} weiche_groups[sivasnr] = {"anzahl": 0, "ids": []}
weiche_groups[sivasnr]["anzahl"] += 1 weiche_groups[sivasnr]["anzahl"] += 1
weiche_groups[sivasnr]["ids"].append(get_id(block)) weiche_groups[sivasnr]["ids"].append(get_id(block))
subtyp = classify_weiche(eintrag) subtyp = classify_weiche(eintrag)
@@ -372,7 +353,6 @@ def process_blocks(blocks, lookup):
attribs = block.get("attribs", {}) attribs = block.get("attribs", {})
artinr = attribs.get("ARTINR", "") artinr = attribs.get("ARTINR", "")
key = artinr if artinr else "AP110" key = artinr if artinr else "AP110"
hoehe = get_hoehe_mm(block)
laenge = 2000.0 laenge = 2000.0
laenge_attr = attribs.get("LAENGE") or attribs.get("A") laenge_attr = attribs.get("LAENGE") or attribs.get("A")
if laenge_attr: if laenge_attr:
@@ -382,7 +362,7 @@ def process_blocks(blocks, lookup):
pass pass
if key not in gerade_groups: if key not in gerade_groups:
gerade_groups[key] = { gerade_groups[key] = {
"anzahl": 0, "laenge_mm": 0.0, "hoehe_mm": hoehe, "anzahl": 0, "laenge_mm": 0.0,
"artinr": artinr, "ids": [], "artinr": artinr, "ids": [],
} }
gerade_groups[key]["anzahl"] += 1 gerade_groups[key]["anzahl"] += 1
@@ -484,7 +464,6 @@ def process_blocks(blocks, lookup):
"dispgruppe": 10, "dispgruppe": 10,
"anzahl": g["anzahl"], "anzahl": g["anzahl"],
"laenge_mm": "", "laenge_mm": "",
"hoehe_m": format_hoehe_m(g["hoehe_mm"]),
"ids": g["ids"], "ids": g["ids"],
"details": {}, "details": {},
}) })
@@ -500,7 +479,6 @@ def process_blocks(blocks, lookup):
"dispgruppe": 10, "dispgruppe": 10,
"anzahl": g["anzahl"], "anzahl": g["anzahl"],
"laenge_mm": "", "laenge_mm": "",
"hoehe_m": format_hoehe_m(g["hoehe_mm"]),
"ids": g["ids"], "ids": g["ids"],
"details": {}, "details": {},
}) })
@@ -516,7 +494,6 @@ def process_blocks(blocks, lookup):
"dispgruppe": 10, "dispgruppe": 10,
"anzahl": g["anzahl"], "anzahl": g["anzahl"],
"laenge_mm": int(g["laenge_mm"]), "laenge_mm": int(g["laenge_mm"]),
"hoehe_m": format_hoehe_m(g["hoehe_mm"]),
"ids": g["ids"], "ids": g["ids"],
"details": {}, "details": {},
}) })
@@ -544,7 +521,6 @@ def process_blocks(blocks, lookup):
"dispgruppe": 20, "dispgruppe": 20,
"anzahl": len(group["ids"]), "anzahl": len(group["ids"]),
"laenge_mm": "", "laenge_mm": "",
"hoehe_m": "",
"ids": group["ids"], "ids": group["ids"],
"details": build_kreisel_details(group["block"]), "details": build_kreisel_details(group["block"]),
}) })
@@ -561,7 +537,6 @@ def process_blocks(blocks, lookup):
"dispgruppe": 20, "dispgruppe": 20,
"anzahl": counters["anzahl_eckraeder"], "anzahl": counters["anzahl_eckraeder"],
"laenge_mm": "", "laenge_mm": "",
"hoehe_m": "",
"ids": eckrad_ids, "ids": eckrad_ids,
"details": {}, "details": {},
}) })
@@ -581,7 +556,6 @@ def process_blocks(blocks, lookup):
"dispgruppe": 20, "dispgruppe": 20,
"anzahl": len(strecke_ids), "anzahl": len(strecke_ids),
"laenge_mm": "", "laenge_mm": "",
"hoehe_m": "",
"ids": strecke_ids, "ids": strecke_ids,
"details": {}, "details": {},
}) })
@@ -600,7 +574,6 @@ def process_blocks(blocks, lookup):
"dispgruppe": 20, "dispgruppe": 20,
"anzahl": 1, "anzahl": 1,
"laenge_mm": "", "laenge_mm": "",
"hoehe_m": "",
"ids": [get_id(block)], "ids": [get_id(block)],
"details": build_variofoerderer_details(block), "details": build_variofoerderer_details(block),
}) })
@@ -629,7 +602,6 @@ def process_blocks(blocks, lookup):
"dispgruppe": 20, "dispgruppe": 20,
"anzahl": len(group["ids"]), "anzahl": len(group["ids"]),
"laenge_mm": "", "laenge_mm": "",
"hoehe_m": "",
"ids": group["ids"], "ids": group["ids"],
"details": details, "details": details,
}) })
@@ -673,7 +645,6 @@ def process_blocks(blocks, lookup):
"dispgruppe": 20, "dispgruppe": 20,
"anzahl": 1, "anzahl": 1,
"laenge_mm": "", "laenge_mm": "",
"hoehe_m": "",
"details": automation_details, "details": automation_details,
}) })
@@ -693,7 +664,6 @@ def format_csv_line(item):
f';{item["dispgruppe"]}' f';{item["dispgruppe"]}'
f';{item["anzahl"]}' f';{item["anzahl"]}'
f';{item["laenge_mm"]}' f';{item["laenge_mm"]}'
f';{item["hoehe_m"]}'
f';"{ids_str}"' f';"{ids_str}"'
f';{details_json}' f';{details_json}'
) )
@@ -722,7 +692,7 @@ def main():
items, _ = process_blocks(blocks, lookup) items, _ = process_blocks(blocks, lookup)
header = "Nr;TeileArt;SivasNummer;Bezeichnung;Dispogruppe;Anzahl;Laenge[mm];Hoehe[m];IDs;details" header = "Nr;TeileArt;SivasNummer;Bezeichnung;Dispogruppe;Anzahl;Laenge[mm];IDs;details"
with open(output_csv, "w", encoding="utf-8") as f: with open(output_csv, "w", encoding="utf-8") as f:
f.write(header + "\n") f.write(header + "\n")
for item in items: for item in items:
+1 -1
View File
@@ -290,7 +290,7 @@ class TestFoerdererExportSivas:
def test_header_felder(self): def test_header_felder(self):
"""Sivas-CSV-Header muss korrekte Spalten haben.""" """Sivas-CSV-Header muss korrekte Spalten haben."""
expected = ["Nr", "TeileArt", "SivasNummer", "Bezeichnung", expected = ["Nr", "TeileArt", "SivasNummer", "Bezeichnung",
"Dispogruppe", "Anzahl", "Laenge[mm]", "Hoehe[m]", "details"] "Dispogruppe", "Anzahl", "Laenge[mm]", "details"]
for i, name in enumerate(expected): for i, name in enumerate(expected):
assert self.header[i] == name, ( assert self.header[i] == name, (
f"Header[{i}]: erwartet '{name}', ist '{self.header[i]}'" f"Header[{i}]: erwartet '{name}', ist '{self.header[i]}'"