From 903e086e7f58b924fbdac8e30349ab3a20df57e0 Mon Sep 17 00:00:00 2001 From: Michael Stangl Date: Mon, 20 Jul 2026 16:46:16 +0200 Subject: [PATCH] =?UTF-8?q?Bezeichnung=20statt=20Name=20bei=20ILS=20KReise?= =?UTF-8?q?l=20und=20Eckrad=20verwendet.=20Eigene=20Spalte=20f=C3=BCr=20Be?= =?UTF-8?q?zeichnung=20im=20Sivas=20Export=20dazu=20gebaut?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Lisp/KreiselInsert.lsp | 16 ++++++++-------- lib/export_csv.py | 2 +- lib/export_sivas.py | 23 +++++++++++++++++++++-- tests/reference/kreisel_results.json | 16 ++++++++-------- tests/test_foerderer.py | 10 +++++----- 5 files changed, 43 insertions(+), 24 deletions(-) diff --git a/Lisp/KreiselInsert.lsp b/Lisp/KreiselInsert.lsp index cb8c6a3..d4dde50 100644 --- a/Lisp/KreiselInsert.lsp +++ b/Lisp/KreiselInsert.lsp @@ -72,7 +72,7 @@ ;; Attribut-Definitionen: ((TAG DEFAULT) ...) (setq *kreisel-attrib-defs* - '(("NAME" "") + '(("Bezeichnung" "") ("DREHRICHTUNG" "UZS") ("ANZAHL_SEPARATOR" "2") ("KREISELART" "STANDARD") @@ -90,7 +90,7 @@ ;; Eckrad Attribut-Definitionen: ((TAG DEFAULT) ...) (setq *eckrad-attrib-defs* - '(("NAME" "") + '(("Bezeichnung" "") ("DREHRICHTUNG" "UZS") ("DREHUNG" "0") ("NUMMER" "0") @@ -325,9 +325,9 @@ ) ) - ;; NAME automatisch setzen: "KreiselN" - (setq attribs (subst (cons "NAME" (strcat "Kreisel" (itoa kreisel-nummer))) - (assoc "NAME" attribs) attribs)) + ;; Bezeichnung automatisch setzen: "KreiselN" + (setq attribs (subst (cons "Bezeichnung" (strcat "Kreisel" (itoa kreisel-nummer))) + (assoc "Bezeichnung" attribs) attribs)) ;; --- HÖHE BESTIMMEN --- ;; Priorität 1: Aus basePoint (wenn 3D Punkt mit Z > 0) @@ -928,7 +928,7 @@ ) ;; 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 "hoehe" (cdr (assoc "HOEHE" attribs))) @@ -976,8 +976,8 @@ (setq newRotation (kreisel-idx-to-rotation (atoi dlg-ausrichtung))) ;; Attribute aktualisieren - (setq attribs (subst (cons "NAME" dlg-name) - (assoc "NAME" attribs) attribs)) + (setq attribs (subst (cons "Bezeichnung" dlg-name) + (assoc "Bezeichnung" attribs) attribs)) (setq attribs (subst (cons "HOEHE" dlg-hoehe) (assoc "HOEHE" attribs) attribs)) (setq attribs (subst (cons "KREISELART" diff --git a/lib/export_csv.py b/lib/export_csv.py index e416c54..4865dce 100644 --- a/lib/export_csv.py +++ b/lib/export_csv.py @@ -214,7 +214,7 @@ def build_kreisel_merkmale(block): "Höhe in m": hoehe_m, "Drehrichtung": attribs.get("DREHRICHTUNG", "UZS"), "Drehung": block.get("rotation", 0.0), - "Name": attribs.get("NAME", ""), + "Name": attribs.get("Bezeichnung", ""), } diff --git a/lib/export_sivas.py b/lib/export_sivas.py index 288fbc4..b01fefc 100644 --- a/lib/export_sivas.py +++ b/lib/export_sivas.py @@ -4,7 +4,12 @@ export_sivas.py - Erzeugt Sivas-Export-CSV mit gruppierten Zeilen und Summierungszeilen. 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 Gerade: gruppiert nach ARTINR-Attribut, Laenge[mm] summiert @@ -271,7 +276,9 @@ def process_blocks(blocks, lookup): gerade_groups = {} kreisel_list = [] # Liste von blocks 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_bezeichnungen = [] # Bezeichnung-Attribut loser Strecke-Elemente vario_list = [] # Liste von VarioFoerderer-Compound-Bloecken (VF_N), 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", [])): counters["anzahl_eckraeder"] += 1 eckrad_ids.append(get_id(block)) + eckrad_bezeichnungen.append(block.get("attribs", {}).get("Bezeichnung", "")) continue # --- ILS Kreisel --- @@ -443,6 +451,7 @@ def process_blocks(blocks, lookup): if matches_any(bname, BLOCKPATTERNS.get("pattern_strecke_module", [])): counters["anzahl_variofoerderer"] += 1 strecke_ids.append(get_id(block)) + strecke_bezeichnungen.append(block.get("attribs", {}).get("Bezeichnung", "")) # --- Zeilen aufbauen --- items = [] @@ -454,6 +463,7 @@ def process_blocks(blocks, lookup): "teileart": "Omniflo Bogen", "sivasnr": sivasnr, "sivasnr_quoted": False, + "bezeichnung": "", "dispgruppe": 10, "anzahl": g["anzahl"], "laenge_mm": "", @@ -468,6 +478,7 @@ def process_blocks(blocks, lookup): "teileart": "Omniflo Weiche", "sivasnr": sivasnr, "sivasnr_quoted": False, + "bezeichnung": "", "dispgruppe": 10, "anzahl": g["anzahl"], "laenge_mm": "", @@ -482,6 +493,7 @@ def process_blocks(blocks, lookup): "teileart": "Omniflo Gerade", "sivasnr": g["artinr"], "sivasnr_quoted": True, + "bezeichnung": "", "dispgruppe": 10, "anzahl": g["anzahl"], "laenge_mm": int(g["laenge_mm"]), @@ -499,6 +511,7 @@ def process_blocks(blocks, lookup): "teileart": teileart, "sivasnr": sivasnr, "sivasnr_quoted": True, + "bezeichnung": block.get("attribs", {}).get("Bezeichnung", ""), "dispgruppe": 20, "anzahl": 1, "laenge_mm": "", @@ -514,6 +527,7 @@ def process_blocks(blocks, lookup): "teileart": teileart, "sivasnr": sivasnr, "sivasnr_quoted": True, + "bezeichnung": ", ".join(b for b in eckrad_bezeichnungen if b), "dispgruppe": 20, "anzahl": counters["anzahl_eckraeder"], "laenge_mm": "", @@ -532,6 +546,7 @@ def process_blocks(blocks, lookup): "teileart": teileart, "sivasnr": sivasnr, "sivasnr_quoted": True, + "bezeichnung": ", ".join(b for b in strecke_bezeichnungen if b), "dispgruppe": 20, "anzahl": len(strecke_ids), "laenge_mm": "", @@ -549,6 +564,7 @@ def process_blocks(blocks, lookup): "teileart": teileart, "sivasnr": sivasnr, "sivasnr_quoted": True, + "bezeichnung": block.get("attribs", {}).get("Bezeichnung", ""), "dispgruppe": 20, "anzahl": 1, "laenge_mm": "", @@ -578,6 +594,7 @@ def process_blocks(blocks, lookup): "teileart": teileart, "sivasnr": sivasnr, "sivasnr_quoted": True, + "bezeichnung": ", ".join(b for b in group["bezeichnungen"] if b), "dispgruppe": 20, "anzahl": len(group["ids"]), "laenge_mm": "", @@ -620,6 +637,7 @@ def process_blocks(blocks, lookup): "teileart": auto_teileart, "sivasnr": auto_sivasnr, "sivasnr_quoted": True, + "bezeichnung": "", "dispgruppe": 20, "anzahl": 1, "laenge_mm": "", @@ -638,6 +656,7 @@ def format_csv_line(item): f'{item["nr"]}' f';"{item["teileart"]}"' f';{sivasnr}' + f';"{item["bezeichnung"]}"' f';{item["dispgruppe"]}' f';{item["anzahl"]}' f';{item["laenge_mm"]}' @@ -669,7 +688,7 @@ def main(): 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: f.write(header + "\n") for item in items: diff --git a/tests/reference/kreisel_results.json b/tests/reference/kreisel_results.json index 0b5ada1..e32a8c7 100644 --- a/tests/reference/kreisel_results.json +++ b/tests/reference/kreisel_results.json @@ -6,7 +6,7 @@ "block_handle": "11A", "insert_point": [500, 500, 2500], "actual_attributes": { - "NAME": "Kreisel1", + "Bezeichnung": "Kreisel1", "DREHRICHTUNG": "UZS", "N_SEPARATOREN": "2", "KREISELART": "STANDARD", @@ -27,7 +27,7 @@ "block_handle": "14A", "insert_point": [-500, 500, 2500], "actual_attributes": { - "NAME": "Kreisel2", + "Bezeichnung": "Kreisel2", "DREHRICHTUNG": "UZS", "N_SEPARATOREN": "2", "KREISELART": "STANDARD", @@ -48,7 +48,7 @@ "block_handle": "17A", "insert_point": [-500, -500, 2500], "actual_attributes": { - "NAME": "Kreisel3", + "Bezeichnung": "Kreisel3", "DREHRICHTUNG": "UZS", "N_SEPARATOREN": "2", "KREISELART": "STANDARD", @@ -69,7 +69,7 @@ "block_handle": "1AA", "insert_point": [500, -500, 2500], "actual_attributes": { - "NAME": "Kreisel4", + "Bezeichnung": "Kreisel4", "DREHRICHTUNG": "UZS", "N_SEPARATOREN": "2", "KREISELART": "STANDARD", @@ -90,7 +90,7 @@ "block_handle": "1DA", "insert_point": [3000, 3000, 3000], "actual_attributes": { - "NAME": "Kreisel5", + "Bezeichnung": "Kreisel5", "DREHRICHTUNG": "UZS", "N_SEPARATOREN": "2", "KREISELART": "STANDARD", @@ -111,7 +111,7 @@ "block_handle": "20F", "insert_point": [500, 6000, 1500], "actual_attributes": { - "NAME": "Kreisel6", + "Bezeichnung": "Kreisel6", "DREHRICHTUNG": "UZS", "N_SEPARATOREN": "2", "KREISELART": "PIN", @@ -132,7 +132,7 @@ "block_handle": "243", "insert_point": [-500, 6500, 1500], "actual_attributes": { - "NAME": "Kreisel7", + "Bezeichnung": "Kreisel7", "DREHRICHTUNG": "UZS", "N_SEPARATOREN": "2", "KREISELART": "PIN", @@ -153,7 +153,7 @@ "block_handle": "277", "insert_point": [3000, 8000, 1500], "actual_attributes": { - "NAME": "Kreisel8", + "Bezeichnung": "Kreisel8", "DREHRICHTUNG": "UZS", "N_SEPARATOREN": "2", "KREISELART": "PIN", diff --git a/tests/test_foerderer.py b/tests/test_foerderer.py index 29a28de..7515323 100644 --- a/tests/test_foerderer.py +++ b/tests/test_foerderer.py @@ -289,7 +289,7 @@ class TestFoerdererExportSivas: def test_header_felder(self): """Sivas-CSV-Header muss korrekte Spalten haben.""" - expected = ["Nr", "TeileArt", "SivasNummer", + expected = ["Nr", "TeileArt", "SivasNummer", "Bezeichnung", "Dispogruppe", "Anzahl", "Laenge[mm]", "Hoehe[m]", "details"] for i, name in enumerate(expected): assert self.header[i] == name, ( @@ -317,10 +317,10 @@ class TestFoerdererExportSivas: def test_details_sind_valides_json(self): """details-Spalte muss valides JSON enthalten.""" for i, row in enumerate(self.rows): - if len(row) < 8: + if len(row) < 9: continue try: - json.loads(row[7]) + json.loads(row[8]) except json.JSONDecodeError as e: pytest.fail(f"Zeile {i + 2}: details ist kein valides JSON: {e}") @@ -330,10 +330,10 @@ class TestFoerdererExportSivas: "Laengen aller Variofoerderer", "Anzahl aller Separatoren"} for row in self.rows: - if len(row) < 8: + if len(row) < 9: continue 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()) assert not missing, ( f"Automation-details: fehlende Felder: {missing}"