Bezeichnung statt Name bei ILS KReisel und Eckrad verwendet. Eigene Spalte für Bezeichnung im Sivas Export dazu gebaut

This commit is contained in:
2026-07-20 16:46:16 +02:00
parent d4ea049918
commit 903e086e7f
5 changed files with 43 additions and 24 deletions
+8 -8
View File
@@ -72,7 +72,7 @@
;; Attribut-Definitionen: ((TAG DEFAULT) ...) ;; Attribut-Definitionen: ((TAG DEFAULT) ...)
(setq *kreisel-attrib-defs* (setq *kreisel-attrib-defs*
'(("NAME" "") '(("Bezeichnung" "")
("DREHRICHTUNG" "UZS") ("DREHRICHTUNG" "UZS")
("ANZAHL_SEPARATOR" "2") ("ANZAHL_SEPARATOR" "2")
("KREISELART" "STANDARD") ("KREISELART" "STANDARD")
@@ -90,7 +90,7 @@
;; Eckrad Attribut-Definitionen: ((TAG DEFAULT) ...) ;; Eckrad Attribut-Definitionen: ((TAG DEFAULT) ...)
(setq *eckrad-attrib-defs* (setq *eckrad-attrib-defs*
'(("NAME" "") '(("Bezeichnung" "")
("DREHRICHTUNG" "UZS") ("DREHRICHTUNG" "UZS")
("DREHUNG" "0") ("DREHUNG" "0")
("NUMMER" "0") ("NUMMER" "0")
@@ -325,9 +325,9 @@
) )
) )
;; NAME automatisch setzen: "KreiselN" ;; Bezeichnung automatisch setzen: "KreiselN"
(setq attribs (subst (cons "NAME" (strcat "Kreisel" (itoa kreisel-nummer))) (setq attribs (subst (cons "Bezeichnung" (strcat "Kreisel" (itoa kreisel-nummer)))
(assoc "NAME" attribs) attribs)) (assoc "Bezeichnung" attribs) attribs))
;; --- HÖHE BESTIMMEN --- ;; --- HÖHE BESTIMMEN ---
;; Priorität 1: Aus basePoint (wenn 3D Punkt mit Z > 0) ;; Priorität 1: Aus basePoint (wenn 3D Punkt mit Z > 0)
@@ -928,7 +928,7 @@
) )
;; Tiles initialisieren ;; Tiles initialisieren
(set_tile "name" (cdr (assoc "NAME" attribs))) (set_tile "name" (cdr (assoc "Bezeichnung" attribs)))
(set_tile "abstand" (cdr (assoc "ABSTAND" attribs))) (set_tile "abstand" (cdr (assoc "ABSTAND" attribs)))
(set_tile "hoehe" (cdr (assoc "HOEHE" attribs))) (set_tile "hoehe" (cdr (assoc "HOEHE" attribs)))
@@ -976,8 +976,8 @@
(setq newRotation (kreisel-idx-to-rotation (atoi dlg-ausrichtung))) (setq newRotation (kreisel-idx-to-rotation (atoi dlg-ausrichtung)))
;; Attribute aktualisieren ;; Attribute aktualisieren
(setq attribs (subst (cons "NAME" dlg-name) (setq attribs (subst (cons "Bezeichnung" dlg-name)
(assoc "NAME" attribs) attribs)) (assoc "Bezeichnung" attribs) attribs))
(setq attribs (subst (cons "HOEHE" dlg-hoehe) (setq attribs (subst (cons "HOEHE" dlg-hoehe)
(assoc "HOEHE" attribs) attribs)) (assoc "HOEHE" attribs) attribs))
(setq attribs (subst (cons "KREISELART" (setq attribs (subst (cons "KREISELART"
+1 -1
View File
@@ -214,7 +214,7 @@ def build_kreisel_merkmale(block):
"Höhe in m": hoehe_m, "Höhe in m": hoehe_m,
"Drehrichtung": attribs.get("DREHRICHTUNG", "UZS"), "Drehrichtung": attribs.get("DREHRICHTUNG", "UZS"),
"Drehung": block.get("rotation", 0.0), "Drehung": block.get("rotation", 0.0),
"Name": attribs.get("NAME", ""), "Name": attribs.get("Bezeichnung", ""),
} }
+21 -2
View File
@@ -4,7 +4,12 @@
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;Dispogruppe;Anzahl;Laenge[mm];Hoehe[m];details Nr;TeileArt;SivasNummer;Bezeichnung;Dispogruppe;Anzahl;Laenge[mm];Hoehe[m];details
- Bezeichnung: Wert des Attributs "Bezeichnung" (Kreisel/Eckrad/VF/GF/Strecke).
Bei gruppierten Zeilen (mehrere Bloecke je Zeile) kommasepariert.
Bei Omniflo-Zeilen (Bogen/Weiche/Gerade) und der Automation-Summenzeile
bleibt das Feld leer, da es sich um Sammlungen gleichartiger Objekte handelt.
- Omniflo Bogen/Weiche: gruppiert nach SivasNummer, Anzahl summiert - Omniflo Bogen/Weiche: gruppiert nach SivasNummer, Anzahl summiert
- Omniflo Gerade: gruppiert nach ARTINR-Attribut, Laenge[mm] summiert - Omniflo Gerade: gruppiert nach ARTINR-Attribut, Laenge[mm] summiert
@@ -271,7 +276,9 @@ def process_blocks(blocks, lookup):
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
eckrad_bezeichnungen = [] # Bezeichnung-Attribut aller Eckrad-Bloecke
strecke_ids = [] # IDs loser Strecke-Elemente (Vario/Staustrecke ausserhalb VF_N) strecke_ids = [] # IDs loser Strecke-Elemente (Vario/Staustrecke ausserhalb VF_N)
strecke_bezeichnungen = [] # Bezeichnung-Attribut loser Strecke-Elemente
vario_list = [] # Liste von VarioFoerderer-Compound-Bloecken (VF_N), je einer Zeile vario_list = [] # Liste von VarioFoerderer-Compound-Bloecken (VF_N), je einer Zeile
gefaelle_list = [] # Liste von Gefaellestrecke-Bloecken (GF_*), je einer Zeile gefaelle_list = [] # Liste von Gefaellestrecke-Bloecken (GF_*), je einer Zeile
@@ -372,6 +379,7 @@ def process_blocks(blocks, lookup):
if matches_any(bname, BLOCKPATTERNS.get("pattern_eckrad", [])): if matches_any(bname, BLOCKPATTERNS.get("pattern_eckrad", [])):
counters["anzahl_eckraeder"] += 1 counters["anzahl_eckraeder"] += 1
eckrad_ids.append(get_id(block)) eckrad_ids.append(get_id(block))
eckrad_bezeichnungen.append(block.get("attribs", {}).get("Bezeichnung", ""))
continue continue
# --- ILS Kreisel --- # --- ILS Kreisel ---
@@ -443,6 +451,7 @@ def process_blocks(blocks, lookup):
if matches_any(bname, BLOCKPATTERNS.get("pattern_strecke_module", [])): if matches_any(bname, BLOCKPATTERNS.get("pattern_strecke_module", [])):
counters["anzahl_variofoerderer"] += 1 counters["anzahl_variofoerderer"] += 1
strecke_ids.append(get_id(block)) strecke_ids.append(get_id(block))
strecke_bezeichnungen.append(block.get("attribs", {}).get("Bezeichnung", ""))
# --- Zeilen aufbauen --- # --- Zeilen aufbauen ---
items = [] items = []
@@ -454,6 +463,7 @@ def process_blocks(blocks, lookup):
"teileart": "Omniflo Bogen", "teileart": "Omniflo Bogen",
"sivasnr": sivasnr, "sivasnr": sivasnr,
"sivasnr_quoted": False, "sivasnr_quoted": False,
"bezeichnung": "",
"dispgruppe": 10, "dispgruppe": 10,
"anzahl": g["anzahl"], "anzahl": g["anzahl"],
"laenge_mm": "", "laenge_mm": "",
@@ -468,6 +478,7 @@ def process_blocks(blocks, lookup):
"teileart": "Omniflo Weiche", "teileart": "Omniflo Weiche",
"sivasnr": sivasnr, "sivasnr": sivasnr,
"sivasnr_quoted": False, "sivasnr_quoted": False,
"bezeichnung": "",
"dispgruppe": 10, "dispgruppe": 10,
"anzahl": g["anzahl"], "anzahl": g["anzahl"],
"laenge_mm": "", "laenge_mm": "",
@@ -482,6 +493,7 @@ def process_blocks(blocks, lookup):
"teileart": "Omniflo Gerade", "teileart": "Omniflo Gerade",
"sivasnr": g["artinr"], "sivasnr": g["artinr"],
"sivasnr_quoted": True, "sivasnr_quoted": True,
"bezeichnung": "",
"dispgruppe": 10, "dispgruppe": 10,
"anzahl": g["anzahl"], "anzahl": g["anzahl"],
"laenge_mm": int(g["laenge_mm"]), "laenge_mm": int(g["laenge_mm"]),
@@ -499,6 +511,7 @@ def process_blocks(blocks, lookup):
"teileart": teileart, "teileart": teileart,
"sivasnr": sivasnr, "sivasnr": sivasnr,
"sivasnr_quoted": True, "sivasnr_quoted": True,
"bezeichnung": block.get("attribs", {}).get("Bezeichnung", ""),
"dispgruppe": 20, "dispgruppe": 20,
"anzahl": 1, "anzahl": 1,
"laenge_mm": "", "laenge_mm": "",
@@ -514,6 +527,7 @@ def process_blocks(blocks, lookup):
"teileart": teileart, "teileart": teileart,
"sivasnr": sivasnr, "sivasnr": sivasnr,
"sivasnr_quoted": True, "sivasnr_quoted": True,
"bezeichnung": ", ".join(b for b in eckrad_bezeichnungen if b),
"dispgruppe": 20, "dispgruppe": 20,
"anzahl": counters["anzahl_eckraeder"], "anzahl": counters["anzahl_eckraeder"],
"laenge_mm": "", "laenge_mm": "",
@@ -532,6 +546,7 @@ def process_blocks(blocks, lookup):
"teileart": teileart, "teileart": teileart,
"sivasnr": sivasnr, "sivasnr": sivasnr,
"sivasnr_quoted": True, "sivasnr_quoted": True,
"bezeichnung": ", ".join(b for b in strecke_bezeichnungen if b),
"dispgruppe": 20, "dispgruppe": 20,
"anzahl": len(strecke_ids), "anzahl": len(strecke_ids),
"laenge_mm": "", "laenge_mm": "",
@@ -549,6 +564,7 @@ def process_blocks(blocks, lookup):
"teileart": teileart, "teileart": teileart,
"sivasnr": sivasnr, "sivasnr": sivasnr,
"sivasnr_quoted": True, "sivasnr_quoted": True,
"bezeichnung": block.get("attribs", {}).get("Bezeichnung", ""),
"dispgruppe": 20, "dispgruppe": 20,
"anzahl": 1, "anzahl": 1,
"laenge_mm": "", "laenge_mm": "",
@@ -578,6 +594,7 @@ def process_blocks(blocks, lookup):
"teileart": teileart, "teileart": teileart,
"sivasnr": sivasnr, "sivasnr": sivasnr,
"sivasnr_quoted": True, "sivasnr_quoted": True,
"bezeichnung": ", ".join(b for b in group["bezeichnungen"] if b),
"dispgruppe": 20, "dispgruppe": 20,
"anzahl": len(group["ids"]), "anzahl": len(group["ids"]),
"laenge_mm": "", "laenge_mm": "",
@@ -620,6 +637,7 @@ def process_blocks(blocks, lookup):
"teileart": auto_teileart, "teileart": auto_teileart,
"sivasnr": auto_sivasnr, "sivasnr": auto_sivasnr,
"sivasnr_quoted": True, "sivasnr_quoted": True,
"bezeichnung": "",
"dispgruppe": 20, "dispgruppe": 20,
"anzahl": 1, "anzahl": 1,
"laenge_mm": "", "laenge_mm": "",
@@ -638,6 +656,7 @@ def format_csv_line(item):
f'{item["nr"]}' f'{item["nr"]}'
f';"{item["teileart"]}"' f';"{item["teileart"]}"'
f';{sivasnr}' f';{sivasnr}'
f';"{item["bezeichnung"]}"'
f';{item["dispgruppe"]}' f';{item["dispgruppe"]}'
f';{item["anzahl"]}' f';{item["anzahl"]}'
f';{item["laenge_mm"]}' f';{item["laenge_mm"]}'
@@ -669,7 +688,7 @@ def main():
items, _ = process_blocks(blocks, lookup) items, _ = process_blocks(blocks, lookup)
header = "Nr;TeileArt;SivasNummer;Dispogruppe;Anzahl;Laenge[mm];Hoehe[m];details" header = "Nr;TeileArt;SivasNummer;Bezeichnung;Dispogruppe;Anzahl;Laenge[mm];Hoehe[m];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:
+8 -8
View File
@@ -6,7 +6,7 @@
"block_handle": "11A", "block_handle": "11A",
"insert_point": [500, 500, 2500], "insert_point": [500, 500, 2500],
"actual_attributes": { "actual_attributes": {
"NAME": "Kreisel1", "Bezeichnung": "Kreisel1",
"DREHRICHTUNG": "UZS", "DREHRICHTUNG": "UZS",
"N_SEPARATOREN": "2", "N_SEPARATOREN": "2",
"KREISELART": "STANDARD", "KREISELART": "STANDARD",
@@ -27,7 +27,7 @@
"block_handle": "14A", "block_handle": "14A",
"insert_point": [-500, 500, 2500], "insert_point": [-500, 500, 2500],
"actual_attributes": { "actual_attributes": {
"NAME": "Kreisel2", "Bezeichnung": "Kreisel2",
"DREHRICHTUNG": "UZS", "DREHRICHTUNG": "UZS",
"N_SEPARATOREN": "2", "N_SEPARATOREN": "2",
"KREISELART": "STANDARD", "KREISELART": "STANDARD",
@@ -48,7 +48,7 @@
"block_handle": "17A", "block_handle": "17A",
"insert_point": [-500, -500, 2500], "insert_point": [-500, -500, 2500],
"actual_attributes": { "actual_attributes": {
"NAME": "Kreisel3", "Bezeichnung": "Kreisel3",
"DREHRICHTUNG": "UZS", "DREHRICHTUNG": "UZS",
"N_SEPARATOREN": "2", "N_SEPARATOREN": "2",
"KREISELART": "STANDARD", "KREISELART": "STANDARD",
@@ -69,7 +69,7 @@
"block_handle": "1AA", "block_handle": "1AA",
"insert_point": [500, -500, 2500], "insert_point": [500, -500, 2500],
"actual_attributes": { "actual_attributes": {
"NAME": "Kreisel4", "Bezeichnung": "Kreisel4",
"DREHRICHTUNG": "UZS", "DREHRICHTUNG": "UZS",
"N_SEPARATOREN": "2", "N_SEPARATOREN": "2",
"KREISELART": "STANDARD", "KREISELART": "STANDARD",
@@ -90,7 +90,7 @@
"block_handle": "1DA", "block_handle": "1DA",
"insert_point": [3000, 3000, 3000], "insert_point": [3000, 3000, 3000],
"actual_attributes": { "actual_attributes": {
"NAME": "Kreisel5", "Bezeichnung": "Kreisel5",
"DREHRICHTUNG": "UZS", "DREHRICHTUNG": "UZS",
"N_SEPARATOREN": "2", "N_SEPARATOREN": "2",
"KREISELART": "STANDARD", "KREISELART": "STANDARD",
@@ -111,7 +111,7 @@
"block_handle": "20F", "block_handle": "20F",
"insert_point": [500, 6000, 1500], "insert_point": [500, 6000, 1500],
"actual_attributes": { "actual_attributes": {
"NAME": "Kreisel6", "Bezeichnung": "Kreisel6",
"DREHRICHTUNG": "UZS", "DREHRICHTUNG": "UZS",
"N_SEPARATOREN": "2", "N_SEPARATOREN": "2",
"KREISELART": "PIN", "KREISELART": "PIN",
@@ -132,7 +132,7 @@
"block_handle": "243", "block_handle": "243",
"insert_point": [-500, 6500, 1500], "insert_point": [-500, 6500, 1500],
"actual_attributes": { "actual_attributes": {
"NAME": "Kreisel7", "Bezeichnung": "Kreisel7",
"DREHRICHTUNG": "UZS", "DREHRICHTUNG": "UZS",
"N_SEPARATOREN": "2", "N_SEPARATOREN": "2",
"KREISELART": "PIN", "KREISELART": "PIN",
@@ -153,7 +153,7 @@
"block_handle": "277", "block_handle": "277",
"insert_point": [3000, 8000, 1500], "insert_point": [3000, 8000, 1500],
"actual_attributes": { "actual_attributes": {
"NAME": "Kreisel8", "Bezeichnung": "Kreisel8",
"DREHRICHTUNG": "UZS", "DREHRICHTUNG": "UZS",
"N_SEPARATOREN": "2", "N_SEPARATOREN": "2",
"KREISELART": "PIN", "KREISELART": "PIN",
+5 -5
View File
@@ -289,7 +289,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", expected = ["Nr", "TeileArt", "SivasNummer", "Bezeichnung",
"Dispogruppe", "Anzahl", "Laenge[mm]", "Hoehe[m]", "details"] "Dispogruppe", "Anzahl", "Laenge[mm]", "Hoehe[m]", "details"]
for i, name in enumerate(expected): for i, name in enumerate(expected):
assert self.header[i] == name, ( assert self.header[i] == name, (
@@ -317,10 +317,10 @@ class TestFoerdererExportSivas:
def test_details_sind_valides_json(self): def test_details_sind_valides_json(self):
"""details-Spalte muss valides JSON enthalten.""" """details-Spalte muss valides JSON enthalten."""
for i, row in enumerate(self.rows): for i, row in enumerate(self.rows):
if len(row) < 8: if len(row) < 9:
continue continue
try: try:
json.loads(row[7]) json.loads(row[8])
except json.JSONDecodeError as e: except json.JSONDecodeError as e:
pytest.fail(f"Zeile {i + 2}: details ist kein valides JSON: {e}") pytest.fail(f"Zeile {i + 2}: details ist kein valides JSON: {e}")
@@ -330,10 +330,10 @@ class TestFoerdererExportSivas:
"Laengen aller Variofoerderer", "Laengen aller Variofoerderer",
"Anzahl aller Separatoren"} "Anzahl aller Separatoren"}
for row in self.rows: for row in self.rows:
if len(row) < 8: if len(row) < 9:
continue continue
if row[1].strip('"') == "ILS 2.0 Automation und Pneumatik - Gesamtanlage": if row[1].strip('"') == "ILS 2.0 Automation und Pneumatik - Gesamtanlage":
details = json.loads(row[7]) details = json.loads(row[8])
missing = required - set(details.keys()) missing = required - set(details.keys())
assert not missing, ( assert not missing, (
f"Automation-details: fehlende Felder: {missing}" f"Automation-details: fehlende Felder: {missing}"