Weichen werden bei der Kollisionspunkten zweier Kreisel erzeugt und im csv Export mit heraus geschrieben

This commit is contained in:
2026-08-04 12:55:31 +02:00
parent 49652b2744
commit 6648156d12
2 changed files with 281 additions and 0 deletions
+76
View File
@@ -7,6 +7,14 @@ 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 = 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.
Aufruf:
python export_csv.py <export_raw.json> <data_dir> <output.csv>
@@ -81,7 +89,9 @@ from export_neighbors import (
compute_neighbor_errors,
compute_sensor_zuordnung,
compute_scanner_nearest_separator,
compute_kreisel_touch_switches,
SENSOR_TEILEARTEN,
WEICHE_TEILEART,
)
BLOCKPATTERNS = load_patterns()
@@ -392,6 +402,66 @@ SKIP_BLOCKS = set(BLOCKPATTERNS.get("pattern_ks_subblocks", ["K1", "K2", "K3", "
# Bloecke verarbeiten (einfache Liste, keine Summierung)
# ---------------------------------------------------------------------------
def max_numeric_teileid(items):
"""Hoechste rein-numerische TeileId in items (z.B. "0008" -> 8). Nicht-
numerische IDs (SEP-0001, autogenerated_of_json, ...) werden ignoriert.
0, wenn keine numerische ID existiert. Basis fuer die fortlaufende
Nummerierung der am Kreisel-Beruehrpunkt erzeugten ILS-Weichen (siehe
'Zaehle die Id aus der letzten enthaltenen ID hoch')."""
max_id = 0
for item in items:
tid = str(item.get("teileid", "")).strip()
if tid.isdigit():
max_id = max(max_id, int(tid))
return max_id
def build_kreisel_weiche_items(items, planquadrat_cfg, start_elem_nr, dbg=None):
"""Haengt fuer jeden Kreisel-Beruehrpunkt eine "ILS Weiche"-Zeile an items
an (siehe export_neighbors.compute_kreisel_touch_switches).
TeileId zaehlt aus der hoechsten bereits enthaltenen numerischen ID hoch
(max_numeric_teileid), 4-stellig aufgefuellt wie die Kreisel-IDs. Anzahl
ist wie bei allen Zeilen 1; Nachbarn = die beiden Kreisel-IDs; K1-K4 und
Insertpoint bleiben leer; Position = Beruehrkoordinaten; Boundingbox = die
statische, an der Kreiselachse ausgerichtete Default-Box (WEICHE_BOX_*).
Rueckgabe: fortgeschriebene Elementnummer (start_elem_nr + Anzahl Weichen).
"""
switches = compute_kreisel_touch_switches(
items, NEIGHBOR_TOLERANCE_MM, durchmesser_mm=KREISEL_DURCHMESSER_MM, dbg=dbg)
naechste_id = max_numeric_teileid(items)
elem_nr = start_elem_nr
for n, sw in enumerate(switches, start=1):
elem_nr += 1
naechste_id += 1
teileid = f"{naechste_id:04d}"
planquadrat = (compute_planquadrat(sw["x"], sw["y"], planquadrat_cfg)
if planquadrat_cfg is not None else "")
items.append({
"nr": elem_nr,
"teileart": WEICHE_TEILEART,
"teileid": teileid,
"bezeichnung": f"ILS Weiche :{n}",
"planquadrat": planquadrat,
"position": f'{sw["x"]:.2f}, {sw["y"]:.2f}, {sw["z"]:.2f}',
"boundingbox": f'{sw["dx"]:.2f}, {sw["dy"]:.2f}, {sw["dz"]:.2f}',
"insertpoint": "",
"k1": "", "k2": "", "k3": "", "k4": "",
"nachbarn": ", ".join(sw["nachbarn"]),
"fehler": "",
"merkmale": {
"Erzeugt aus": "Kreisel-Beruehrpunkt",
"Kreisel A": sw["nachbarn"][0],
"Kreisel B": sw["nachbarn"][1],
"Achse von Kreisel": sw["achse_von"],
"Beruehrung": sw["beruehrung"],
},
})
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
@@ -655,6 +725,12 @@ def process_blocks(blocks, lookup, dbg=None):
if item.get("teileart", "") == "ILS 2.0 Scanner" and separator_id:
item["merkmale"]["Naechster Separator"] = separator_id
# 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)
return items