docs: CSV-Export-Doku in doc/csv-export.md ausgelagert und mit Beispiel ergaenzt
Der lange Docstring in lib/export_csv.py wandert nach doc/csv-export.md (inkl. durchgerechnetem Beispiel Kreisel+VarioFoerderer), der Docstring verweist nur noch darauf. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
23d79ec354
commit
c171bc44d6
@@ -145,6 +145,133 @@ Elementnummer;TeileArt;TeileId;Bezeichnung;Planquadrat;Anzahl;Position;Boundingb
|
||||
Insertpoint;K1;K2;K3;K4;Nachbarn;TrackIds;Fehler;Warnungen;Merkmale
|
||||
```
|
||||
|
||||
- **Position** = Mittenkoordinate x, y, z; **Boundingbox** = Ausdehnung
|
||||
(Laenge, Breite, Hoehe) in x, y, z — beide aus `csv:get-bbox`
|
||||
(`vla-getboundingbox`), siehe Phase 1.
|
||||
- **Insertpoint** = KOS-String (24-Zeichen Base64, Position+Rotation als
|
||||
Quaternion, `csv:kos-encode`) des Block-Einfuegepunkts selbst.
|
||||
- **K1-K4** = Positions-Strings der im Block enthaltenen Koordinatensysteme
|
||||
K1..K4 (12-Zeichen Base64, nur Position, `csv:trans-encode`) — nur bei
|
||||
Omniflo Bogen/Weiche/Gerade und VF_n/GF_n (K1/K2 aus AS/ES) vorhanden,
|
||||
sonst leer.
|
||||
- **Fehler** = `"unverbunden"` (keine Partner, aber mindestens einer noetig),
|
||||
`"nur ein Partner"` (ein Partner, aber mindestens zwei noetig) oder leer.
|
||||
Kreisel/Eckrad/Omniflo brauchen mindestens einen Partner,
|
||||
Gefaellestrecke/Foerderer/Strecke-Modul mindestens zwei
|
||||
(`export_neighbors.MIN_PARTNER`).
|
||||
- **Elementnummer** wird NICHT aus der TeileId uebernommen, sondern am Ende
|
||||
neu von 1 an vergeben, nachdem alle Zeilen aufsteigend nach TeileId
|
||||
sortiert wurden (`teileid_sort_key` in `process_blocks`). Ohne geloeschte
|
||||
Elemente stimmen Elementnummer und TeileId dadurch ueberein; geloeschte
|
||||
Elemente hinterlassen Luecken nur in der TeileId-Folge. Zeilen ohne
|
||||
numerische TeileId (Omniflo-Sum-Zeile, SEP-/SCN-Fallback-IDs ohne
|
||||
ID-Attribut) behalten stabil ihre bisherige Reihenfolge und stehen danach.
|
||||
|
||||
### Beispiel: Kreisel mit 2 Separatoren + VarioFoerderer mit 2 Separatoren
|
||||
|
||||
Ausgangslage in der Zeichnung: ein kleiner Kreisel (`KREISEL_1`, ID `0010`)
|
||||
mit zwei frei aufgesetzten Separatoren auf seiner Bahn, daran andockend ein
|
||||
`VF_1` mit einer Kette AS -> Separator -> Separator -> ES (IDs `0021`-`0024`).
|
||||
|
||||
**Ausschnitt `export_raw.json`** (von `csv:collect-export-blocks` /
|
||||
`csv:block-to-json` geschrieben, hier gekuerzt auf die fuer dieses Beispiel
|
||||
relevanten Felder):
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"block_name": "KREISEL_1",
|
||||
"layer": "ILS_Kreisel",
|
||||
"handle": "2A1",
|
||||
"x": 10000.0, "y": 5000.0, "z": 0.0, "rotation": 0.0,
|
||||
"attribs": {"ID": "0010", "DREHRICHTUNG": "UZS", "ABSTAND": "800"},
|
||||
"insertpoint": "AAB3QAAATkAAAAAA...",
|
||||
"bbox": {"min": [9200.0, 4200.0, 0.0], "max": [10800.0, 5800.0, 0.0]}
|
||||
},
|
||||
{
|
||||
"block_name": "Separator_SP_300mm",
|
||||
"layer": "ILS_Sensor",
|
||||
"handle": "2A5",
|
||||
"x": 10800.0, "y": 5000.0, "z": 0.0, "rotation": 0.0,
|
||||
"attribs": {"ID": "0011"},
|
||||
"insertpoint": "AAD4QAAATkAAAAAA..."
|
||||
},
|
||||
{
|
||||
"block_name": "Separator_SP_300mm",
|
||||
"layer": "ILS_Sensor",
|
||||
"handle": "2A9",
|
||||
"x": 10000.0, "y": 5800.0, "z": 0.0, "rotation": 90.0,
|
||||
"attribs": {"ID": "0012"},
|
||||
"insertpoint": "AAB3QAAAxEAAAAAA..."
|
||||
},
|
||||
{
|
||||
"block_name": "VF_1",
|
||||
"layer": "ILS_Foerderer",
|
||||
"handle": "2B0",
|
||||
"x": 10800.0, "y": 5000.0, "z": 0.0, "rotation": 0.0,
|
||||
"attribs": {"ID": "0021", "Bezeichnung": ""},
|
||||
"insertpoint": "AAD4QAAATkAAAAAA...",
|
||||
"k1": "AAD4QAAATkAAAAAA...",
|
||||
"k2": "AAAAQwAATkAAAAAA...",
|
||||
"bbox": {"min": [10800.0, 4850.0, 0.0], "max": [13000.0, 5150.0, 300.0]},
|
||||
"sepliste": [
|
||||
["AS", 1, 10800.0, 5000.0],
|
||||
["SEP", 2, 11600.0, 5000.0],
|
||||
["SEP", 3, 12300.0, 5000.0],
|
||||
["ES", 4, 13000.0, 5000.0]
|
||||
]
|
||||
},
|
||||
{
|
||||
"block_name": "Separator_SP_300mm",
|
||||
"layer": "ILS_Sensor",
|
||||
"handle": "2B4",
|
||||
"x": 11600.0, "y": 5000.0, "z": 0.0, "rotation": 0.0,
|
||||
"attribs": {"ID": "0022"}
|
||||
},
|
||||
{
|
||||
"block_name": "Separator_SP_300mm",
|
||||
"layer": "ILS_Sensor",
|
||||
"handle": "2B8",
|
||||
"x": 12300.0, "y": 5000.0, "z": 0.0, "rotation": 0.0,
|
||||
"attribs": {"ID": "0023"}
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
Die beiden Separatoren `0022`/`0023` sind hier die ECHTEN, top-level
|
||||
exportierten Separator-Bloecke (identisch mit den `SEP`-Eintraegen der
|
||||
`sepliste` von `VF_1` — siehe "Die `sepliste`" oben: kein doppeltes Konzept,
|
||||
zwei Blickwinkel auf dieselben Symbole).
|
||||
|
||||
**Resultierende CSV-Zeilen** (Header + betroffene Zeilen, Spalten
|
||||
`Insertpoint`/`K3`/`K4`/`Merkmale` fuer die Lesbarkeit gekuerzt):
|
||||
|
||||
```text
|
||||
Elementnummer;TeileArt;TeileId;Bezeichnung;Planquadrat;Anzahl;Position;Boundingbox;Insertpoint;K1;K2;K3;K4;Nachbarn;TrackIds;Fehler;Warnungen;Merkmale
|
||||
1;"ILS 2.0 Kreisel";"0010";"Kreisel :1";"B/3";1;"10000.0, 5000.0, 0.0";"1600.0, 1600.0, 0.0";"...";"";"";"";"";"0011, 0012, 0021";"0011, 0012, 0021, 0022, 0023, 0024";"";"";{"Abstand":"800"}
|
||||
2;"ILS 2.0 Separator";"0011";"Separator :1";"B/3";1;"10800.0, 5000.0, 0.0";"210.0, 150.0, 14.0";"...";"";"";"";"";"0010, 0012";"";"";"";{"Zuordnung":"0010"}
|
||||
3;"ILS 2.0 Separator";"0012";"Separator :2";"B/3";1;"10000.0, 5800.0, 0.0";"150.0, 210.0, 14.0";"...";"";"";"";"";"0011, 0021";"";"";"";{"Zuordnung":"0010"}
|
||||
4;"ILS 2.0 VarioFoerderer";"0021";"VarioFoerderer :1";"B/3";1;"11900.0, 5000.0, 0.0";"2200.0, 300.0, 300.0";"...";"...";"...";"";"";"0010, 0024";"0021, 0022, 0023, 0024";"";"";{}
|
||||
5;"ILS 2.0 Separator";"0022";"Separator :3";"C/4";1;"11600.0, 5000.0, 0.0";"210.0, 150.0, 14.0";"...";"";"";"";"";"";"";"";"";{"Zuordnung":"0021"}
|
||||
6;"ILS 2.0 Separator";"0023";"Separator :4";"C/4";1;"12300.0, 5000.0, 0.0";"210.0, 150.0, 14.0";"...";"";"";"";"";"";"";"";"";{"Zuordnung":"0021"}
|
||||
```
|
||||
|
||||
Zu beachten:
|
||||
|
||||
- Der Kreisel (`0010`) traegt in `TrackIds` den KOMPLETTEN Umlauf inkl. der
|
||||
VF-Kettenenden (`0021`=AS, `0024`=ES, aus `compute_kreisel_umlauf`), waehrend
|
||||
seine `Nachbarn`-Spalte nur die unmittelbaren Umlauf-Nachbarn zeigt.
|
||||
- `VF_1` (`0021`) bekommt seine eigene `TrackIds`-Spalte
|
||||
(`write_separatorliste_merkmale`) aus der `sepliste`: AS -> SEP -> SEP -> ES
|
||||
in Baureihenfolge, unabhaengig vom Kreisel-Umlauf.
|
||||
- Die AS/ES-Enden (`0021`=AS, `0024`=ES) sind hier synthetische Zeilen aus
|
||||
`build_strecke_schleus_items` (Zeilentyp "ILS Ausschleuselement"/
|
||||
"ILS Einschleuselement") — in diesem gekuerzten Beispiel nicht einzeln
|
||||
aufgefuehrt, aber ihre TeileIds tauchen in `TrackIds` beider Seiten auf.
|
||||
- Die Separatoren 3 und 5 (`0012`/`0022`) unterscheiden sich nur durch ihre
|
||||
`Zuordnung`: `0012` haengt am Kreisel, `0022`/`0023` an der VF-Kette — beide
|
||||
Faelle laufen ueber denselben `pattern_separator`-Blocktyp.
|
||||
|
||||
### 1. Blöcke klassifizieren
|
||||
|
||||
Eine grosse Schleife über alle rohen JSON-Blöcke ordnet jeden Block anhand
|
||||
|
||||
Reference in New Issue
Block a user