Dispogruppe-Header korrigiert, Container-Referenzen und --type 2D/3D fuer set_attributs.py
Sivasnr-Werte mit 0_BGxxxxxx-Mustern werden jetzt ueber die neue [container]-Config-Sektion in kommaseparierte Listen aufgeloest. set_attributs.py kann nun explizit zwischen data/omniflo/2D und /3D als Quellverzeichnis waehlen.
This commit is contained in:
+2
-2
@@ -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:
|
||||
|
||||
+59
-8
@@ -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/<type> (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")
|
||||
|
||||
Reference in New Issue
Block a user