Kreisel: Attribut Geruest_Einzelmodul hinzugefuegt (Erzeugung, Edit-Dialog, Export)

Jeder Kreisel bekommt bei der Erzeugung das neue Attribut GERUEST_EINZELMODUL
(Default false), im KreiselEdit-Dialog per Checkbox "Geruest fuer Einzelmodul"
umschaltbar. Fliesst als echter JSON-Bool ins details-Feld von EXPORTSIVAS/
EXPORTCSV und wird bei der Sivas-Gruppierung gleichartiger Kreisel beruecksichtigt.
This commit is contained in:
2026-07-22 11:25:09 +02:00
parent 12fc783eb7
commit 3f916a6fed
4 changed files with 68 additions and 19 deletions
+8 -1
View File
@@ -82,6 +82,7 @@
("ABSTAND" "2300") ("ABSTAND" "2300")
("NUMMER" "0") ("NUMMER" "0")
("HOEHE" "0") ("HOEHE" "0")
("GERUEST_EINZELMODUL" "0")
("ID" "")) ("ID" ""))
) )
@@ -856,7 +857,7 @@
(defun c:KreiselEdit ( / sel ss ent ed attribs basePoint rotation (defun c:KreiselEdit ( / sel ss ent ed attribs basePoint rotation
dcl-pfad dat ergebnis dcl-pfad dat ergebnis
dlg-name dlg-abstand dlg-hoehe dlg-ausrichtung dlg-name dlg-abstand dlg-hoehe dlg-ausrichtung
dlg-drehrichtung dlg-kreiselart dlg-drehrichtung dlg-kreiselart dlg-geruest-einzelmodul
newAbstand newRotation ausrichtLabels) newAbstand newRotation ausrichtLabels)
;; Implied Selection VOR ssg-start pruefen (ssg-start hebt Selektion auf) ;; Implied Selection VOR ssg-start pruefen (ssg-start hebt Selektion auf)
@@ -951,6 +952,9 @@
(end_list) (end_list)
(set_tile "kreiselart" (if (equal (cdr (assoc "KREISELART" attribs)) "PIN") "1" "0")) (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 ;; Actions
(action_tile "accept" (action_tile "accept"
(strcat (strcat
@@ -960,6 +964,7 @@
"(setq dlg-ausrichtung (get_tile \"ausrichtung\"))" "(setq dlg-ausrichtung (get_tile \"ausrichtung\"))"
"(setq dlg-drehrichtung (get_tile \"drehrichtung\"))" "(setq dlg-drehrichtung (get_tile \"drehrichtung\"))"
"(setq dlg-kreiselart (get_tile \"kreiselart\"))" "(setq dlg-kreiselart (get_tile \"kreiselart\"))"
"(setq dlg-geruest-einzelmodul (get_tile \"geruest_einzelmodul\"))"
"(done_dialog 1)" "(done_dialog 1)"
) )
) )
@@ -986,6 +991,8 @@
(setq attribs (subst (cons "DREHRICHTUNG" (setq attribs (subst (cons "DREHRICHTUNG"
(if (= dlg-drehrichtung "1") "GUZ" "UZS")) (if (= dlg-drehrichtung "1") "GUZ" "UZS"))
(assoc "DREHRICHTUNG" attribs) attribs)) (assoc "DREHRICHTUNG" attribs) attribs))
(setq attribs (subst (cons "GERUEST_EINZELMODUL" dlg-geruest-einzelmodul)
(assoc "GERUEST_EINZELMODUL" attribs) attribs))
;; Alten Block loeschen ;; Alten Block loeschen
(command "_.ERASE" ent "") (command "_.ERASE" ent "")
+5
View File
@@ -47,6 +47,11 @@ kreisel_edit : dialog {
} }
} }
: toggle {
key = "geruest_einzelmodul";
label = "Geruest fuer Einzelmodul";
}
} }
ok_cancel; ok_cancel;
+1
View File
@@ -215,6 +215,7 @@ def build_kreisel_merkmale(block):
"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("Bezeichnung", ""), "Name": attribs.get("Bezeichnung", ""),
"Geruest fuer Einzelmodul": attribs.get("GERUEST_EINZELMODUL", "0") == "1",
} }
+54 -18
View File
@@ -4,16 +4,20 @@
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];details Nr;TeileArt;SivasNummer;Bezeichnung;Dispogruppe;Anzahl;Laenge[mm];Hoehe[m];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.
Bei Omniflo-Zeilen (Bogen/Weiche/Gerade) und der Automation-Summenzeile Bei Omniflo-Zeilen (Bogen/Weiche/Gerade) und der Automation-Summenzeile
bleibt das Feld leer, da es sich um Sammlungen gleichartiger Objekte handelt. 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 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
- 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) - ILS 2.0 Automation: Summierungszeile (nur wenn ILS-Elemente vorhanden)
Aufruf: Aufruf:
@@ -119,7 +123,6 @@ def build_gefaellestrecke_details(block):
return "0" return "0"
return { return {
"IDs": [get_id(block)],
"Bezeichnung": attribs.get("Bezeichnung", block.get("block_name", "")), "Bezeichnung": attribs.get("Bezeichnung", block.get("block_name", "")),
"Hoehe oben": mm_to_m("HOEHE_VON_mm"), "Hoehe oben": mm_to_m("HOEHE_VON_mm"),
"Hoehe unten": mm_to_m("HOEHE_BIS_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): def gefaellestrecke_signature(block):
""" """
Schluessel zur Gruppierung gleichartiger Gefaellestrecken: Bloecke mit Schluessel zur Gruppierung gleichartiger Gefaellestrecken: Bloecke mit
@@ -182,7 +202,6 @@ def build_variofoerderer_details(block):
return 0 return 0
return { return {
"IDs": [get_id(block)],
"Anzahl Foerdergruppen": to_int("ANZAHL_VF"), "Anzahl Foerdergruppen": to_int("ANZAHL_VF"),
"Anzahl Gefaellegruppen": to_int("ANZAHL_GF"), "Anzahl Gefaellegruppen": to_int("ANZAHL_GF"),
"Hoehe in m": attribs.get("MONTAGEHOEHE_m", "0"), "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 Separatoren": attribs.get("ANZAHL_SEPARATOR", attribs.get("N_SEPARATOREN", "2")),
"Anzahl der Scanner": attribs.get("ANZAHL_SCANNER", attribs.get("N_SCANNER", "0")), "Anzahl der Scanner": attribs.get("ANZAHL_SCANNER", attribs.get("N_SCANNER", "0")),
"Anzahl der Rampen": attribs.get("N_RAMPEN", "0"), "Anzahl der Rampen": attribs.get("N_RAMPEN", "0"),
"Drehrichtung": attribs.get("DREHRICHTUNG", "UZS"), "Geruest fuer Einzelmodul": attribs.get("GERUEST_EINZELMODUL", "0") == "1",
"Drehung": block.get("rotation", 0.0),
} }
@@ -468,7 +486,8 @@ def process_blocks(blocks, lookup):
"anzahl": g["anzahl"], "anzahl": g["anzahl"],
"laenge_mm": "", "laenge_mm": "",
"hoehe_m": format_hoehe_m(g["hoehe_mm"]), "hoehe_m": format_hoehe_m(g["hoehe_mm"]),
"details": {"IDs": g["ids"]}, "ids": g["ids"],
"details": {},
}) })
nr += 1 nr += 1
@@ -483,7 +502,8 @@ def process_blocks(blocks, lookup):
"anzahl": g["anzahl"], "anzahl": g["anzahl"],
"laenge_mm": "", "laenge_mm": "",
"hoehe_m": format_hoehe_m(g["hoehe_mm"]), "hoehe_m": format_hoehe_m(g["hoehe_mm"]),
"details": {"IDs": g["ids"]}, "ids": g["ids"],
"details": {},
}) })
nr += 1 nr += 1
@@ -498,25 +518,36 @@ def process_blocks(blocks, lookup):
"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"]), "hoehe_m": format_hoehe_m(g["hoehe_mm"]),
"details": {"IDs": g["ids"]}, "ids": g["ids"],
"details": {},
}) })
nr += 1 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: 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"] sivasnr, teileart = ILS_SIVASNR["kreisel"]
details = build_kreisel_details(block)
details["ID"] = get_id(block)
items.append({ items.append({
"nr": nr, "nr": nr,
"teileart": teileart, "teileart": teileart,
"sivasnr": sivasnr, "sivasnr": sivasnr,
"sivasnr_quoted": True, "sivasnr_quoted": True,
"bezeichnung": block.get("attribs", {}).get("Bezeichnung", ""), "bezeichnung": ", ".join(b for b in group["bezeichnungen"] if b),
"dispgruppe": 20, "dispgruppe": 20,
"anzahl": 1, "anzahl": len(group["ids"]),
"laenge_mm": "", "laenge_mm": "",
"hoehe_m": "", "hoehe_m": "",
"details": details, "ids": group["ids"],
"details": build_kreisel_details(group["block"]),
}) })
nr += 1 nr += 1
@@ -532,7 +563,8 @@ def process_blocks(blocks, lookup):
"anzahl": counters["anzahl_eckraeder"], "anzahl": counters["anzahl_eckraeder"],
"laenge_mm": "", "laenge_mm": "",
"hoehe_m": "", "hoehe_m": "",
"details": {"IDs": eckrad_ids}, "ids": eckrad_ids,
"details": {},
}) })
nr += 1 nr += 1
@@ -551,7 +583,8 @@ def process_blocks(blocks, lookup):
"anzahl": len(strecke_ids), "anzahl": len(strecke_ids),
"laenge_mm": "", "laenge_mm": "",
"hoehe_m": "", "hoehe_m": "",
"details": {"IDs": strecke_ids}, "ids": strecke_ids,
"details": {},
}) })
nr += 1 nr += 1
@@ -569,6 +602,7 @@ def process_blocks(blocks, lookup):
"anzahl": 1, "anzahl": 1,
"laenge_mm": "", "laenge_mm": "",
"hoehe_m": "", "hoehe_m": "",
"ids": [get_id(block)],
"details": build_variofoerderer_details(block), "details": build_variofoerderer_details(block),
}) })
nr += 1 nr += 1
@@ -587,7 +621,6 @@ def process_blocks(blocks, lookup):
for group in gefaelle_groups.values(): for group in gefaelle_groups.values():
sivasnr, teileart = ILS_SIVASNR["gefaellestrecke"] sivasnr, teileart = ILS_SIVASNR["gefaellestrecke"]
details = build_gefaellestrecke_details(group["block"]) details = build_gefaellestrecke_details(group["block"])
details["IDs"] = group["ids"]
details["Bezeichnung"] = group["bezeichnungen"] details["Bezeichnung"] = group["bezeichnungen"]
items.append({ items.append({
"nr": nr, "nr": nr,
@@ -599,6 +632,7 @@ def process_blocks(blocks, lookup):
"anzahl": len(group["ids"]), "anzahl": len(group["ids"]),
"laenge_mm": "", "laenge_mm": "",
"hoehe_m": "", "hoehe_m": "",
"ids": group["ids"],
"details": details, "details": details,
}) })
nr += 1 nr += 1
@@ -652,6 +686,7 @@ def format_csv_line(item):
"""Formatiert eine CSV-Zeile im neuen Sivas-Format.""" """Formatiert eine CSV-Zeile im neuen Sivas-Format."""
details_json = json.dumps(item["details"], ensure_ascii=False) details_json = json.dumps(item["details"], ensure_ascii=False)
sivasnr = f'"{item["sivasnr"]}"' if item["sivasnr_quoted"] else item["sivasnr"] 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 ( return (
f'{item["nr"]}' f'{item["nr"]}'
f';"{item["teileart"]}"' f';"{item["teileart"]}"'
@@ -661,6 +696,7 @@ def format_csv_line(item):
f';{item["anzahl"]}' f';{item["anzahl"]}'
f';{item["laenge_mm"]}' f';{item["laenge_mm"]}'
f';{item["hoehe_m"]}' f';{item["hoehe_m"]}'
f';"{ids_str}"'
f';{details_json}' f';{details_json}'
) )
@@ -688,7 +724,7 @@ def main():
items, _ = process_blocks(blocks, lookup) 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: 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: