[FIX] Export: ZUORDNUNG-Attribut vor BBox-Suche bei Separator/Scanner
Separatoren an einer Kreisel-Kreisel-Weiche ragen mit Toleranz in die Box beider Kreisel; compute_kreisel_umlauf/compute_sensor_zuordnung nahmen den ersten Treffer (test_system: Separator 0018 an Kreisel 0006 statt 0005, 0015 an 0003 statt 0002). Das ZUORDNUNG-Attribut aus count_sep_scan hat jetzt Vorrang, sofern es einen vorhandenen Carrier nennt; die Haelfte L/R wird weiter per BBox bestimmt, ohne Attribut bleibt die BBox-Suche. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+33
-4
@@ -784,6 +784,9 @@ def compute_sensor_zuordnung(items, tolerance_mm, kreisel_durchmesser_mm=800.0,
|
||||
gf_entries = []
|
||||
vf_entries = []
|
||||
kreisel_entries = []
|
||||
# TeileIds aller Carrier (GF/VF/Kreisel) - fuer den Vorrang des
|
||||
# ZUORDNUNG-Attributs ("_zuordnung_attr") vor der BBox-Suche.
|
||||
carrier_ids = set()
|
||||
|
||||
for item in items:
|
||||
bbox = item.get("_bbox")
|
||||
@@ -793,9 +796,12 @@ def compute_sensor_zuordnung(items, tolerance_mm, kreisel_durchmesser_mm=800.0,
|
||||
teileid = item.get("teileid", "")
|
||||
if teileart == "ILS 2.0 Gefaellestrecke":
|
||||
gf_entries.append((teileid, _bounds(bbox, half_tol)))
|
||||
carrier_ids.add(teileid)
|
||||
elif teileart in ("ILS 2.0 Strecke", "ILS 2.0 Strecke - Modul"):
|
||||
vf_entries.append((teileid, _bounds(bbox, half_tol)))
|
||||
carrier_ids.add(teileid)
|
||||
elif teileart == KREISEL_SPLIT_TEILEART:
|
||||
carrier_ids.add(teileid)
|
||||
bbox_links, bbox_rechts = kreisel_half_bboxes(item, kreisel_durchmesser_mm)
|
||||
kreisel_entries.append((f"{teileid}-L", _bounds(bbox_links, half_tol)))
|
||||
kreisel_entries.append((f"{teileid}-R", _bounds(bbox_rechts, half_tol)))
|
||||
@@ -824,10 +830,22 @@ def compute_sensor_zuordnung(items, tolerance_mm, kreisel_durchmesser_mm=800.0,
|
||||
result.append("")
|
||||
continue
|
||||
bounds = _bounds(bbox, half_tol)
|
||||
treffer = (_find(bounds, gf_entries)
|
||||
or _find(bounds, vf_entries)
|
||||
or _find(bounds, kreisel_entries)
|
||||
or "nicht zugeordnet")
|
||||
# Vorrang: ZUORDNUNG aus der Zeichnung (cs-zuordnung-lauf), sofern sie
|
||||
# einen vorhandenen Carrier nennt. Die BBox-Suche nimmt sonst den
|
||||
# ERSTEN Treffer - an einer Kreisel-Kreisel-Weiche ragt ein Separator
|
||||
# mit Toleranz in beide Kreisel und landete beim falschen (realer
|
||||
# Fall test_system, Separator 0018: Attribut 0005, BBox -> 0006).
|
||||
# Bei einem Kreisel wird nur noch die Haelfte (L/R) per BBox bestimmt.
|
||||
attr = (item.get("_zuordnung_attr") or "").strip()
|
||||
if attr in carrier_ids:
|
||||
haelften = [e for e in kreisel_entries
|
||||
if e[0] in (f"{attr}-L", f"{attr}-R")]
|
||||
treffer = (_find(bounds, haelften) if haelften else None) or attr
|
||||
else:
|
||||
treffer = (_find(bounds, gf_entries)
|
||||
or _find(bounds, vf_entries)
|
||||
or _find(bounds, kreisel_entries)
|
||||
or "nicht zugeordnet")
|
||||
if dbg:
|
||||
dbg(f" {item.get('teileart', '')} {item.get('teileid', '')!r} "
|
||||
f"bounds={_fmt_bounds(bounds)} -> {treffer!r}")
|
||||
@@ -1383,7 +1401,18 @@ def compute_kreisel_umlauf(items, tolerance_mm, durchmesser_mm=800.0,
|
||||
continue
|
||||
bounds = _bounds(bbox, half_tol)
|
||||
matched_tid = None
|
||||
# Vorrang: ZUORDNUNG-Attribut des Separators/Scanners, wenn es einen
|
||||
# Kreisel nennt (siehe compute_sensor_zuordnung) - die BBox-Suche
|
||||
# unten nimmt den ERSTEN ueberlappenden Kreisel und verwechselt an
|
||||
# einer Kreisel-Kreisel-Weiche die beiden Kreisel.
|
||||
attr = (item.get("_zuordnung_attr") or "").strip()
|
||||
if attr in kreisel_bounds:
|
||||
punkte_je_kreisel[attr].append(
|
||||
(teileid, bbox.get("cx", 0.0), bbox.get("cy", 0.0)))
|
||||
matched_tid = attr
|
||||
for tid, kb in kreisel_bounds.items():
|
||||
if matched_tid is not None:
|
||||
break
|
||||
if _overlaps(bounds, kb):
|
||||
punkte_je_kreisel[tid].append(
|
||||
(teileid, bbox.get("cx", 0.0), bbox.get("cy", 0.0)))
|
||||
|
||||
Reference in New Issue
Block a user