diff --git a/lib/export_sivas.py b/lib/export_sivas.py index 2157b96..9a45aa3 100644 --- a/lib/export_sivas.py +++ b/lib/export_sivas.py @@ -4,7 +4,7 @@ export_sivas.py - Erzeugt Sivas-Export-CSV mit gruppierten Zeilen und Summierungszeilen. Neues CSV-Format: - Nr;TeileArt;SivasNummer;Dispgruppe;Anzahl;Laenge[mm];Hoehe[m];details + Nr;TeileArt;SivasNummer;Dispogruppe;Anzahl;Laenge[mm];Hoehe[m];details - Omniflo Bogen/Weiche: gruppiert nach SivasNummer, Anzahl summiert - Omniflo Gerade: gruppiert nach ARTINR-Attribut, Laenge[mm] summiert @@ -492,7 +492,7 @@ def main(): items, _ = process_blocks(blocks, lookup) - header = "Nr;TeileArt;SivasNummer;Dispgruppe;Anzahl;Laenge[mm];Hoehe[m];details" + header = "Nr;TeileArt;SivasNummer;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/lib/set_attributs.py b/lib/set_attributs.py index e638502..5c45080 100644 --- a/lib/set_attributs.py +++ b/lib/set_attributs.py @@ -39,13 +39,14 @@ Umgebungsvariablen: DXFM_RESULTS - Pfad zum results/-Verzeichnis Aufruf: - python lib/set_attributs.py [--number SIVASNR] [--dry-run] + python lib/set_attributs.py [--number SIVASNR] [--dry-run] [--type 2D|3D] """ import argparse import configparser import json import os +import re import sys import ezdxf @@ -64,6 +65,7 @@ def load_config(cfg_path): "bogen": [("BESCHR", "ProfilTyp"), ("ARTINR", "Sivasnr"), ...], "weiche": [("BESCHR", "ProfilTyp"), ...], "layer": {"bogen": "OF Boegen A-2", "weiche_90": "Weiche 90 Grad A-2", ...}, + "container": {"0_BG071090": "0_B10071, 0_B10090, 0_B10090", ...}, } """ config = configparser.ConfigParser() @@ -81,6 +83,13 @@ def load_config(cfg_path): val = val[1:-1] layer_map[key] = val result["layer"] = layer_map + elif section == "container": + # Container-Sektion: 0_BGxxxxxx -> bereinigte, kommaseparierte Liste + container_map = {} + for key, val in config.items(section): + parts = [p.strip() for p in val.split(",") if p.strip()] + container_map[key] = ", ".join(parts) + result["container"] = container_map else: attrs = [] for tag, source in config.items(section): @@ -131,12 +140,33 @@ def get_layer_for_entry(typ, json_entry, layer_map): return "" -def resolve_value(source, json_entry, sivasnr): +CONTAINER_PATTERN = re.compile(r"0_BG\d+") + + +def resolve_container_refs(text, container_map): + """ + Ersetzt jedes Vorkommen von 0_BGxxxxxx in text durch die zugehoerige + kommaseparierte Liste aus [container]. Kommt das Muster mehrfach vor, + wird jedes Vorkommen einzeln ersetzt. Unbekannte 0_BG-Werte bleiben + unveraendert stehen. + """ + if not container_map or "0_BG" not in text: + return text + return CONTAINER_PATTERN.sub( + lambda m: container_map.get(m.group(0), m.group(0)), text + ) + + +def resolve_value(source, json_entry, sivasnr, container_map=None): """ Loest einen Quell-Ausdruck aus der Config auf: - "fester Text" -> fester Text - {sivasnr} -> SivasNr-Wert - Feldname -> Wert aus json_entry + + Wird das Feld "Sivasnr" aufgeloest und enthaelt der Wert ein oder + mehrere 0_BGxxxxxx-Muster, werden diese anhand von [container] durch + die dort hinterlegte kommaseparierte Liste ersetzt. """ source = source.strip() @@ -152,7 +182,10 @@ def resolve_value(source, json_entry, sivasnr): val = json_entry.get(source) if val is None: return "" - return str(val) + val = str(val) + if source == "Sivasnr": + val = resolve_container_refs(val, container_map) + return val # --------------------------------------------------------------------------- @@ -225,7 +258,7 @@ def wrap_entities_in_block(doc, block_name): def add_attdefs_to_dxf(dxf_path, output_path, attr_defs, json_entry, sivasnr, - layer_value=""): + layer_value="", container_map=None): """ Oeffnet eine DXF-Datei, fuegt ATTDEF-Entities in den Modelspace ein und speichert das Ergebnis. @@ -233,6 +266,7 @@ def add_attdefs_to_dxf(dxf_path, output_path, attr_defs, json_entry, sivasnr, attr_defs: Liste von (TAG, source_expression) aus der Config json_entry: Dict mit den JSON-Daten fuer dieses Element layer_value: Layer-Name aus [layer]-Sektion (wird als LAYER-ATTDEF gesetzt) + container_map: Dict aus [container]-Sektion fuer 0_BG-Aufloesung in Sivasnr """ doc = ezdxf.readfile(dxf_path) msp = doc.modelspace() @@ -265,7 +299,7 @@ def add_attdefs_to_dxf(dxf_path, output_path, attr_defs, json_entry, sivasnr, y_pos = y_start count = 0 for tag, source in all_defs: - default_value = resolve_value(source, json_entry, sivasnr) + default_value = resolve_value(source, json_entry, sivasnr, container_map) prompt = tag msp.add_attdef( @@ -296,6 +330,7 @@ def process_all(data_dir, cfg_path, results_dir, single_nr=None, dry_run=False): # Config laden attr_config = load_config(cfg_path) layer_map = attr_config.pop("layer", {}) + container_map = attr_config.pop("container", {}) print(f"[set_attributs] Config geladen: {list(attr_config.keys())}") if layer_map: print(f" [layer] {len(layer_map)} Zuordnungen: " @@ -319,7 +354,18 @@ def process_all(data_dir, cfg_path, results_dir, single_nr=None, dry_run=False): out_dir = os.path.join(results_dir, "omniflo") os.makedirs(out_dir, exist_ok=True) - omniflo_dir = os.environ.get("DXFM_OMNIFLO") or os.path.join(data_dir, "omniflo") + dxfm_dim = os.environ.get("DXFM_DIM") + if dxfm_dim: + omniflo_dir = os.path.join(data_dir, "omniflo", dxfm_dim) + else: + omniflo_dir = os.environ.get("DXFM_OMNIFLO") or os.path.join(data_dir, "omniflo") + if not os.path.isdir(omniflo_dir) or not any( + f.lower().endswith(".dxf") for f in os.listdir(omniflo_dir) + ): + print(f"[set_attributs] FEHLER: Im Quellverzeichnis '{omniflo_dir}' " + f"wurden keine DXF-Dateien gefunden. eventuell DXFM_DIM=2D in Umgebung setzen") + sys.exit(1) + processed = 0 skipped = 0 errors = 0 @@ -348,7 +394,7 @@ def process_all(data_dir, cfg_path, results_dir, single_nr=None, dry_run=False): output_path = os.path.join(out_dir, dxf_name) if dry_run: - values = {tag: resolve_value(src, entry, sivasnr) + values = {tag: resolve_value(src, entry, sivasnr, container_map) for tag, src in attr_defs} if layer_value: values["LAYER"] = layer_value @@ -359,7 +405,8 @@ def process_all(data_dir, cfg_path, results_dir, single_nr=None, dry_run=False): try: count = add_attdefs_to_dxf(dxf_path, output_path, attr_defs, entry, sivasnr, - layer_value=layer_value) + layer_value=layer_value, + container_map=container_map) processed += 1 print(f" OK: {sivasnr} ({typ}) -> {count} Attribute -> {output_path}") except Exception as e: @@ -379,9 +426,13 @@ def main(): help="Nur diese SivasNr verarbeiten") parser.add_argument("--dry-run", "-d", action="store_true", help="Nur anzeigen, nicht schreiben") + parser.add_argument("--type", "-t", choices=["2D", "3D"], default="2D", + help="Ueberschreibt DXFM_DIM und damit das " + "Quellverzeichnis data/omniflo/ (Default: 2D)") args = parser.parse_args() # Umgebungsvariablen + os.environ["DXFM_DIM"] = args.type data_dir = os.environ.get("DXFM_DATA") cfg_dir = os.environ.get("DXFM_CFG") results_dir = os.environ.get("DXFM_RESULTS")