Export: ILS-Weiche an Kreisel-Beruehrpunkten + Ein-/Ausschleuselemente an Strecken
- compute_kreisel_touch_switches: erzeugt an jedem Beruehrpunkt zweier Kreisel eine "ILS Weiche" (Kapsel-Geometrie, Position=Beruehrpunkt, statische Box 250x100x30 mit Laengsseite senkrecht zur Kreiselachse, Nachbarn=beide Kreisel) - compute_strecke_kreisel_schleus: an Anfang/Ende jeder Gefaellestrecke bzw. jedes Foerderers (ILS 2.0 Strecke) ein Aus-/Einschleuselement an der Kollisionsposition zum naechsten BBox-Nachbar-Kreisel (Nachbarn=Kreisel+Strecke) - TeileId zaehlt fortlaufend aus der hoechsten vorhandenen ID hoch (Weichen zuerst, dann Schleuselemente) - Warnung (Konsole + neue CSV-Spalte "Warnungen"), wenn eine Strecke mehr als zwei Kreisel-BoundingBoxen beruehrt (erwartet: ein Anfang + ein Ende) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
+90
-4
@@ -15,12 +15,25 @@ K1-K4/Insertpoint leer, Boundingbox = statische Default-Box (WEICHE_BOX_*),
|
||||
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).
|
||||
|
||||
Aufruf:
|
||||
python export_csv.py <export_raw.json> <data_dir> <output.csv>
|
||||
|
||||
CSV-Format:
|
||||
Elementnummer;TeileArt;TeileId;Bezeichnung;Planquadrat;Anzahl;Position;Boundingbox;
|
||||
Insertpoint;K1;K2;K3;K4;Nachbarn;Fehler;Merkmale
|
||||
Insertpoint;K1;K2;K3;K4;Nachbarn;Fehler;Warnungen;Merkmale
|
||||
|
||||
Position und Boundingbox stammen aus der von export.lsp (csv:get-bbox, per
|
||||
vla-getboundingbox) ermittelten Bounding-Box je Block:
|
||||
@@ -90,8 +103,10 @@ from export_neighbors import (
|
||||
compute_sensor_zuordnung,
|
||||
compute_scanner_nearest_separator,
|
||||
compute_kreisel_touch_switches,
|
||||
compute_strecke_kreisel_schleus,
|
||||
SENSOR_TEILEARTEN,
|
||||
WEICHE_TEILEART,
|
||||
GF_VF_TEILEARTEN,
|
||||
)
|
||||
|
||||
BLOCKPATTERNS = load_patterns()
|
||||
@@ -462,6 +477,65 @@ def build_kreisel_weiche_items(items, planquadrat_cfg, start_elem_nr, dbg=None):
|
||||
return elem_nr
|
||||
|
||||
|
||||
def build_strecke_schleus_items(items, planquadrat_cfg, start_elem_nr, dbg=None):
|
||||
"""Haengt fuer jedes Strecken-Ende mit anschliessendem Kreisel eine
|
||||
"ILS Ausschleuselement"- (Anfang) bzw. "ILS Einschleuselement"-Zeile
|
||||
(Ende) an items an (siehe export_neighbors.compute_strecke_kreisel_schleus).
|
||||
|
||||
Muss NACH build_kreisel_weiche_items laufen, damit die TeileId-Zaehlung
|
||||
(max_numeric_teileid) auch die bereits erzeugten Weichen einschliesst.
|
||||
Position = Kollisionsposition Kreisel<->Strecke; Nachbarn = Kreisel-ID +
|
||||
Strecken-ID; Anzahl 1; K1-K4/Insertpoint leer; Boundingbox = die statische,
|
||||
an der Kreiselachse ausgerichtete Default-Box.
|
||||
|
||||
Rueckgabe: fortgeschriebene Elementnummer.
|
||||
"""
|
||||
schleus, warnings = compute_strecke_kreisel_schleus(
|
||||
items, durchmesser_mm=KREISEL_DURCHMESSER_MM, dbg=dbg)
|
||||
|
||||
# Warnungen (>2 Kreisel-BBox-Beruehrungen je Strecke) auf die Strecken-Zeile
|
||||
# schreiben (Spalte "Warnungen") und in die Konsole ausgeben.
|
||||
if warnings:
|
||||
strecke_by_id = {it.get("teileid", ""): it for it in items
|
||||
if it.get("teileart", "") in GF_VF_TEILEARTEN}
|
||||
for sid, text in warnings.items():
|
||||
if sid in strecke_by_id:
|
||||
strecke_by_id[sid]["warnung"] = text
|
||||
print(f"[export_csv] WARNUNG: Strecke {sid} {text}")
|
||||
|
||||
naechste_id = max_numeric_teileid(items)
|
||||
elem_nr = start_elem_nr
|
||||
zaehler = {}
|
||||
for sp in schleus:
|
||||
elem_nr += 1
|
||||
naechste_id += 1
|
||||
teileid = f"{naechste_id:04d}"
|
||||
teileart = sp["teileart"]
|
||||
zaehler[teileart] = zaehler.get(teileart, 0) + 1
|
||||
planquadrat = (compute_planquadrat(sp["x"], sp["y"], planquadrat_cfg)
|
||||
if planquadrat_cfg is not None else "")
|
||||
items.append({
|
||||
"nr": elem_nr,
|
||||
"teileart": teileart,
|
||||
"teileid": teileid,
|
||||
"bezeichnung": f"{teileart} :{zaehler[teileart]}",
|
||||
"planquadrat": planquadrat,
|
||||
"position": f'{sp["x"]:.2f}, {sp["y"]:.2f}, {sp["z"]:.2f}',
|
||||
"boundingbox": f'{sp["dx"]:.2f}, {sp["dy"]:.2f}, {sp["dz"]:.2f}',
|
||||
"insertpoint": "",
|
||||
"k1": "", "k2": "", "k3": "", "k4": "",
|
||||
"nachbarn": ", ".join([sp["kreisel_id"], sp["strecke_id"]]),
|
||||
"fehler": "",
|
||||
"merkmale": {
|
||||
"Erzeugt aus": "Kreisel-Strecke-Kollision",
|
||||
"Kreisel": sp["kreisel_id"],
|
||||
"Strecke": sp["strecke_id"],
|
||||
"Streckenende": sp["ende_label"],
|
||||
},
|
||||
})
|
||||
return elem_nr
|
||||
|
||||
|
||||
def process_blocks(blocks, lookup, dbg=None):
|
||||
# x_origin_mm/y_origin_mm einmalig fuer diesen Exportlauf aufloesen (siehe
|
||||
# export_planquadrat.resolve_origins): automatisch aus den Bloecken, falls
|
||||
@@ -565,6 +639,10 @@ def process_blocks(blocks, lookup, dbg=None):
|
||||
"bezeichnung": f"VarioFoerderer :{vf_count}",
|
||||
"planquadrat": planquadrat_column(block, planquadrat_cfg),
|
||||
"merkmale": build_variofoerderer_merkmale(block),
|
||||
# x/y (Block-Einfuegepunkt = Kettenanfang) fuer die Anfang/Ende-
|
||||
# Bestimmung der Ein-/Ausschleuselemente (compute_strecke_kreisel_schleus)
|
||||
"x": block.get("x", 0.0),
|
||||
"y": block.get("y", 0.0),
|
||||
**bbox_columns(block),
|
||||
})
|
||||
continue
|
||||
@@ -580,6 +658,10 @@ def process_blocks(blocks, lookup, dbg=None):
|
||||
"bezeichnung": f"Gefaellestrecke :{gf_count}",
|
||||
"planquadrat": planquadrat_column(block, planquadrat_cfg),
|
||||
"merkmale": build_variofoerderer_merkmale(block),
|
||||
# x/y (Block-Einfuegepunkt = Kettenanfang) fuer die Anfang/Ende-
|
||||
# Bestimmung der Ein-/Ausschleuselemente (compute_strecke_kreisel_schleus)
|
||||
"x": block.get("x", 0.0),
|
||||
"y": block.get("y", 0.0),
|
||||
**bbox_columns(block),
|
||||
})
|
||||
continue
|
||||
@@ -728,8 +810,11 @@ def process_blocks(blocks, lookup, dbg=None):
|
||||
# Nach der Kollisions-/Nachbarschaftserkennung: an jedem Kreisel-
|
||||
# Beruehrpunkt eine ILS-Weiche anhaengen (eigene Zeilen am Listenende -
|
||||
# sie nehmen an der Nachbarschaftserkennung selbst nicht teil, ihre
|
||||
# Nachbarn sind fest die beiden beruehrenden Kreisel).
|
||||
build_kreisel_weiche_items(items, planquadrat_cfg, elem_nr, dbg=dbg)
|
||||
# Nachbarn sind fest die beiden beruehrenden Kreisel). Danach an jedem
|
||||
# Strecken-Ende mit anschliessendem Kreisel ein Aus-/Einschleuselement -
|
||||
# die TeileId-Zaehlung laeuft ueber beide hinweg weiter (Weichen zuerst).
|
||||
elem_nr = build_kreisel_weiche_items(items, planquadrat_cfg, elem_nr, dbg=dbg)
|
||||
build_strecke_schleus_items(items, planquadrat_cfg, elem_nr, dbg=dbg)
|
||||
|
||||
return items
|
||||
|
||||
@@ -756,6 +841,7 @@ def format_csv_line(item):
|
||||
f';"{csv_quote(item["k4"])}"'
|
||||
f';"{csv_quote(item["nachbarn"])}"'
|
||||
f';"{csv_quote(item["fehler"])}"'
|
||||
f';"{csv_quote(item.get("warnung", ""))}"'
|
||||
f';{merkmale_json}'
|
||||
)
|
||||
|
||||
@@ -812,7 +898,7 @@ def main():
|
||||
print(f"[export_csv] Kollisions-Debuglog geschrieben: {NEIGHBOR_DEBUG_TARGET}")
|
||||
|
||||
header = ("Elementnummer;TeileArt;TeileId;Bezeichnung;Planquadrat;Anzahl;Position;Boundingbox;"
|
||||
"Insertpoint;K1;K2;K3;K4;Nachbarn;Fehler;Merkmale")
|
||||
"Insertpoint;K1;K2;K3;K4;Nachbarn;Fehler;Warnungen;Merkmale")
|
||||
with open(output_csv, "w", encoding="utf-8") as f:
|
||||
f.write(header + "\n")
|
||||
for item in items:
|
||||
|
||||
Reference in New Issue
Block a user