export: jeden Wert nur an einer Stelle setzen (ZUORDNUNG, sepliste-IDs, Typen, K1/K2)
- ZUORDNUNG: ssg-id-check-all laeuft jetzt ZUERST, danach sind die Wrapper-IDs endgueltig - Separator-Kopien, AS/ES- und Einheiten-Marker bekommen ZUORDNUNG direkt beim Erzeugen. Entfallen: csv:sep-proxies-zuordnung-setzen, csv:asmark-ids-setzen, csv:unitmark-ids-setzen. zuordnung_fix/*cs-sep-fix-by-handle* bleibt (count_sep_scan rechnet eigenstaendige Sensoren bewusst neu). - sepliste-IDs: Zuordnung ueber die KS-Kettenfolge je Typ (csv:sepliste-kette-paare) statt ueber die teils gespiegelten sepliste-Koordinaten (csv:sepliste-paare, csv:sepliste-ids-setzen entfallen). Die Kette wird je Lauf einmal berechnet (csv:kette-von); die ID liest csv:block-to-json erst beim Schreiben. Behebt vertauschte TrackIds/Nachbarn in HundM05 VF_1 (0031/0029). - Element-Klassifizierung: eine Tabelle csv:element-familien (cfg-Muster) fuer Suche und Klassifizierung; csv:proxy-typ entfaellt. - Einheiten-Marker: K1/K2 nur noch in *csv-baustein-by-handle* (csv:geometrie-merken), K1/K2-Attribute und csv:unitmark-k-kos-strings entfallen. Geprueft: HundM05-Export alt/neu headless verglichen - einzige Abweichung ist die korrigierte Reihenfolge in VF_1. LISP-Unit-Tests 303/303. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
e67f7cc1aa
commit
1e6b152d72
+48
-47
@@ -43,7 +43,14 @@ Datei: `Lisp/export.lsp`. `c:EXPORTCSV` ruft `csv:run-export` mit
|
||||
`include-bbox=T` auf (im Unterschied zu `c:EXPORTSIVAS`, das keine
|
||||
Bounding-Boxen braucht).
|
||||
|
||||
1. **`csv:sep-proxies-erzeugen`** — Separator_SP-Symbole, die beim
|
||||
Jeder Wert wird dabei genau EINMAL gesetzt; die Reihenfolge sorgt dafuer,
|
||||
dass er beim Setzen schon feststeht (`csv:export-vorbereiten`):
|
||||
|
||||
1. **`ssg-id-check-all`** — ZUERST, noch bevor ein Stellvertreter existiert:
|
||||
vergibt fehlende IDs und korrigiert Duplikate. Danach ist die ID jedes
|
||||
Wrappers (`VF_n`/`GF_n`/`KREISEL_n`) endgueltig, die folgenden Schritte
|
||||
koennen `ZUORDNUNG` direkt beim Erzeugen setzen.
|
||||
2. **`csv:sep-proxies-erzeugen`** — Separator_SP-Symbole, die beim
|
||||
Zusammenbau von `KREISEL_n`/`ECKRAD_n`/`VF_n`/`GF_n` in die
|
||||
Compound-Blockdefinition verpackt wurden, sind fuer `(ssget "X" ...)`
|
||||
unsichtbar. Diese Funktion fuegt fuer jeden Fund eine ECHTE, temporaere
|
||||
@@ -51,32 +58,30 @@ Bounding-Boxen braucht).
|
||||
durchlaeuft danach ID-Vergabe und Export ganz normal ueber den freien-
|
||||
Separator-Pfad (Blockname-Muster `Separator_SP*` trifft zu) und bekommt
|
||||
dadurch eine echte `vla-getboundingbox`-Box, die das verpackte Original nie
|
||||
haben koennte. Rueckgabe: Liste von Records
|
||||
`(proxy-ename wrapper-ename typ (x y z))`.
|
||||
1b. **`csv:asmark-aktualisieren`** — die AS-/ES-Enden derselben Kette
|
||||
haben koennte. Dabei bekommt die Kopie `ZUORDNUNG = Wrapper-ID` (bekannt,
|
||||
nicht geraten) und wird in `*cs-sep-fix-by-handle*` als "bekannt"
|
||||
vermerkt: `count_sep_scan.lsp` und `export_csv.py` (Feld `zuordnung_fix`)
|
||||
berechnen die Zuordnung EIGENSTAENDIGER Sensoren bei jedem Lauf
|
||||
geometrisch neu und nehmen verpackte Separatoren damit davon aus.
|
||||
Rueckgabe: Liste von Records `(proxy-ename wrapper-ename "SEP" (x y z)
|
||||
trennsteg-ent)`.
|
||||
2b. **`csv:asmark-aktualisieren`** — die AS-/ES-Enden derselben Kette
|
||||
(`AS_Element*`/`ES_Element*`, Muster `pattern_schleuselement`) bekommen
|
||||
KEINE Kopie des Elements, sondern einen eigenen (ebenfalls temporaeren) Marker — siehe eigener
|
||||
Abschnitt "Der AS/ES-Marker" unten. Beide Wege teilen sich die
|
||||
Platzierungsrechnung (`csv:nested-welt-records` liefert die Weltlage jedes
|
||||
verpackten Fundes, `csv:block-einfuegen-welt` setzt ein Objekt dorthin).
|
||||
2. **`ssg-id-check-all`** — vergibt fehlende IDs (inkl. der frisch erzeugten
|
||||
Proxies) und korrigiert Duplikate. Muss NACH den Proxies laufen, sonst
|
||||
wuerden diese Kopien numerisch nie erfasst. `ssg-id-collect-blocks`
|
||||
(`ssg_id.lsp`) erfasst dafuer auch `AS_Element*`/`ES_Element*`.
|
||||
3. **`csv:sep-proxies-zuordnung-setzen`** — jetzt steht die ID jedes Wrappers
|
||||
fest: die Proxy-Kopie bekommt `ZUORDNUNG = Wrapper-ID` fest zugewiesen
|
||||
(nicht geraten) und wird zusaetzlich in `*cs-sep-fix-by-handle*` vermerkt,
|
||||
damit `count_sep_scan.lsp` diesen Wert spaeter nicht per Geometrie
|
||||
ueberschreibt. Nur fuer die Separator-Kopien — AS/ES sind keine Sensoren.
|
||||
3b. **`csv:asmark-ids-setzen` + `csv:sepliste-ids-setzen`** — ebenfalls erst
|
||||
jetzt moeglich: jedes Bauteil wird seinem `sepliste`-Eintrag zugeordnet und
|
||||
seine ID unter `*csv-sepliste-id-by-handle*` (Key = Wrapper-Handle)
|
||||
abgelegt; `csv:block-to-json` schreibt sie als Feld `id` in den Eintrag.
|
||||
AS/ES laufen ueber die Marker (die ihre ID schon kennen, die Zuordnung
|
||||
steht im Marker-Attribut `LFDNR`), SEP ueber die temporaeren Kopien und
|
||||
`csv:sepliste-paare` — siehe eigener Abschnitt unten. `csv:asmark-ids-setzen`
|
||||
traegt zusaetzlich die `ZUORDNUNG` (Wrapper-ID) am Marker nach; ohne sie
|
||||
faende der naechste Export den Marker nicht wieder.
|
||||
KEINE Kopie des Elements, sondern einen eigenen (ebenfalls temporaeren)
|
||||
Marker, mit `ZUORDNUNG` direkt beim Erzeugen — siehe eigener Abschnitt
|
||||
"Der AS/ES-Marker" unten.
|
||||
2c. **`csv:element-proxies-erzeugen`** — nur Modus `all_elements`: Kopien der
|
||||
uebrigen Kettenbausteine (Boegen, Streckenelemente, Umlenk-/Motorstation).
|
||||
3. **`csv:ketten-verarbeiten`** — je `VF_n`/`GF_n` die KS-geordnete Kette
|
||||
(`csv:kette-von`, einmal je Lauf berechnet) auswerten: Einheiten-Proxies
|
||||
(Modus `group_vf_gf`), IDs in Kettenfolge, Separator-Typ VF/GF
|
||||
(`csv:kette-sep-typen`) und die Stellvertreter der `sepliste`-Eintraege
|
||||
(`csv:sepliste-kette-paare`, siehe eigener Abschnitt unten). Alles aus
|
||||
DERSELBEN Kette - Einheiten-BB, Separator-Typ und TrackIds passen damit
|
||||
zusammen.
|
||||
3b. **`ssg-id-check-all`** (zweiter Lauf) — Restnummerierung (z.B. Kreisel-
|
||||
Separator ohne Kette) und Duplikat-Korrektur unter den neuen
|
||||
Stellvertretern; danach `csv:res-ids-schreiben` (reservierte IDs).
|
||||
4. **`omni:update-all-attribs`** — Hoehe/Drehung aller Omniflo-Elemente vor
|
||||
dem Export aktualisieren.
|
||||
5. **`count_sep_scan.lsp::cs-zuordnung-lauf`** (nur bei Bedarf, siehe
|
||||
@@ -229,8 +234,9 @@ zu zaehlen.
|
||||
|
||||
### Das Feld `id` je sepliste-Eintrag
|
||||
|
||||
Seit `csv:sepliste-ids-setzen` traegt JEDER Eintrag zusaetzlich die `id` des
|
||||
realen Bauteils, das ihn in der Zeichnung vertritt:
|
||||
JEDER Eintrag traegt zusaetzlich die `id` des realen Bauteils, das ihn in der
|
||||
Zeichnung vertritt (zugeordnet in `csv:ketten-verarbeiten`, die ID selbst
|
||||
liest `csv:block-to-json` erst beim Schreiben vom Stellvertreter):
|
||||
|
||||
```json
|
||||
{"typ": "AS", "lfdnr": 1, "x": 5070.1, "y": 1199.2, "id": "0031"}
|
||||
@@ -286,26 +292,21 @@ jeder, der keinem Kettenende mehr entspricht.
|
||||
Im Export ist der Marker eine eigene Zeile (`pattern_ases_marker` in
|
||||
`cfg/export.cfg`) und liefert die `id` des AS-/ES-Eintrags in der `sepliste`.
|
||||
|
||||
**Zuordnung Eintrag -> Kopie (`csv:sepliste-paare`).** Verglichen wird nur
|
||||
innerhalb desselben Typmarkers (`AS`/`ES`/`SEP`) und EXKLUSIV: alle Paare
|
||||
eines Typs werden nach Abstand sortiert, das kuerzeste zuerst genommen, danach
|
||||
sind Eintrag UND Kopie verbraucht. Zwei Gruende gegen das naheliegende "je
|
||||
Eintrag die naechste Kopie":
|
||||
**Zuordnung Eintrag -> Bauteil (`csv:sepliste-kette-paare`).** Ueber die
|
||||
REIHENFOLGE je Typ: das k-te `AS`/`SEP`/`ES` der sepliste (nach `lfdnr`) ist
|
||||
das k-te `AS`/`SEP`/`ES` der KS-geordneten Kette (`csv:kette-von`). Die
|
||||
sepliste entsteht beim Bau per `entnext`-Wanderung in Baureihenfolge, und
|
||||
gebaut wird in Foerderrichtung - dieselbe Folge, die die KS-Kette
|
||||
rekonstruiert. Die x/y-Koordinaten der sepliste werden dafuer NICHT benutzt.
|
||||
|
||||
- waehlen zwei Eintraege dieselbe Kopie, bleibt eine Kopie ohne Eintrag und
|
||||
ein Eintrag ohne ID (genau dieses Muster verursacht in Python die
|
||||
Separatoren ohne `Nachbarn`/`TrackIds`);
|
||||
- EIN fehlerhafter Koordinatenwert in der sepliste (bekannter Fall: gespiegeltes
|
||||
`x` bei `lfdnr=2`) verschiebt so keine anderen Zuordnungen mehr — alle
|
||||
uebrigen Eintraege finden ihre Kopie ueber den kurzen Abstand zuerst, der
|
||||
fehlerhafte bekommt den Rest zugeteilt. Liegt dieser Rest weiter als
|
||||
`csv:sepliste-abstand-warnung-mm` (500 mm) entfernt, meldet der Export das
|
||||
(`exp-sepliste-abstand`), ohne die Zuordnung zu verwerfen.
|
||||
|
||||
Die Sortierung ist eine strikte Totalordnung (Abstand, dann `lfdnr`, dann
|
||||
Index) — `vl-sort` wirft Elemente weg, die unter der Vergleichsfunktion gleich
|
||||
sind, zwei Paare mit identischem Abstand wuerden sonst zu einem verschmelzen.
|
||||
Getestet in `tests/test_unit.lsp` (`csv:sepliste-paare/*`, zeichnungsfrei).
|
||||
Frueher lief die Zuordnung ueber den kuerzesten Abstand zwischen sepliste-
|
||||
Koordinate und Kopie (`csv:sepliste-paare`). Die sepliste-Koordinaten sind
|
||||
aber teils gespiegelt (bekannter Fall: `x` bei `lfdnr=2`) - das vertauschte
|
||||
real zwei Separatoren von HundM05 `VF_1` in TrackIds und Nachbarn. Passen
|
||||
sepliste und Kette in der Anzahl nicht zusammen, meldet der Export das
|
||||
(`exp-sepliste-ohne-proxy`); die ueberzaehligen Eintraege bleiben ohne `id`.
|
||||
Getestet in `tests/test_unit.lsp` (`csv:sepliste-kette-paare/*`,
|
||||
zeichnungsfrei).
|
||||
|
||||
## Phase 2 (Python): `lib/export_csv.py::process_blocks`
|
||||
|
||||
|
||||
Reference in New Issue
Block a user