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
+8
-98
@@ -3,111 +3,21 @@
|
||||
"""
|
||||
export_csv.py - Erzeugt eine einfache Item-Liste als CSV.
|
||||
|
||||
Fuer Omniflo-Elemente (Bogen/Weiche/Gerade) wird am Ende zusaetzlich eine
|
||||
"Omniflo Sum"-Zeile mit Anzahl Boegen/Weichentypen und Gesamtlaenge AP110/AP60
|
||||
angehaengt (siehe build_omni_sum_merkmale).
|
||||
|
||||
Nach der Kollisions-/Nachbarschaftserkennung wird ausserdem an jedem
|
||||
Beruehrpunkt zweier Kreisel eine "ILS Weiche"-Zeile angehaengt (siehe
|
||||
build_kreisel_weiche_items / export_neighbors.compute_kreisel_touch_switches):
|
||||
Anzahl 1, Position = Beruehrkoordinaten, Nachbarn = die beiden Kreisel-IDs,
|
||||
K1-K4/Insertpoint leer, Boundingbox = feste Element-Box (element_box_mm,
|
||||
cfg/export.cfg [Boundingbox]),
|
||||
mit der Laengsseite senkrecht zur Achse des beruehrenden Kreisels; die TeileId
|
||||
zaehlt aus der hoechsten bereits vergebenen numerischen ID hoch.
|
||||
|
||||
Anschliessend (TeileId-Zaehlung laeuft ueber die Weichen hinweg weiter) wird
|
||||
an jedem Ende einer Gefaellestrecke/eines Foerderers, an dem ein Kreisel
|
||||
anschliesst, ein Aus- (Anfang) bzw. Einschleuselement (Ende) an der Kollisions-
|
||||
position Kreisel<->Strecke angehaengt (siehe build_strecke_schleus_items /
|
||||
export_neighbors.compute_strecke_kreisel_schleus) - Format wie die Weiche,
|
||||
Nachbarn = Kreisel-ID + Strecken-ID. Zugeordnet wird je Streckenende der
|
||||
naechstgelegene ihrer BBox-Kreisel-Nachbarn.
|
||||
|
||||
Warnungen = Spalte fuer Auffaelligkeiten. Aktuell: eine Strecke sollte genau
|
||||
zwei Kreisel (Anfang + Ende) beruehren - beruehrt ihre (in x/y gepruefte)
|
||||
Bounding-Box mehr, steht hier ein Hinweis und es wird zusaetzlich eine
|
||||
Konsolen-WARNUNG ausgegeben (mit exakten 3D-BBoxen sollte das nicht auftreten).
|
||||
Scanner-Zeilen bekommen dieselbe Spalte fuer strittige Distanz-Zuordnungen:
|
||||
liegt ein Scanner ausserhalb jeder Kreisel-/Streckengruppen-/Gefaellestrecke-
|
||||
Boundingbox und ist der Abstand zum naechsten und zweitnaechsten Carrier fast
|
||||
gleich gross, schreibt Lisp/count_sep_scan.lsp (cs-zuordnung-lauf, vor dem
|
||||
Export automatisch aufgerufen) einen Warnungstext mit den IDs beider
|
||||
Kandidaten in das "warnung"-Feld des Scanner-Blocks im Roh-JSON (siehe
|
||||
csv:block-to-json in export.lsp) - hier unveraendert uebernommen.
|
||||
|
||||
Aufruf:
|
||||
python export_csv.py <export_raw.json> <data_dir> <output.csv>
|
||||
|
||||
CSV-Format:
|
||||
CSV-Format (Header):
|
||||
Elementnummer;TeileArt;TeileId;Bezeichnung;Planquadrat;Anzahl;Position;Boundingbox;
|
||||
Insertpoint;K1;K2;K3;K4;Nachbarn;TrackIds;Fehler;Warnungen;Merkmale
|
||||
|
||||
Position und Boundingbox stammen aus der von export.lsp (csv:get-bbox, per
|
||||
vla-getboundingbox) ermittelten Bounding-Box je Block:
|
||||
Position = Mittenkoordinate x, y, z
|
||||
Boundingbox = Ausdehnung (Laenge, Breite, Hoehe) in x, y, z
|
||||
Insertpoint = KOS-String (24-Zeichen Base64, Position+Rotation als Quaternion,
|
||||
siehe csv:kos-encode in export.lsp) des Block-Einfuegepunkts selbst.
|
||||
K1-K4 = Positions-Strings der im Block enthaltenen Koordinatensysteme K1..K4
|
||||
(12-Zeichen Base64, nur Position ohne Rotation, siehe csv:trans-encode;
|
||||
nur bei Omniflo Bogen/Weiche/Gerade vorhanden, sonst leer).
|
||||
Planquadrat wird aus der x/y-Koordinate des Blocks berechnet, siehe
|
||||
export_planquadrat.py ([Planquadrate] in cfg/export.cfg).
|
||||
Nachbarn = kommaseparierte TeileId-Liste ueberschneidender Elemente (Bounding-
|
||||
Box-Ueberschneidung in der x/y-Ebene, reines Python ohne externe Abhaengigkeit,
|
||||
siehe export_neighbors.py). Geprueft wird NICHT global ueber alle Elemente,
|
||||
sondern in drei getrennten Gruppen: 1) Kreisel/Eckrad gegen Kreisel/Eckrad,
|
||||
2) Kreisel/Eckrad gegen Gefaellestrecke/Foerderer/Strecke-Modul (diese drei
|
||||
nicht gegeneinander), 3) Omniflo-Elemente gegen Omniflo-Elemente. Fuer die
|
||||
Omniflo-Gruppe liefert eine shapely-STRtree-Broad-Phase zunaechst alle Paare
|
||||
mit ueberschneidenden Bounding-Boxen; anschliessend gelten sie nur dann als
|
||||
benachbart, wenn sich ihre Anschluss-Koordinatensysteme K1-K4 tatsaechlich
|
||||
beruehren (ein K-Punkt naeher als omniflo_ks_toleranz_mm, Default 10mm) -
|
||||
das trennt bloss ueberlappende BBoxen von echten Anschluessen (Geraden fuehren
|
||||
dafuer beim Export synthetisierte K1/K2, siehe csv:gerade-k-kos-strings).
|
||||
Toleranzen und (Fallback-)Rastergroesse konfigurierbar ueber [Nachbarschaft]
|
||||
in cfg/export.cfg.
|
||||
TrackIds = kommaseparierte TeileId-Liste der Separatoren/BTMT-Beladung/
|
||||
BTMT-Entladung (und bei einem Kreisel zusaetzlich der AS/ES-Streckenenden
|
||||
und Kreisel-Kreisel-Weichen) entlang einer VF_n/GF_n-Strecke bzw. rund um
|
||||
einen Kreisel, in Baureihenfolge (Strecke) bzw. Umlaufreihenfolge ab Winkel
|
||||
0 Grad (Kreisel, siehe export_neighbors.compute_kreisel_umlauf) - nur bei
|
||||
VF_n/GF_n/Kreisel vorhanden, sonst leer. Siehe write_separatorliste_
|
||||
merkmale/write_kreisel_separatorliste_merkmale.
|
||||
Fehler = "unverbunden" (keine Partner, aber mindestens einer noetig),
|
||||
"nur ein Partner" (ein Partner, aber mindestens zwei noetig) oder leer
|
||||
(Mindestanzahl erreicht bzw. TeileArt wird nicht geprueft). Kreisel/Eckrad/
|
||||
Omniflo-Elemente brauchen mindestens einen Partner, Gefaellestrecke/
|
||||
Foerderer/Strecke-Modul mindestens zwei (siehe export_neighbors.py
|
||||
MIN_PARTNER). Ein Kreisel wird dabei NICHT als eine, sondern als zwei
|
||||
BBoxen (links/rechts, geteilt entlang der Achse durch Antriebs-/
|
||||
Spannstation, siehe export_neighbors.kreisel_half_bboxes) gegen
|
||||
Gefaellestrecke/Foerderer getestet - deren "Nachbarn"-Spalte zeigt darum
|
||||
"<KreiselTeileId>-L" bzw. "-R" statt nur der Kreisel-TeileId.
|
||||
Separator/Scanner-Zeilen bekommen zusaetzlich ein berechnetes "Zuordnung"-
|
||||
Merkmal (Gefaellestrecke > Foerderer > Kreiselhaelfte, per BBox-Ueber-
|
||||
schneidung - siehe export_neighbors.compute_sensor_zuordnung), das die
|
||||
ATTRIB-Zuordnung (falls das Attribut ZUORDNUNG in der Zeichnung von Hand
|
||||
gesetzt wurde) ersetzt, sofern ein Treffer gefunden wird. Scanner-Zeilen
|
||||
bekommen zusaetzlich ein "Naechster Separator"-Merkmal (raeumlich naechst-
|
||||
gelegener Separator, euklidischer Abstand der BBox-Mittelpunkte - eigene,
|
||||
von der Zuordnung unabhaengige Suche, siehe export_neighbors.compute_
|
||||
scanner_nearest_separator).
|
||||
Position, Boundingbox, Planquadrat, Nachbarn und Fehler sind nur fuer
|
||||
EXPORTCSV vorhanden (nicht EXPORTSIVAS) - siehe csv:run-export. Insertpoint/
|
||||
K1-K4 stehen zwar in export_raw.json fuer jeden Export zur Verfuegung (siehe
|
||||
csv:block-to-json), werden aber ebenfalls nur von diesem Skript (EXPORTCSV)
|
||||
als CSV-Spalten ausgegeben.
|
||||
Beispielzeile (Separator, TeileId 0011 an Kreisel 0010):
|
||||
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"}
|
||||
|
||||
Reihenfolge/Elementnummer: die Zeilen werden am Ende aufsteigend nach
|
||||
TeileId sortiert (numerische IDs) und die Elementnummer (erste Spalte)
|
||||
danach neu von 1 an vergeben (siehe teileid_sort_key in process_blocks) -
|
||||
wurde kein Element geloescht, stimmen Elementnummer und TeileId dadurch
|
||||
ueberein, geloeschte Elemente hinterlassen Luecken 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.
|
||||
Fuer die vollstaendige Herleitung jeder Spalte (Nachbarn/TrackIds/sepliste/
|
||||
Fehler/Warnungen, inkl. eines durchgerechneten Beispiels Kreisel+VarioFoerderer
|
||||
von export_raw.json bis zur fertigen CSV-Zeile) siehe doc/csv-export.md.
|
||||
"""
|
||||
|
||||
import json
|
||||
|
||||
Reference in New Issue
Block a user