diff --git a/Lisp/KreiselInsert.lsp b/Lisp/KreiselInsert.lsp index d4dde50..ee48fd5 100644 --- a/Lisp/KreiselInsert.lsp +++ b/Lisp/KreiselInsert.lsp @@ -82,6 +82,7 @@ ("ABSTAND" "2300") ("NUMMER" "0") ("HOEHE" "0") + ("GERUEST_EINZELMODUL" "0") ("ID" "")) ) @@ -856,7 +857,7 @@ (defun c:KreiselEdit ( / sel ss ent ed attribs basePoint rotation dcl-pfad dat ergebnis dlg-name dlg-abstand dlg-hoehe dlg-ausrichtung - dlg-drehrichtung dlg-kreiselart + dlg-drehrichtung dlg-kreiselart dlg-geruest-einzelmodul newAbstand newRotation ausrichtLabels) ;; Implied Selection VOR ssg-start pruefen (ssg-start hebt Selektion auf) @@ -951,6 +952,9 @@ (end_list) (set_tile "kreiselart" (if (equal (cdr (assoc "KREISELART" attribs)) "PIN") "1" "0")) + (set_tile "geruest_einzelmodul" + (if (equal (cdr (assoc "GERUEST_EINZELMODUL" attribs)) "1") "1" "0")) + ;; Actions (action_tile "accept" (strcat @@ -960,6 +964,7 @@ "(setq dlg-ausrichtung (get_tile \"ausrichtung\"))" "(setq dlg-drehrichtung (get_tile \"drehrichtung\"))" "(setq dlg-kreiselart (get_tile \"kreiselart\"))" + "(setq dlg-geruest-einzelmodul (get_tile \"geruest_einzelmodul\"))" "(done_dialog 1)" ) ) @@ -986,6 +991,8 @@ (setq attribs (subst (cons "DREHRICHTUNG" (if (= dlg-drehrichtung "1") "GUZ" "UZS")) (assoc "DREHRICHTUNG" attribs) attribs)) + (setq attribs (subst (cons "GERUEST_EINZELMODUL" dlg-geruest-einzelmodul) + (assoc "GERUEST_EINZELMODUL" attribs) attribs)) ;; Alten Block loeschen (command "_.ERASE" ent "") diff --git a/dcl/kreisel_edit.dcl b/dcl/kreisel_edit.dcl index b715316..82801b7 100644 --- a/dcl/kreisel_edit.dcl +++ b/dcl/kreisel_edit.dcl @@ -47,6 +47,11 @@ kreisel_edit : dialog { } } + : toggle { + key = "geruest_einzelmodul"; + label = "Geruest fuer Einzelmodul"; + } + } ok_cancel; diff --git a/lib/export_csv.py b/lib/export_csv.py index 4865dce..d1a6b4c 100644 --- a/lib/export_csv.py +++ b/lib/export_csv.py @@ -215,6 +215,7 @@ def build_kreisel_merkmale(block): "Drehrichtung": attribs.get("DREHRICHTUNG", "UZS"), "Drehung": block.get("rotation", 0.0), "Name": attribs.get("Bezeichnung", ""), + "Geruest fuer Einzelmodul": attribs.get("GERUEST_EINZELMODUL", "0") == "1", } diff --git a/lib/export_sivas.py b/lib/export_sivas.py index c0a1739..8036362 100644 --- a/lib/export_sivas.py +++ b/lib/export_sivas.py @@ -4,16 +4,20 @@ export_sivas.py - Erzeugt Sivas-Export-CSV mit gruppierten Zeilen und Summierungszeilen. Neues CSV-Format: - Nr;TeileArt;SivasNummer;Bezeichnung;Dispogruppe;Anzahl;Laenge[mm];Hoehe[m];details + Nr;TeileArt;SivasNummer;Bezeichnung;Dispogruppe;Anzahl;Laenge[mm];Hoehe[m];IDs;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. + - IDs: kommaseparierte Liste der ID-Attribute aller Bloecke der Zeile + (eigene Spalte, nicht mehr Teil des details-JSON). + - Omniflo Bogen/Weiche: gruppiert nach SivasNummer, Anzahl summiert - Omniflo Gerade: gruppiert nach ARTINR-Attribut, Laenge[mm] summiert - - ILS 2.0 Kreisel: je Kreisel eine Zeile, details = JSON mit Parametern + - ILS 2.0 Kreisel: gruppiert nach Kreiselart+Abstand+Anzahl Separatoren/ + Scanner/Rampen, Anzahl summiert - ILS 2.0 Automation: Summierungszeile (nur wenn ILS-Elemente vorhanden) Aufruf: @@ -119,7 +123,6 @@ def build_gefaellestrecke_details(block): return "0" return { - "IDs": [get_id(block)], "Bezeichnung": attribs.get("Bezeichnung", block.get("block_name", "")), "Hoehe oben": mm_to_m("HOEHE_VON_mm"), "Hoehe unten": mm_to_m("HOEHE_BIS_mm"), @@ -131,6 +134,23 @@ def build_gefaellestrecke_details(block): } +def kreisel_signature(block): + """ + Schluessel zur Gruppierung gleichartiger Kreisel: Kreiselart, Abstand, + Anzahl der Separatoren, Anzahl der Scanner und Anzahl der Rampen + entscheiden, ob Kreisel in derselben Sivas-Zeile summiert werden. + """ + attribs = block.get("attribs", {}) + return ( + attribs.get("KREISELART", "STANDARD"), + attribs.get("ABSTAND", "2300"), + attribs.get("ANZAHL_SEPARATOR", attribs.get("N_SEPARATOREN", "2")), + attribs.get("ANZAHL_SCANNER", attribs.get("N_SCANNER", "0")), + attribs.get("N_RAMPEN", "0"), + attribs.get("GERUEST_EINZELMODUL", "0"), + ) + + def gefaellestrecke_signature(block): """ Schluessel zur Gruppierung gleichartiger Gefaellestrecken: Bloecke mit @@ -182,7 +202,6 @@ def build_variofoerderer_details(block): return 0 return { - "IDs": [get_id(block)], "Anzahl Foerdergruppen": to_int("ANZAHL_VF"), "Anzahl Gefaellegruppen": to_int("ANZAHL_GF"), "Hoehe in m": attribs.get("MONTAGEHOEHE_m", "0"), @@ -235,8 +254,7 @@ def build_kreisel_details(block): "Anzahl der Separatoren": attribs.get("ANZAHL_SEPARATOR", attribs.get("N_SEPARATOREN", "2")), "Anzahl der Scanner": attribs.get("ANZAHL_SCANNER", attribs.get("N_SCANNER", "0")), "Anzahl der Rampen": attribs.get("N_RAMPEN", "0"), - "Drehrichtung": attribs.get("DREHRICHTUNG", "UZS"), - "Drehung": block.get("rotation", 0.0), + "Geruest fuer Einzelmodul": attribs.get("GERUEST_EINZELMODUL", "0") == "1", } @@ -468,7 +486,8 @@ def process_blocks(blocks, lookup): "anzahl": g["anzahl"], "laenge_mm": "", "hoehe_m": format_hoehe_m(g["hoehe_mm"]), - "details": {"IDs": g["ids"]}, + "ids": g["ids"], + "details": {}, }) nr += 1 @@ -483,7 +502,8 @@ def process_blocks(blocks, lookup): "anzahl": g["anzahl"], "laenge_mm": "", "hoehe_m": format_hoehe_m(g["hoehe_mm"]), - "details": {"IDs": g["ids"]}, + "ids": g["ids"], + "details": {}, }) nr += 1 @@ -498,25 +518,36 @@ def process_blocks(blocks, lookup): "anzahl": g["anzahl"], "laenge_mm": int(g["laenge_mm"]), "hoehe_m": format_hoehe_m(g["hoehe_mm"]), - "details": {"IDs": g["ids"]}, + "ids": g["ids"], + "details": {}, }) nr += 1 + # Gleichartige Kreisel (gleiche Kreiselart und gleicher Abstand) zu einer + # Zeile zusammenfassen - nur IDs/Bezeichnung bleiben je Block unterschiedlich. + kreisel_groups = {} for block in kreisel_list: + sig = kreisel_signature(block) + if sig not in kreisel_groups: + kreisel_groups[sig] = {"ids": [], "bezeichnungen": [], "block": block} + kreisel_groups[sig]["ids"].append(get_id(block)) + kreisel_groups[sig]["bezeichnungen"].append( + block.get("attribs", {}).get("Bezeichnung", "")) + + for group in kreisel_groups.values(): sivasnr, teileart = ILS_SIVASNR["kreisel"] - details = build_kreisel_details(block) - details["ID"] = get_id(block) items.append({ "nr": nr, "teileart": teileart, "sivasnr": sivasnr, "sivasnr_quoted": True, - "bezeichnung": block.get("attribs", {}).get("Bezeichnung", ""), + "bezeichnung": ", ".join(b for b in group["bezeichnungen"] if b), "dispgruppe": 20, - "anzahl": 1, + "anzahl": len(group["ids"]), "laenge_mm": "", "hoehe_m": "", - "details": details, + "ids": group["ids"], + "details": build_kreisel_details(group["block"]), }) nr += 1 @@ -532,7 +563,8 @@ def process_blocks(blocks, lookup): "anzahl": counters["anzahl_eckraeder"], "laenge_mm": "", "hoehe_m": "", - "details": {"IDs": eckrad_ids}, + "ids": eckrad_ids, + "details": {}, }) nr += 1 @@ -551,7 +583,8 @@ def process_blocks(blocks, lookup): "anzahl": len(strecke_ids), "laenge_mm": "", "hoehe_m": "", - "details": {"IDs": strecke_ids}, + "ids": strecke_ids, + "details": {}, }) nr += 1 @@ -569,6 +602,7 @@ def process_blocks(blocks, lookup): "anzahl": 1, "laenge_mm": "", "hoehe_m": "", + "ids": [get_id(block)], "details": build_variofoerderer_details(block), }) nr += 1 @@ -587,7 +621,6 @@ def process_blocks(blocks, lookup): for group in gefaelle_groups.values(): sivasnr, teileart = ILS_SIVASNR["gefaellestrecke"] details = build_gefaellestrecke_details(group["block"]) - details["IDs"] = group["ids"] details["Bezeichnung"] = group["bezeichnungen"] items.append({ "nr": nr, @@ -599,6 +632,7 @@ def process_blocks(blocks, lookup): "anzahl": len(group["ids"]), "laenge_mm": "", "hoehe_m": "", + "ids": group["ids"], "details": details, }) nr += 1 @@ -652,6 +686,7 @@ def format_csv_line(item): """Formatiert eine CSV-Zeile im neuen Sivas-Format.""" details_json = json.dumps(item["details"], ensure_ascii=False) sivasnr = f'"{item["sivasnr"]}"' if item["sivasnr_quoted"] else item["sivasnr"] + ids_str = ", ".join(str(i) for i in item.get("ids", []) if i) return ( f'{item["nr"]}' f';"{item["teileart"]}"' @@ -661,6 +696,7 @@ def format_csv_line(item): f';{item["anzahl"]}' f';{item["laenge_mm"]}' f';{item["hoehe_m"]}' + f';"{ids_str}"' f';{details_json}' ) @@ -688,7 +724,7 @@ def main(): items, _ = process_blocks(blocks, lookup) - header = "Nr;TeileArt;SivasNummer;Bezeichnung;Dispogruppe;Anzahl;Laenge[mm];Hoehe[m];details" + header = "Nr;TeileArt;SivasNummer;Bezeichnung;Dispogruppe;Anzahl;Laenge[mm];Hoehe[m];IDs;details" with open(output_csv, "w", encoding="utf-8") as f: f.write(header + "\n") for item in items: