feat: GR_-Geruest-Baugruppen in EXPORTCSV/EXPORTSIVAS aufnehmen
GR_-Bloecke werden jetzt wie BTMT eigenstaendig gesammelt (LISP: neues pattern_geruest in cfg/export.cfg, csv:collect-export-blocks, ssg-id-collect-blocks + ID-ATTDEF in *geruest-attrib-defs*) und in beiden Python-Exporten als eigene TeileArt-Zeile ausgegeben: ARTINR/BEZEICHNUNG/ TEILEART/LAENGE in festen Spalten, restliche Attribute (FARBE/LAYER) im Merkmale-/details-JSON. Dabei zwei Bugs behoben, die beim ersten echten GR_-Export sichtbar wurden: - csv:json-escape nutzte vl-string-subst (ersetzt nur das erste Vorkommen) statt des global ersetzenden ssg-str-replace-all - bei Attributwerten mit mehreren Anfuehrungszeichen blieb ein Zeichen unescaped und brach die JSON-Struktur beim Python-Parsen. - Gradzeichen (°) in data/json/geruest.json durch "Grad" ersetzt, um das Encoding-Risiko (cp1252 vs. UTF-8 beim LISP-Export) zu vermeiden.
This commit is contained in:
@@ -107,7 +107,7 @@ Detaillierte Dokumentation aller Funktionen und Befehle: siehe `Lisp/README.md`.
|
||||
| `OmniModulInsert.lsp` | OMNI_LOAD, OMNI_APB_*, OMNI_W*_*, OMNI_AP60/AP110, OMNI_TEF_*, OMNI_TV_*, OMNI_APBW_*, OMNI_EDIT | Omniflo-Komponenten: Boegen, Weichen, Verbinder, Transferwagen, Edit-Dialog |
|
||||
| `SSG_LIB_Commands.lsp` | ILS_BTMT_Beladung, ILS_BTMT_Entladung, ILS_SCANNER_INSERT, ILS_SEPARATOR_INSERT, ILS_EINGANG_INSERT, ILS_AUSGANG_INSERT, ILS_ETF_*, ILS_GK*_*, SSG_BLOCKEDIT, SSG_DIM_SWITCH, SSG_SPRACHE | BTMT Be-/Entladung (`ils-insert-station`: wiederholtes Einfuegen von `BTMT-Beladung` bzw. `SC_Entladung`, Drehung interaktiv, Layer aus `LAYER`-Attribut, Dimension via `ssg-ils-block-laden`) + Sensoren (`ils-insert-sensor`) + Eingang-/Ausgang-Symbol (frei platzierbar wie BTMT Be-/Entladung, ueber `ils-insert-station` mit den Rohnamen `Eingang`/`Ausgang`, Bloecke `Eingang_<DIM>.dwg`/`Ausgang_<DIM>.dwg` in data/ils) + Dummy-Befehle fuer Menue + Doppelklick/Kontextmenue-Dispatcher + Konfiguration (2D/3D, Sprache) |
|
||||
| `Tro_Edit.lsp` | TRO_INSERT, TRO_EDIT | TRO-Marker (Block `TRO_SYM_<Typ>`) fuer sps_skel (lib/tro_annotate.py): TRO_INSERT fuegt eine bestehende Blockdefinition an einem gewaehlten Punkt ein und setzt ID/TYPE (bricht ab, wenn der Typ noch keine Blockdefinition in der Zeichnung hat - die entsteht nur ueber tro_annotate.py); TRO_EDIT aendert ID/TYPE eines bestehenden Markers per Dialog. Typliste aus `tro_types.lsp` (von `tro_annotate.py --emit-lisp` nach DXFM_LISP geschrieben). Der Dispatcher SSG_BLOCKEDIT leitet Blocknamen `TRO_*` zu TRO_EDIT. |
|
||||
| `GeruestInsert.lsp` | GERUEST_ROHRABHAENGER, GERUEST_SAEULE_2ZOLL, GERUEST_SAEULE_1ZOLL, GERUEST_WANDBEFESTIGUNG | Geruest-Baugruppen aus `data/json/geruest.json` konfigurieren und einfuegen. Dialog (`dcl/geruest.dcl`): Basis-Variante aus `geometrie_varianten` (Dropdown), Anbauteile aus `anbaugruppen` (`list_box` mit `multiple_select` - im Projekt der erste), Laenge (gegen `attribute.Laenge` min/max geprueft, Retry-Schleife) und Farbe (`attribute.Farbe`, Freitext bei `frei_option`). Baugruppen ohne `attribute`-Block (Wandbefestigung) bekommen Laenge/Farbe gesperrt. Der Block wird - wie KREISEL_n/VF_n - SELBST zusammengebaut: Dummy-DWG aus `data/geruest` liefert nur Geometrie, das Attribut-Schema kommt aus `*geruest-attrib-defs*` (ARTINR, LAENGE, BEZEICHNUNG, TEILEART, FARBE, LAYER) und wird per `ssg-attrib-merge` mit den Dummy-Tags zusammengefuehrt - sonst verschluckt `ssg-attrib-set-on` stillschweigend jeden Tag, den die Dummy-DWG nicht als ATTDEF kennt. Blockname `GR_<id>_<ssg-timestamp>` (Kollisionszaehler wie in OmniModulInsert). **Das `GR_`-Praefix ist nicht kosmetisch**: `SSG_BLOCKEDIT` haelt JEDEN Block mit TEILEART-Attribut fuer ein Omniflo-Element, deshalb steht in `SSG_LIB_Commands.lsp` ein `GR_*`-Zweig VOR dem Omniflo-Zweig. ARTINR listet jede Sivas-ID so oft, wie `menge` es vorgibt (benannte Gruppen mit `teile` werden rekursiv aufgeloest); BEZEICHNUNG verkettet mit `" + "`, NICHT mit Komma - die Artikelbezeichnungen enthalten selbst Kommas ("ROHR R 1\" 33,7 x 2,6"). Zuordnung Menue -> JSON laeuft ueber das ASCII-Feld `id`, weil die aeusseren JSON-Schluessel Umlaute bzw. Anfuehrungszeichen tragen. Noch NICHT enthalten: Edit-Pfad (GERUEST_EDIT) und CSV-/Sivas-Export (`csv:collect-export-blocks` braucht dafuer ein `pattern_geruest = GR_*`) |
|
||||
| `GeruestInsert.lsp` | GERUEST_ROHRABHAENGER, GERUEST_SAEULE_2ZOLL, GERUEST_SAEULE_1ZOLL, GERUEST_WANDBEFESTIGUNG | Geruest-Baugruppen aus `data/json/geruest.json` konfigurieren und einfuegen. Dialog (`dcl/geruest.dcl`): Basis-Variante aus `geometrie_varianten` (Dropdown), Anbauteile aus `anbaugruppen` (`list_box` mit `multiple_select` - im Projekt der erste), Laenge (gegen `attribute.Laenge` min/max geprueft, Retry-Schleife) und Farbe (`attribute.Farbe`, Freitext bei `frei_option`). Baugruppen ohne `attribute`-Block (Wandbefestigung) bekommen Laenge/Farbe gesperrt. Der Block wird - wie KREISEL_n/VF_n - SELBST zusammengebaut: Dummy-DWG aus `data/geruest` liefert nur Geometrie, das Attribut-Schema kommt aus `*geruest-attrib-defs*` (ARTINR, LAENGE, BEZEICHNUNG, TEILEART, FARBE, LAYER) und wird per `ssg-attrib-merge` mit den Dummy-Tags zusammengefuehrt - sonst verschluckt `ssg-attrib-set-on` stillschweigend jeden Tag, den die Dummy-DWG nicht als ATTDEF kennt. Blockname `GR_<id>_<ssg-timestamp>` (Kollisionszaehler wie in OmniModulInsert). **Das `GR_`-Praefix ist nicht kosmetisch**: `SSG_BLOCKEDIT` haelt JEDEN Block mit TEILEART-Attribut fuer ein Omniflo-Element, deshalb steht in `SSG_LIB_Commands.lsp` ein `GR_*`-Zweig VOR dem Omniflo-Zweig. ARTINR listet jede Sivas-ID so oft, wie `menge` es vorgibt (benannte Gruppen mit `teile` werden rekursiv aufgeloest); BEZEICHNUNG verkettet mit `" + "`, NICHT mit Komma - die Artikelbezeichnungen enthalten selbst Kommas ("ROHR R 1\" 33,7 x 2,6"). Zuordnung Menue -> JSON laeuft ueber das ASCII-Feld `id`, weil die aeusseren JSON-Schluessel Umlaute bzw. Anfuehrungszeichen tragen. CSV-/Sivas-Export: `pattern_geruest = GR_*` (cfg/export.cfg), `csv:collect-export-blocks`/`ssg-id-collect-blocks` sammeln GR_-Bloecke wie BTMT eigenstaendig; `*geruest-attrib-defs*` traegt zusaetzlich ein leeres `ID`-ATTDEF (Voraussetzung fuer `ssg-id-check-all`, das nur bestehende ATTRIBs beschreiben kann). ARTINR/BEZEICHNUNG/TEILEART/LAENGE landen in export_csv.py/export_sivas.py in festen Spalten, FARBE/LAYER (+ ARTINR bei export_csv.py) im Merkmale-/details-JSON. Noch NICHT enthalten: Edit-Pfad (GERUEST_EDIT) |
|
||||
| `menu-inventory.lsp` | MenuInventory | BricsCAD Diagnostik (Menuegruppen, Plugins, Startdateien) |
|
||||
| `DrawPlanquadrate.lsp` | DRAW_PLANQUADRATE, DELETE_PLANQUADRATE, PLANQUADRATE_TOGGLE | Zeichnet auf Z=0 ein Planquadrat-Linienraster (senkrecht/waagerecht), im Abstand/Zaehlschema der aktiven `[Planquadrate]`-Konfiguration aus `cfg/export.cfg` (dieselbe Quelle wie `lib/export_planquadrat.py` fuer den CSV-Export). Bereich kommt NICHT aus den Zeichnungs-Extents, sondern aus derselben Blockmenge wie EXPORTCSV (`csv:collect-export-blocks`, export.lsp; siehe `plq-export-bbox`): Ursprung (Index 1) UND obere Grenze kommen BEIDE aus der tatsaechlichen Bounding-Box jedes Blocks (`csv:get-bbox`, wie `bbox_columns()`/`planquadrat_column()`/`_bbox_min()` in `lib/export_csv.py` bzw. `lib/export_planquadrat.py`), NICHT aus dem reinen Einfuegepunkt - bei einem gedrehten/exzentrisch eingefuegten Block (z.B. ein um 90 Grad gedrehter Kreisel) kann das Bounding-Box-Zentrum weit vom Einfuegepunkt abweichen; Ursprung und Zellzuordnung muessen auf derselben Referenz beruhen, sonst driften sie auseinander (realer Bug, behoben). Reine Hilfsgeometrie (Kreisel-Umfahrungsboegen als eigene Linien, Texte) zaehlt bewusst nicht mit, sonst weicht das Raster vom CSV-Export ab. `x_origin`/`y_origin` ueberschreiben den Ursprung, Fallback auf EXTMIN/EXTMAX falls keine Export-Bloecke vorhanden sind bzw. `csv:get-bbox` fuer einen Block scheitert. Spalten-/Zeilenzahl wird IMMER aufgerundet auf volle Rasterschritte, damit alle senkrechten Linien auf der letzten waagerechten enden und umgekehrt - das Raster bildet immer ein geschlossenes Rechteck. Zaehlung (alphabetisch/numerisch je Achse) als Text am linken/unteren Rand. Das fertige Raster (Linien+Texte) wird per `_.-BLOCK`/`_.INSERT` zu einem einzigen Block `ZZ_PLANQUADRATE` bei (0,0,0) zusammengefasst. Layer aus `cfg/layer.cfg` (`[allgemein]` Key `planquadrate`, Fallback `ZZ_Planquadrate`). DRAW_PLANQUADRATE entfernt vor dem Neuaufbau zuerst einen evtl. vorhandenen Block (`plq-block-entfernen`: INSERTs loeschen + `_-PURGE _B`), DELETE_PLANQUADRATE ruft nur diese Entfernung auf. PLANQUADRATE_TOGGLE ("Planquadrate an/aus", Menue: Konfiguration) prueft per `tblsearch`/`ssget "X"`, ob der Block existiert, und dispatcht auf Zeichnen bzw. Loeschen. Lazy geladen ueber `(ssg-ensure "DrawPlanquadrate")`, nicht in der Core-Ladereihenfolge. Die Planquadrat-SPALTE im CSV-Export (`export_csv.py::planquadrat_column`/`resolve_origins`, `lib/export_planquadrat.py::compute_planquadrat`/`_bbox_min`) rechnet ebenfalls durchgaengig auf Bounding-Box-Basis (nicht nur Einfuegepunkt) und liefert eine SPANNE ("A/1-J/1") statt nur einer Zelle, wenn ein Element mehr als eine Zelle ueberdeckt (Kreisel, lange VF-/GF-Ketten). |
|
||||
|
||||
|
||||
@@ -24,9 +24,15 @@
|
||||
|
||||
;; Attribut-Schema des Wrapper-Blocks. Die Dummy-DWG darf eigene Tags
|
||||
;; mitbringen - die bleiben erhalten (ssg-attrib-merge).
|
||||
;; "ID" (leer vorbelegt, wie bei Kreisel/VF_n/GF_n) ist Voraussetzung dafuer,
|
||||
;; dass ssg-id-check-all dem Block ueberhaupt eine ID zuweisen kann -
|
||||
;; ssg-attrib-set-on schreibt nur auf ein bereits vorhandenes ATTDEF, siehe
|
||||
;; oben. Ohne diesen Eintrag bliebe ID fuer immer leer (csv:read-attribs
|
||||
;; exportiert dann eben kein "ID"-Feld statt eines Werts).
|
||||
(if (null *geruest-attrib-defs*)
|
||||
(setq *geruest-attrib-defs*
|
||||
'(("ARTINR" "")
|
||||
'(("ID" "")
|
||||
("ARTINR" "")
|
||||
("LAENGE" "")
|
||||
("BEZEICHNUNG" "")
|
||||
("TEILEART" "")
|
||||
|
||||
+13
-2
@@ -198,12 +198,18 @@
|
||||
|
||||
;; --- String fuer JSON escapen (Anfuehrungszeichen/Backslash) ---
|
||||
;; Konvertiert nicht-String-Werte (z.B. T, nil, Zahlen) defensiv in String.
|
||||
;; ssg-str-replace-all (ssg_lang.lsp) statt vl-string-subst: vl-string-subst
|
||||
;; ersetzt nur das ERSTE Vorkommen, nicht alle - bei einem Attributwert mit
|
||||
;; MEHREREN Anfuehrungszeichen (z.B. BEZEICHNUNG einer Geruest-Baugruppe mit
|
||||
;; zwei Zoll-Angaben wie 'F. 2" UND 1" ROHR') blieb das zweite Vorkommen
|
||||
;; unescaped stehen und brach die JSON-Struktur beim Python-Parsen (realer
|
||||
;; Bug, behoben) - export_raw.json/EXPORTCSV.
|
||||
(defun csv:json-escape (s)
|
||||
(if (not (= (type s) 'STR))
|
||||
(setq s (if s (vl-princ-to-string s) ""))
|
||||
)
|
||||
(setq s (vl-string-subst "\\\\" "\\" s))
|
||||
(vl-string-subst "\\\"" "\"" s)
|
||||
(setq s (ssg-str-replace-all "\\\\" "\\" s))
|
||||
(ssg-str-replace-all "\\\"" "\"" s)
|
||||
)
|
||||
|
||||
|
||||
@@ -1082,6 +1088,10 @@
|
||||
;; ils-insert-station in SSG_LIB_Commands.lsp). Anders als Separator/
|
||||
;; Scanner werden sie von KEINEM anderen Element mitgezaehlt - export_csv.py
|
||||
;; UND export_sivas.py fuehren sie beide als eigene TeileArt-Zeilen.
|
||||
;; GR_* = Geruest-Baugruppen (siehe pattern_geruest in cfg/export.cfg,
|
||||
;; GeruestInsert.lsp). Wie BTMT eigenstaendig und von keinem anderen
|
||||
;; Element mitgezaehlt - export_csv.py UND export_sivas.py fuehren sie
|
||||
;; beide als eigene TeileArt-Zeilen.
|
||||
;; Gibt Auswahlsatz zurueck oder nil.
|
||||
(defun csv:collect-export-blocks ( / ss-all ss-out i ename ed bname)
|
||||
(setq ss-all (ssget "X" (list (cons 0 "INSERT"))))
|
||||
@@ -1101,6 +1111,7 @@
|
||||
(wcmatch bname (export:pattern "pattern_scanner" "Scanner*"))
|
||||
(wcmatch bname (export:pattern "pattern_btmt_beladung" "BTMT-Beladung*"))
|
||||
(wcmatch bname (export:pattern "pattern_btmt_entladung" "SC_Entladung*"))
|
||||
(wcmatch bname (export:pattern "pattern_geruest" "GR_*"))
|
||||
;; Rein numerische Namen = Omniflo SivasNr (Boegen/Weichen)
|
||||
;; Rein LISP-intern (Python klassifiziert Omniflo stattdessen
|
||||
;; ueber exakten Katalog-Match), daher fest im Code statt in
|
||||
|
||||
@@ -38,6 +38,8 @@
|
||||
;; pattern_btmt_entladung in cfg/export.cfg) aus demselben Grund: sonst bleibt
|
||||
;; ihre ID trotz ATTDEF leer und sie fehlen bei der zeichnungsweiten Duplikat-
|
||||
;; pruefung/Maximum-Ermittlung (ssg-id-check-all).
|
||||
;; GR_* (Geruest-Baugruppen, siehe pattern_geruest in cfg/export.cfg) ebenso -
|
||||
;; das ID-ATTDEF steht seit *geruest-attrib-defs* zur Verfuegung.
|
||||
(defun ssg-id-collect-blocks ( / ss-all ss-out i ename ed bname)
|
||||
(dbgf "ssg-id-collect-blocks")
|
||||
(setq ss-all (ssget "X" (list (cons 0 "INSERT"))))
|
||||
@@ -55,6 +57,7 @@
|
||||
(wcmatch bname "Vario*,Staustrecke*,AUS_Element*,EIN_Element*,VF_*,GF_*")
|
||||
(wcmatch bname "Separator_SP*,S-LP*,Scanner*")
|
||||
(wcmatch bname "BTMT-Beladung*,SC_Entladung*")
|
||||
(wcmatch bname "GR_*")
|
||||
(wcmatch bname "#*")
|
||||
)
|
||||
(ssadd ename ss-out)
|
||||
|
||||
@@ -36,6 +36,10 @@
|
||||
# fuehren sie daher beide als eigene TeileArt-Zeilen (export_sivas.py zusaetzlich
|
||||
# in den Summierungszaehlern "Anzahl aller BTBeladung"/"Anzahl aller
|
||||
# Abwurfstationen" der ILS-Automation-Zeile).
|
||||
#
|
||||
# pattern_geruest: Geruest-Baugruppen (GeruestInsert.lsp, GR_<id>_<timestamp>).
|
||||
# Eigenstaendig wie BTMT, kein ANZAHL_*-Attribut an einem Carrier - export_csv.py
|
||||
# UND export_sivas.py fuehren sie als eigene TeileArt-Zeilen.
|
||||
# ============================================================
|
||||
|
||||
[blockpattern]
|
||||
@@ -50,6 +54,7 @@ pattern_separator= Separator_SP*, S-LP*
|
||||
pattern_scanner= Scanner*
|
||||
pattern_btmt_beladung= BTMT-Beladung*
|
||||
pattern_btmt_entladung= SC_Entladung*
|
||||
pattern_geruest= GR_*
|
||||
pattern_ks_subblocks= KS_EIN, KS_AUS, K1, K2, K3, K4
|
||||
|
||||
[python]
|
||||
|
||||
@@ -244,7 +244,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "R 2\" Haltearm 2-ARMIG 90°",
|
||||
"name": "R 2\" Haltearm 2-ARMIG 90 Grad",
|
||||
"teile": [
|
||||
{
|
||||
"artikel": "BODENSÄULE R 2\" 60,3 MIT FUSSPLATTE",
|
||||
@@ -257,14 +257,14 @@
|
||||
"menge": 1
|
||||
},
|
||||
{
|
||||
"artikel": "HALTEARM FÜR BODENSÄULE R 2\" 2-ARMIG 90° KPL.",
|
||||
"artikel": "HALTEARM FÜR BODENSÄULE R 2\" 2-ARMIG 90 Grad KPL.",
|
||||
"sivas_id": 821004054,
|
||||
"menge": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "R 2\" Haltearm 2-ARMIG 180°",
|
||||
"name": "R 2\" Haltearm 2-ARMIG 180 Grad",
|
||||
"teile": [
|
||||
{
|
||||
"artikel": "BODENSÄULE R 2\" 60,3 MIT FUSSPLATTE",
|
||||
@@ -277,7 +277,7 @@
|
||||
"menge": 1
|
||||
},
|
||||
{
|
||||
"artikel": "HALTEARM FÜR BODENSÄULE R 2\" 2-ARMIG 180° KPL.",
|
||||
"artikel": "HALTEARM FÜR BODENSÄULE R 2\" 2-ARMIG 180 Grad KPL.",
|
||||
"sivas_id": 821004052,
|
||||
"menge": 1
|
||||
}
|
||||
@@ -311,17 +311,17 @@
|
||||
"menge": 2
|
||||
},
|
||||
{
|
||||
"artikel": "KLEMMRING MIT MUFFE DOPPELT 90°, KPL.",
|
||||
"artikel": "KLEMMRING MIT MUFFE DOPPELT 90 Grad, KPL.",
|
||||
"sivas_id": 825002009,
|
||||
"menge": 2
|
||||
},
|
||||
{
|
||||
"artikel": "KLEMMRING MIT MUFFE DOPPELT 180°, KPL.",
|
||||
"artikel": "KLEMMRING MIT MUFFE DOPPELT 180 Grad, KPL.",
|
||||
"sivas_id": 825002008,
|
||||
"menge": 2
|
||||
},
|
||||
{
|
||||
"artikel": "KLEMMRING M. MUFFE DREIFACH 90°/180° KPL.",
|
||||
"artikel": "KLEMMRING M. MUFFE DREIFACH 90 Grad/180 Grad KPL.",
|
||||
"sivas_id": 825002007,
|
||||
"menge": 2
|
||||
},
|
||||
@@ -336,7 +336,7 @@
|
||||
"menge": 2
|
||||
},
|
||||
{
|
||||
"artikel": "KREUZSCHELLE F. 2\" UND 1\" ROHR SCHWENKBAR 360°",
|
||||
"artikel": "KREUZSCHELLE F. 2\" UND 1\" ROHR SCHWENKBAR 360 Grad",
|
||||
"sivas_id": 922083009,
|
||||
"menge": 2
|
||||
}
|
||||
|
||||
@@ -263,6 +263,23 @@ def build_btmt_merkmale(block):
|
||||
}
|
||||
|
||||
|
||||
def build_geruest_merkmale(block):
|
||||
"""Merkmale-Dict fuer einen GR_-Geruest-Baugruppenblock (siehe
|
||||
pattern_geruest in cfg/export.cfg, GeruestInsert.lsp *geruest-attrib-defs*).
|
||||
|
||||
ARTINR/LAENGE/BEZEICHNUNG wandern in feste CSV-Spalten (teileid/
|
||||
bezeichnung ueben in process_blocks unten), TEILEART/FARBE/LAYER bleiben
|
||||
als Rest-Attribute in der Merkmale-JSON-Spalte - so wie bei Separator/
|
||||
Scanner/BTMT bereits ueblich."""
|
||||
attribs = block.get("attribs", {})
|
||||
return {
|
||||
"TeileArt": attribs.get("TEILEART", ""),
|
||||
"Farbe": attribs.get("FARBE", ""),
|
||||
"Laenge": attribs.get("LAENGE", ""),
|
||||
"Layer": attribs.get("LAYER", ""),
|
||||
}
|
||||
|
||||
|
||||
def format_sensor_id(prefix, n):
|
||||
"""Fallback-TeileId fuer Separator/Scanner-Zeilen im CSV-Export, falls das
|
||||
Block-Attribut "ID" (noch) leer ist.
|
||||
@@ -869,6 +886,7 @@ def process_blocks(blocks, lookup, dbg=None):
|
||||
scanner_count = 0
|
||||
btmt_beladung_count = 0
|
||||
btmt_entladung_count = 0
|
||||
geruest_count = 0
|
||||
|
||||
# Zaehlung fuer die Omniflo-Sum-Zeile (nur Bogen/Weiche/Gerade)
|
||||
cnt_wk = cnt_einzel = cnt_delta = cnt_doppel = cnt_stern = 0
|
||||
@@ -1141,6 +1159,30 @@ def process_blocks(blocks, lookup, dbg=None):
|
||||
})
|
||||
continue
|
||||
|
||||
# Geruest-Baugruppe (GR_<id>_<timestamp>) - eigene TeileArt-Zeile,
|
||||
# analog zu BTMT: kein ANZAHL_*-Attribut an einem Carrier zaehlt sie
|
||||
# mit. TeileId ist das echte ID-Attribut (ssg-id-check-all fuellt es
|
||||
# vor jedem Export, siehe *geruest-attrib-defs*); ARTINR (Sivas-IDs,
|
||||
# ggf. mehrere kommagetrennt) landet als eigene Spalte in den
|
||||
# Merkmalen statt in "teileart" - anders als bei Kreisel/BTMT ist
|
||||
# "TEILEART" hier ein FREIES Attribut (Rohrabhaenger/Saeule/...), keine
|
||||
# feste Konstante.
|
||||
if matches_any(bname, BLOCKPATTERNS.get("pattern_geruest", [])):
|
||||
elem_nr += 1
|
||||
geruest_count += 1
|
||||
attribs = block.get("attribs", {})
|
||||
bezeichnung = attribs.get("BEZEICHNUNG", "").strip()
|
||||
items.append({
|
||||
"nr": elem_nr,
|
||||
"teileart": "Geruest",
|
||||
"teileid": attribs.get("ID") or format_sensor_id("GR", geruest_count),
|
||||
"bezeichnung": bezeichnung if bezeichnung else f"Geruest :{geruest_count}",
|
||||
"planquadrat": planquadrat_column(block, planquadrat_cfg),
|
||||
"merkmale": {"ARTINR": attribs.get("ARTINR", ""), **build_geruest_merkmale(block)},
|
||||
**bbox_columns(block),
|
||||
})
|
||||
continue
|
||||
|
||||
if has_omniflo:
|
||||
elem_nr += 1
|
||||
items.append({
|
||||
|
||||
@@ -288,6 +288,19 @@ def build_eckrad_details(block):
|
||||
}
|
||||
|
||||
|
||||
def build_geruest_details(block):
|
||||
"""Merkmale-Dict fuer eine GR_-Geruest-Baugruppe (siehe pattern_geruest in
|
||||
cfg/export.cfg, GeruestInsert.lsp *geruest-attrib-defs*). ARTINR/
|
||||
BEZEICHNUNG/TEILEART/LAENGE wandern in feste Sivas-Spalten (sivasnr/
|
||||
bezeichnung/teileart/laenge_mm), FARBE/LAYER bleiben als Rest-Attribute
|
||||
hier."""
|
||||
attribs = block.get("attribs", {})
|
||||
return {
|
||||
"Farbe": attribs.get("FARBE", ""),
|
||||
"Layer": attribs.get("LAYER", ""),
|
||||
}
|
||||
|
||||
|
||||
# --- Bekannte Bloecke ignorieren ---
|
||||
SKIP_BLOCKS = set(BLOCKPATTERNS.get("pattern_ks_subblocks", ["K1", "K2", "K3", "K4", "KS_EIN", "KS_AUS"]))
|
||||
|
||||
@@ -339,6 +352,7 @@ def process_blocks(blocks, lookup):
|
||||
btmt_beladung_bezeichnungen = []
|
||||
btmt_entladung_ids = [] # IDs aller SC_Entladung*-Bloecke (eine gruppierte Zeile)
|
||||
btmt_entladung_bezeichnungen = []
|
||||
geruest_list = [] # Liste von GR_-Geruest-Baugruppenbloecken, je einer Zeile
|
||||
|
||||
counters = {
|
||||
"anzahl_boegen": 0,
|
||||
@@ -369,6 +383,7 @@ def process_blocks(blocks, lookup):
|
||||
"anzahl_scanner": 0,
|
||||
"anzahl_btbeladung": 0,
|
||||
"anzahl_abwurfstationen": 0,
|
||||
"anzahl_geruest": 0,
|
||||
}
|
||||
|
||||
for block in blocks:
|
||||
@@ -398,6 +413,18 @@ def process_blocks(blocks, lookup):
|
||||
counters["anzahl_abwurfstationen"] += 1
|
||||
continue
|
||||
|
||||
# --- Geruest-Baugruppe ---
|
||||
# Anders als BTMT/Separator je Block eine EIGENE Zeile statt gruppiert:
|
||||
# ARTINR (Sivas-IDs) und Laenge/Farbe koennen von Block zu Block
|
||||
# unterschiedlich sein (freie Basis-Variante+Anbauteile-Auswahl je
|
||||
# GERUEST_*-Aufruf), eine Gruppierung wuerde das verschleiern - wie
|
||||
# bei VF_N/Kreisel oben, die aus demselben Grund ebenfalls einzeln
|
||||
# bleiben.
|
||||
if matches_any(bname, BLOCKPATTERNS.get("pattern_geruest", [])):
|
||||
geruest_list.append(block)
|
||||
counters["anzahl_geruest"] += 1
|
||||
continue
|
||||
|
||||
# --- Omniflo Bogen oder Weiche (erkannt via Katalog) ---
|
||||
if bname in lookup:
|
||||
typ, eintrag = lookup[bname]
|
||||
@@ -702,6 +729,28 @@ def process_blocks(blocks, lookup):
|
||||
})
|
||||
nr += 1
|
||||
|
||||
# Geruest-Baugruppen (GR_<id>_<timestamp>) - je Block eine eigene Zeile
|
||||
# (siehe Kommentar bei geruest_list oben). Sivasnr kommt direkt aus dem
|
||||
# ARTINR-Attribut - kann bereits mehrere, kommagetrennte Sivas-IDs
|
||||
# enthalten (Baugruppe aus mehreren Einzelteilen, siehe ssg-join in
|
||||
# GeruestInsert.lsp), anders als bei den uebrigen Teilearten also KEIN
|
||||
# fester Eintrag aus ILS_SIVASNR.
|
||||
for block in geruest_list:
|
||||
attribs = block.get("attribs", {})
|
||||
items.append({
|
||||
"nr": nr,
|
||||
"teileart": attribs.get("TEILEART", "Geruest"),
|
||||
"sivasnr": attribs.get("ARTINR", ""),
|
||||
"sivasnr_quoted": True,
|
||||
"bezeichnung": attribs.get("BEZEICHNUNG", ""),
|
||||
"dispgruppe": 20,
|
||||
"anzahl": 1,
|
||||
"laenge_mm": attribs.get("LAENGE", ""),
|
||||
"ids": [get_id(block)],
|
||||
"details": build_geruest_details(block),
|
||||
})
|
||||
nr += 1
|
||||
|
||||
# VarioFoerderer-Compound-Bloecke (VF_N) - je Block eine eigene Zeile mit
|
||||
# vollstaendigen Gefaelle-/Angetrieben-Teilgruppen (immer TYP "Streckengruppe").
|
||||
for block in vario_list:
|
||||
|
||||
Reference in New Issue
Block a user