attradd.py und add_attr.bat in set_attributs.py/.bat umbenannt
lib/attradd.py -> lib/set_attributs.py: Name besser passend zum Skript-Zweck (setzt Attribute, analog set_einfuegepkt / set_koords). bin/add_attr.bat -> bin/set_attributs.bat entsprechend angepasst. cfg/attradd.cfg: Kommentar auf neuen Skriptnamen aktualisiert. HOEHE/DREHUNG-Eintraege aus [bogen] und [weiche] entfernt, da diese Attribute jetzt dynamisch via ssg-cfg-or aus component_defaults.json bezogen werden (nicht mehr als statische ATTDEF-Defaults noetig). Ebenso RADIUS aus [weiche] entfernt (war redundant zu KurvenWinkel). doc/tools.md und CLAUDE.md: Alle Verweise auf attradd.py auf set_attributs.py aktualisiert. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -81,14 +81,14 @@ Abhaengigkeiten: `ezdxf`, Standard-Library. Benoetigen Umgebungsvariablen (`DXFM
|
||||
| `omniflo_utils.py` | Gemeinsame Hilfsfunktionen fuer Omniflo-Skripte: `ROW_GROUPS` (Reihen-Gruppierung), `SWITCH_FILTERS` (Schalter-Filter), `build_row_layout`, `import_element_as_block`, `draw_cross`, `load_omniflo_data` |
|
||||
| `set_einfuegepkt.py` | Setzt `$INSBASE` (Einfuegepunkt) in Omniflo-DXF-Dateien. Schalter je Typ: `--boegen`, `--weichen45`, `--weichen90`, `--weichenkoerper`, `--weichen-parallel`, `--delta`, `--dreifachweiche`, `--sternweiche`, `--show-omniflo` |
|
||||
| `set_koords.py` | Setzt Koordinatensystem-Bloecke (K1-K4) in Omniflo-DXF-Dateien. Schalter: `--k1set` bis `--k4set`, `--set-all`, `--force`, `--show-omniflo`, `--test`, `--number` |
|
||||
| `attradd.py` | Fuegt ATTDEF-Attribute zu Omniflo-DXF-Dateien hinzu. Liest Konfiguration aus `cfg/attradd.cfg`. Schalter: `--number`, `--dry-run` |
|
||||
| `set_attributs.py` | Fuegt ATTDEF-Attribute zu Omniflo-DXF-Dateien hinzu. Liest Konfiguration aus `cfg/attradd.cfg`. Schalter: `--number`, `--dry-run` |
|
||||
| `export_sivas.py` | Erzeugt Sivas-Export-CSV mit Summierungszeilen (ILS Automation, Omniflo Sum). Aufruf: `python export_sivas.py <export_raw.json> <data_dir> <output.csv>` |
|
||||
| `export_csv.py` | Erzeugt einfache Item-Liste als CSV (ohne Summierung). Aufruf: `python export_csv.py <export_raw.json> <data_dir> <output.csv>` |
|
||||
| `testpycall.py` | Testskript fuer LISP-Python-Aufruf via CALLPYTHON |
|
||||
|
||||
### Typische Verarbeitungskette (Omniflo-DXF)
|
||||
|
||||
1. `attradd.py` - Attribute zu Quell-DXFs hinzufuegen
|
||||
1. `set_attributs.py` - Attribute zu Quell-DXFs hinzufuegen
|
||||
2. `set_einfuegepkt.py` - Einfuegepunkte berechnen und setzen
|
||||
3. `set_koords.py` - Koordinatensysteme (K1-K4) setzen
|
||||
4. `export_sivas.py` / `export_csv.py` - Export aus Zeichnung
|
||||
|
||||
@@ -5,4 +5,4 @@ REM ================================================================
|
||||
|
||||
call "%~dp0setenv.bat"
|
||||
|
||||
python "%DXFM_LIB%\attradd.py" %*
|
||||
python "%DXFM_LIB%\set_attributs.py" %*
|
||||
+3
-6
@@ -19,7 +19,7 @@
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# Layer-Zuordnung nach Elementkategorie
|
||||
# attradd.py bestimmt die Kategorie anhand KurvenWinkel und
|
||||
# set_attributs.py bestimmt die Kategorie anhand KurvenWinkel und
|
||||
# WeichenTyp aus den JSON-Daten und setzt LAYER entsprechend.
|
||||
# ------------------------------------------------------------
|
||||
[layer]
|
||||
@@ -45,8 +45,7 @@ TEILEART = "Omniflo Kurve"
|
||||
RADIUS = Radius
|
||||
WINKEL = KurvenWinkel
|
||||
SIVASNR_TEF = SivasnrTEF
|
||||
HOEHE = "2000"
|
||||
DREHUNG = "0"
|
||||
|
||||
|
||||
[weiche]
|
||||
BESCHR = ProfilTyp
|
||||
@@ -56,8 +55,6 @@ TEILEART = "Omniflo Weiche"
|
||||
# LAYER = "A-OF-Weiche"
|
||||
WEICHENTYP = WeichenTyp
|
||||
WINKEL = KurvenWinkel
|
||||
RADIUS = Breite
|
||||
RICHTUNG = KurvenRichtung
|
||||
SIVASNR_TEF = SivasnrTEF
|
||||
HOEHE = "2000"
|
||||
DREHUNG = "0"
|
||||
|
||||
|
||||
+60
-26
@@ -35,7 +35,7 @@ Diese Werkzeuge ermöglichen die massenhafte Aufbereitung von einzelnen dxf Date
|
||||
- [--number SIVASNR](#--number-sivasnr-1)
|
||||
- [Uebersicht K-Zuordnung](#uebersicht-k-zuordnung)
|
||||
- [Umgebungsvariablen](#umgebungsvariablen-1)
|
||||
- [attradd](#attradd)
|
||||
- [set_attributs](#set_attributs)
|
||||
- [Aufruf](#aufruf-2)
|
||||
- [Datenquellen](#datenquellen-2)
|
||||
- [Ablauf](#ablauf-2)
|
||||
@@ -274,14 +274,14 @@ Nur die angegebene 9-stellige Sivasnr verarbeiten. Kombinierbar mit jedem Schalt
|
||||
|
||||
---
|
||||
|
||||
# attradd
|
||||
# set_attributs
|
||||
|
||||
Fuegt Attribute (ATTDEF) zu allen Omniflo DXF-Dateien hinzu. Die Attribut-Tags und deren Werte werden ueber eine Konfigurationsdatei gesteuert.
|
||||
|
||||
## Aufruf
|
||||
|
||||
```
|
||||
python lib/attradd.py [--number SIVASNR] [--dry-run]
|
||||
python lib/set_attributs.py [--number SIVASNR] [--dry-run]
|
||||
```
|
||||
|
||||
## Datenquellen
|
||||
@@ -303,34 +303,68 @@ python lib/attradd.py [--number SIVASNR] [--dry-run]
|
||||
|
||||
## Konfiguration (attradd.cfg)
|
||||
|
||||
Die Config-Datei ist im INI-Format mit Abschnitten je Elementtyp:
|
||||
|
||||
```ini
|
||||
[bogen]
|
||||
BESCHR = ProfilTyp
|
||||
ARTINR = Sivasnr
|
||||
TEILEART = "Omniflo Kurve"
|
||||
LAYER = "A-OF-Bogen"
|
||||
RADIUS = Radius
|
||||
WINKEL = KurvenWinkel
|
||||
SIVASNR_TEF = SivasnrTEF
|
||||
|
||||
[weiche]
|
||||
BESCHR = ProfilTyp
|
||||
ARTINR = Sivasnr
|
||||
TEILEART = "Omniflo Weiche"
|
||||
LAYER = "A-OF-Weiche"
|
||||
WEICHENTYP = WeichenTyp
|
||||
WINKEL = KurvenWinkel
|
||||
RADIUS = Breite
|
||||
SIVASNR_TEF = SivasnrTEF
|
||||
```
|
||||
|
||||
Die Config-Datei ist im INI-Format mit Abschnitten je Elementtyp.
|
||||
Quellwerte koennen sein:
|
||||
- **JSON-Feldname** (z.B. `ProfilTyp`) - Wert wird aus dem JSON-Eintrag gelesen
|
||||
- **Fester Text** in Anfuehrungszeichen (z.B. `"Omniflo Kurve"`)
|
||||
- **Platzhalter** `{sivasnr}` - wird durch die Sivasnr ersetzt
|
||||
|
||||
### Attribute Omniflo Kurve (Bogen)
|
||||
|
||||
| ATTDEF-Tag | Quelle | Beschreibung |
|
||||
| --- | --- | --- |
|
||||
| `BESCHR` | `ProfilTyp` | Profilbezeichnung aus JSON |
|
||||
| `ARTINR` | `Sivasnr` | Sivas-Artikelnummer |
|
||||
| `TEILEART` | `"Omniflo Kurve"` | Fester Typname |
|
||||
| `RADIUS` | `Radius` | Kurvenradius in mm |
|
||||
| `WINKEL` | `KurvenWinkel` | Kurvenwinkel in Grad |
|
||||
| `SIVASNR_TEF` | `SivasnrTEF` | Sivas-Nr. des TEF-Antriebs (leer = kein Antrieb) |
|
||||
| `HOEHE` | `"2000"` | Montagehoehe in mm (wird beim Export aus Z-Koordinate aktualisiert) |
|
||||
| `DREHUNG` | `"0"` | Drehwinkel in Grad (wird beim Export aus CAD-Rotation aktualisiert) |
|
||||
| `LAYER` | *(aus [layer])* | Layer-Name gemaess Kategorisierung |
|
||||
|
||||
### Attribute Omniflo Weiche
|
||||
|
||||
| ATTDEF-Tag | Quelle | Beschreibung |
|
||||
| --- | --- | --- |
|
||||
| `BESCHR` | `ProfilTyp` | Profilbezeichnung aus JSON |
|
||||
| `ARTINR` | `Sivasnr` | Sivas-Artikelnummer |
|
||||
| `TEILEART` | `"Omniflo Weiche"` | Fester Typname |
|
||||
| `WEICHENTYP` | `WeichenTyp` | Weichentyp (Einzelweiche, Doppelweiche, Dreiwegeweiche, ...) |
|
||||
| `WINKEL` | `KurvenWinkel` | Kurvenwinkel in Grad |
|
||||
| `RICHTUNG` | `KurvenRichtung` | Richtungskennung (1=Links, 2=Rechts, 3=Beide, 7=Dreiweg) |
|
||||
| `SIVASNR_TEF` | `SivasnrTEF` | Sivas-Nr. des TEF-Antriebs (leer = kein Antrieb) |
|
||||
| `HOEHE` | `"2000"` | Montagehoehe in mm (wird beim Export aus Z-Koordinate aktualisiert) |
|
||||
| `DREHUNG` | `"0"` | Drehwinkel in Grad (wird beim Export aus CAD-Rotation aktualisiert) |
|
||||
| `LAYER` | *(aus [layer])* | Layer-Name gemaess Kategorisierung |
|
||||
|
||||
### CSV-Export-Felder (Merkmale)
|
||||
|
||||
Die Attribute werden beim CSV-Export (`export_csv.py` / `OMNI_EXPORT`) wie folgt in CSV-Merkmale ueberfuehrt.
|
||||
CSV-Format: `Elementnummer;TeileArt;TeileId;Bezeichnung;Anzahl;Merkmale`
|
||||
|
||||
**Omniflo Kurve:**
|
||||
|
||||
| Merkmal | Quelle | Typ |
|
||||
| --- | --- | --- |
|
||||
| `Kurvenwinkel` | JSON `KurvenWinkel` | float |
|
||||
| `Radius` | JSON `Radius` | float |
|
||||
| `Höhe` | Attribut `HOEHE` / Z-Koordinate | string |
|
||||
| `Drehung` | Attribut `DREHUNG` / CAD-Rotation | float |
|
||||
| `SivasNummer` | JSON `Sivasnr` | string |
|
||||
|
||||
**Omniflo Weiche:**
|
||||
|
||||
| Merkmal | Quelle | Typ |
|
||||
| --- | --- | --- |
|
||||
| `Weichentyp` | JSON `WeichenTyp` | string |
|
||||
| `Richtung` | JSON `KurvenRichtung` | string |
|
||||
| `Weichenwinkel` | JSON `KurvenWinkel` | float |
|
||||
| `Höhe` | Attribut `HOEHE` / Z-Koordinate | string |
|
||||
| `Drehung` | Attribut `DREHUNG` / CAD-Rotation | float |
|
||||
| `Antrieb Kurve` | `SivasnrTEF` != null | bool |
|
||||
| `SivasNummer` | JSON `Sivasnr` | string |
|
||||
|
||||
## Schalter
|
||||
|
||||
### --number SIVASNR / -n SIVASNR
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
attradd.py - Fuegt Attribute (ATTDEF) zu allen Omniflo DXF-Dateien hinzu.
|
||||
set_attributs.py - Fuegt Attribute (ATTDEF) zu allen Omniflo DXF-Dateien hinzu.
|
||||
|
||||
Liest die Attribut-Konfiguration aus cfg/attradd.cfg und die Element-Daten
|
||||
aus data/json/omniflo_boegen.json und omniflo_weichen.json.
|
||||
@@ -13,7 +13,7 @@ Umgebungsvariablen:
|
||||
DXFM_RESULTS - Pfad zum results/-Verzeichnis
|
||||
|
||||
Aufruf:
|
||||
python lib/attradd.py [--number SIVASNR] [--dry-run]
|
||||
python lib/set_attributs.py [--number SIVASNR] [--dry-run]
|
||||
"""
|
||||
|
||||
import argparse
|
||||
@@ -157,11 +157,32 @@ ATTDEF_HEIGHT = 5.0
|
||||
ATTDEF_LAYER = "ATTRIB"
|
||||
|
||||
|
||||
def wrap_entities_in_block(doc, block_name):
|
||||
"""
|
||||
Verschiebt alle Entities aus dem Modelspace in eine Blockdefinition
|
||||
mit dem Namen block_name und fuegt eine Blockreferenz bei (0, 0) ein.
|
||||
Vorhandene Blockdefinition mit gleichem Namen wird ersetzt (fuer Re-Runs).
|
||||
"""
|
||||
msp = doc.modelspace()
|
||||
|
||||
# Vorhandene Blockdefinition entfernen
|
||||
if block_name in doc.blocks:
|
||||
doc.blocks.delete_block(block_name, safe=False)
|
||||
|
||||
blk = doc.blocks.new(block_name)
|
||||
|
||||
for entity in list(msp):
|
||||
msp.move_to_layout(entity, blk)
|
||||
|
||||
msp.add_blockref(block_name, (0, 0))
|
||||
|
||||
|
||||
def add_attdefs_to_dxf(dxf_path, output_path, attr_defs, json_entry, sivasnr,
|
||||
layer_value=""):
|
||||
"""
|
||||
Oeffnet eine DXF-Datei, fuegt ATTDEF-Entities in den Modelspace ein
|
||||
und speichert das Ergebnis.
|
||||
Oeffnet eine DXF-Datei, fuegt ATTDEF-Entities in den Modelspace ein,
|
||||
fasst alle Entities anschliessend in einen Block mit dem Namen sivasnr
|
||||
zusammen und speichert das Ergebnis.
|
||||
|
||||
attr_defs: Liste von (TAG, source_expression) aus der Config
|
||||
json_entry: Dict mit den JSON-Daten fuer dieses Element
|
||||
@@ -205,6 +226,9 @@ def add_attdefs_to_dxf(dxf_path, output_path, attr_defs, json_entry, sivasnr,
|
||||
y_pos += ATTDEF_SPACING
|
||||
count += 1
|
||||
|
||||
# Alle Entities (Geometrie + ATTDEFs) in Block mit Sivasnr-Namen fassen
|
||||
wrap_entities_in_block(doc, sivasnr)
|
||||
|
||||
doc.saveas(output_path)
|
||||
return count
|
||||
|
||||
@@ -219,7 +243,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", {})
|
||||
print(f"[attradd] Config geladen: {list(attr_config.keys())}")
|
||||
print(f"[set_attributs] Config geladen: {list(attr_config.keys())}")
|
||||
if layer_map:
|
||||
print(f" [layer] {len(layer_map)} Zuordnungen: "
|
||||
f"{', '.join(f'{k}={v}' for k, v in layer_map.items())}")
|
||||
@@ -231,7 +255,7 @@ def process_all(data_dir, cfg_path, results_dir, single_nr=None, dry_run=False):
|
||||
boegen = load_json(os.path.join(data_dir, "json", "omniflo_boegen.json"))
|
||||
weichen = load_json(os.path.join(data_dir, "json", "omniflo_weichen.json"))
|
||||
lookup = build_lookup(boegen, weichen)
|
||||
print(f"[attradd] {len(boegen)} Boegen, {len(weichen)} Weichen geladen.")
|
||||
print(f"[set_attributs] {len(boegen)} Boegen, {len(weichen)} Weichen geladen.")
|
||||
|
||||
# Ausgabeverzeichnis
|
||||
out_dir = os.path.join(results_dir, "omniflo")
|
||||
@@ -284,10 +308,10 @@ def process_all(data_dir, cfg_path, results_dir, single_nr=None, dry_run=False):
|
||||
errors += 1
|
||||
print(f" FEHLER: {sivasnr}: {e}")
|
||||
|
||||
print(f"\n[attradd] Fertig: {processed} verarbeitet, "
|
||||
print(f"\n[set_attributs] Fertig: {processed} verarbeitet, "
|
||||
f"{skipped} uebersprungen, {errors} Fehler.")
|
||||
if not dry_run:
|
||||
print(f"[attradd] Ausgabe in: {out_dir}")
|
||||
print(f"[set_attributs] Ausgabe in: {out_dir}")
|
||||
|
||||
|
||||
def main():
|
||||
@@ -317,7 +341,7 @@ def main():
|
||||
|
||||
cfg_path = os.path.join(cfg_dir, "attradd.cfg")
|
||||
if not os.path.exists(cfg_path):
|
||||
print(f"[attradd] FEHLER: Config nicht gefunden: {cfg_path}")
|
||||
print(f"[set_attributs] FEHLER: Config nicht gefunden: {cfg_path}")
|
||||
sys.exit(1)
|
||||
|
||||
process_all(data_dir, cfg_path, results_dir,
|
||||
Reference in New Issue
Block a user