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:
+7
-37
@@ -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:
|
||||||
|
|||||||
@@ -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]}'"
|
||||||
|
|||||||
Reference in New Issue
Block a user