From 3c0900a02b388819251bc9b7b87e67ba3b630371 Mon Sep 17 00:00:00 2001 From: Michael Stangl Date: Thu, 10 Sep 2026 14:52:03 +0200 Subject: [PATCH] CSV-Bezeichnung von VF/GF/Kreisel/Eckrad nutzt Anwender-Attribut statt nur Nummerierung Die Spalte "Bezeichnung" verwendet jetzt das in BricsCAD frei editierbare Attribut "Bezeichnung" des Blocks, falls gesetzt - sonst wie bisher die generierte Standardbezeichnung ("VarioFoerderer :3" usw.). Damit laesst sich ein in der Zeichnung umbenanntes Element im CSV-Export wiedererkennen. Co-Authored-By: Claude Sonnet 5 --- doc/csv-export.md | 9 +++++++ lib/export_csv.py | 23 ++++++++++++++--- tests/test_export_bezeichnung.py | 42 ++++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+), 4 deletions(-) create mode 100644 tests/test_export_bezeichnung.py diff --git a/doc/csv-export.md b/doc/csv-export.md index 1f4c3ea..f335823 100644 --- a/doc/csv-export.md +++ b/doc/csv-export.md @@ -149,6 +149,15 @@ Item-dict mit `teileart`, `teileid`, `bezeichnung`, `planquadrat`, bekommen dabei zusaetzlich `x`/`y` (Kettenanfang, fuer die Schleuselement- Berechnung) und `sepliste` (fuer die Ketten-Nachbarschaft) durchgereicht. +Die `bezeichnung`-Spalte von VF_n/GF_n/Kreisel/Eckrad kommt ueber +`bezeichnung_oder_fallback` NICHT nur aus der Lauf-Nummerierung +("VarioFoerderer :3", "Kreisel :2" usw.), sondern zuerst aus dem +Attribut `"Bezeichnung"` des Blocks (ATTDEF, in BricsCAD frei editierbar - +bei Kreisel z.B. ueber das "name"-Dialogfeld). Ist es leer oder fehlt es +(Altbestand ohne das Attribut), bleibt es bei der generierten +Standardbezeichnung. Damit laesst sich ein in BricsCAD umbenanntes Element +im CSV-Export wiedererkennen. + Separator/Scanner-Items ohne Bounding-Box (weil `vla-getboundingbox` scheiterte) bekommen einen Fallback: `_fallback_separator_bbox` baut aus der festen Symbol-Groesse (`cfg/export.cfg [Boundingbox] separator_box_*`, diff --git a/lib/export_csv.py b/lib/export_csv.py index 46cde87..e0b939e 100644 --- a/lib/export_csv.py +++ b/lib/export_csv.py @@ -224,6 +224,21 @@ def build_weiche_merkmale(block, eintrag): } +def bezeichnung_oder_fallback(block, fallback): + """CSV-Spalte "Bezeichnung" fuer VF_N/GF_N/Kreisel/Eckrad: das vom + Anwender in BricsCAD frei editierbare Attribut "Bezeichnung" (ATTDEF, + siehe vf-bname/gf-bname bzw. KreiselInsert.lsp "name"-Dialogfeld), falls + vorhanden und nicht leer - sonst der generierte Standardname + ("VarioFoerderer :3", "Kreisel :2" usw.). + + Das Attribut wird beim Bau zunaechst mit dem Blocknamen (VF_n/GF_n) bzw. + "Kreisel" vorbelegt, kann danach aber umbenannt werden - damit laesst + sich ein Element in der Zeichnung und im CSV-Export leichter + wiedererkennen als ueber die reine Lauf-Nummerierung.""" + bez = (block.get("attribs", {}) or {}).get("Bezeichnung", "").strip() + return bez if bez else fallback + + def build_variofoerderer_merkmale(block): """Merkmale-Dict fuer einen VF_N- oder GF_N-Streckenblock. @@ -1015,7 +1030,7 @@ def process_blocks(blocks, lookup, dbg=None): "nr": elem_nr, "teileart": "ILS 2.0 Strecke", "teileid": block.get("attribs", {}).get("ID", "0000"), - "bezeichnung": f"VarioFoerderer :{vf_count}", + "bezeichnung": bezeichnung_oder_fallback(block, f"VarioFoerderer :{vf_count}"), "planquadrat": planquadrat_column(block, planquadrat_cfg), "merkmale": build_variofoerderer_merkmale(block), # x/y (Block-Einfuegepunkt = Kettenanfang) fuer die Anfang/Ende- @@ -1041,7 +1056,7 @@ def process_blocks(blocks, lookup, dbg=None): "nr": elem_nr, "teileart": "ILS 2.0 Gefaellestrecke", "teileid": block.get("attribs", {}).get("ID", "0000"), - "bezeichnung": f"Gefaellestrecke :{gf_count}", + "bezeichnung": bezeichnung_oder_fallback(block, f"Gefaellestrecke :{gf_count}"), "planquadrat": planquadrat_column(block, planquadrat_cfg), "merkmale": build_variofoerderer_merkmale(block), # x/y (Block-Einfuegepunkt = Kettenanfang) fuer die Anfang/Ende- @@ -1063,7 +1078,7 @@ def process_blocks(blocks, lookup, dbg=None): "nr": elem_nr, "teileart": "ILS 2.0 Eckrad", "teileid": block.get("attribs", {}).get("ID", "0000"), - "bezeichnung": f"Eckrad :{eckrad_count}", + "bezeichnung": bezeichnung_oder_fallback(block, f"Eckrad :{eckrad_count}"), "planquadrat": planquadrat_column(block, planquadrat_cfg), "merkmale": build_kreisel_merkmale(block), **bbox_columns(block), @@ -1078,7 +1093,7 @@ def process_blocks(blocks, lookup, dbg=None): "nr": elem_nr, "teileart": "ILS 2.0 Kreisel", "teileid": block.get("attribs", {}).get("ID", "0000"), - "bezeichnung": f"Kreisel :{kreisel_count}", + "bezeichnung": bezeichnung_oder_fallback(block, f"Kreisel :{kreisel_count}"), "planquadrat": planquadrat_column(block, planquadrat_cfg), "merkmale": build_kreisel_merkmale(block), # x/y/rotation/attribs (roh, nicht nur die Merkmale) werden diff --git a/tests/test_export_bezeichnung.py b/tests/test_export_bezeichnung.py new file mode 100644 index 0000000..0ef58a5 --- /dev/null +++ b/tests/test_export_bezeichnung.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +test_export_bezeichnung.py - CSV-Spalte "Bezeichnung" fuer VF_n/GF_n/ +Kreisel/Eckrad. Laeuft komplett ohne BricsCAD (reine Python-Logik). + +Kundenwunsch: die Bezeichnung soll nicht nur die generierte Lauf-Nummerierung +("VarioFoerderer :3") sein, sondern - falls in der Zeichnung vom Anwender +gesetzt - das frei editierbare Attribut "Bezeichnung" des Blocks (ATTDEF), +damit sich ein Element in BricsCAD und im CSV-Export leichter zuordnen laesst. +""" + +import os +import sys + +sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "lib")) + +from export_csv import bezeichnung_oder_fallback # noqa: E402 + + +class TestBezeichnungOderFallback: + + def test_eigene_bezeichnung_wird_uebernommen(self): + block = {"attribs": {"Bezeichnung": "Haupt-Gefaelle Halle 3"}} + assert bezeichnung_oder_fallback(block, "Gefaellestrecke :5") == \ + "Haupt-Gefaelle Halle 3" + + def test_leere_bezeichnung_faellt_auf_standardname_zurueck(self): + block = {"attribs": {"Bezeichnung": ""}} + assert bezeichnung_oder_fallback(block, "Gefaellestrecke :5") == "Gefaellestrecke :5" + + def test_leerzeichen_bezeichnung_faellt_auf_standardname_zurueck(self): + block = {"attribs": {"Bezeichnung": " "}} + assert bezeichnung_oder_fallback(block, "Kreisel :2") == "Kreisel :2" + + def test_fehlendes_attribut_faellt_auf_standardname_zurueck(self): + block = {"attribs": {}} + assert bezeichnung_oder_fallback(block, "VarioFoerderer :1") == "VarioFoerderer :1" + + def test_fehlende_attribs_faellt_auf_standardname_zurueck(self): + block = {} + assert bezeichnung_oder_fallback(block, "Eckrad :4") == "Eckrad :4"