[ADD] Nachbau ILS-3.0-Showroom: tests/testdata/showroom_ils.json aus Showroom_ILS_3_0.dxf (6 Kreisel, 11 Gefaellestrecken, Separatoren/Scanner; Hoehen noch Platzhalter), Treiber tests/test_showroom_ils.lsp (TEST_SHOWROOM_ILS, Menue Tests -> ILS 3.0 Showroom), in alltests.json bis zu den Hoehen deaktiviert; [ADD] dxf_scan_components.py: --flach (waagrechte Staustrecken mit AS an genau einem Ende als GF), --kreisel-achse (Kreisel ohne AN8/SP8, z.B. Schleifen mit Weichenboegen), zerstueckelte Staustrecken-Linien werden vereint, ES am unteren Ende wird erkannt und verbraucht, AS/ES-Seite ohne Seitenangabe im Namen aus der Lage zur Fahrtrichtung, Kurznamen AE-*/EE-*; [FIX] Kreisel-Paarung: zwei Kreisel auf derselben Achse wurden ueber die Luecke gepaart (800 + 12832 statt 9033 + 3000) - Tausch-Nachbesserung auf minimale Abstandssumme; [CHANGE] test_dematic_arvato.lsp: Lauf als dematic_arvato:bau-datei herausgeloest (vom Showroom-Treiber mitgenutzt); [ADD] Tests in test_dxf_scan_gf.py

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-07 15:00:45 +02:00
parent f1583d2d41
commit 4d0d689815
9 changed files with 824 additions and 47 deletions
+94
View File
@@ -166,3 +166,97 @@ def test_ohne_as_defaults_und_hinweis():
assert eintraege[0]["hz_grad"] == 0.0
assert eintraege[0]["as_seite"] == dsc.DEFAULT_SEITE
assert any("ohne Ausschleuselement" in h for h in hinweise)
# --- Showroom_ILS_3_0.dxf: flacher 2D-Plan, Werte dort gemessen -------------
def _station(x, y):
return {"x": x, "y": y}
def test_kreisel_paare_zwei_kreisel_auf_einer_achse():
# x=26998: AN8 y=3466 / SP8 y=12499 und AN8 y=13299 / SP8 y=16299. Die
# Luecke SP8(12499)-AN8(13299) = 800 ist das kuerzeste Paar - ohne
# Tausch-Nachbesserung kamen 800 + 12833 statt 9033 + 3000 heraus.
an = [_station(26998.0, 3466.4), _station(26998.0, 13298.9)]
sp = [_station(26998.0, 16298.9), _station(26998.0, 12498.9)]
paare, an_rest, sp_rest = dsc.kreisel_paare_bilden(an, sp)
assert an_rest == [] and sp_rest == []
abstaende = sorted(round(p[2], 1) for p in paare)
assert abstaende == [3000.0, 9032.5]
def test_zerstueckelte_linie_wird_vereint():
# GF bei x=34006 in vier Stuecken, das Separatorstueck 0,3 mm daneben
stuecke = [
_linie((34005.93, 13893.90, 0.0), (34005.93, 14193.90, 0.0)),
_linie((34005.93, 15043.90, 0.0), (34005.93, 15593.90, 0.0)),
_linie((34006.24, 14744.31, 0.0), (34006.24, 15044.31, 0.0)),
_linie((34005.93, 14193.90, 0.0), (34005.93, 14743.90, 0.0)),
]
vereint = dsc.linien_zusammenfassen(stuecke)
assert len(vereint) == 1
ys = sorted([vereint[0]["a"][1], vereint[0]["b"][1]])
assert ys == pytest.approx([13893.90, 15593.90], abs=0.01)
def test_parallele_nachbarlinie_wird_nicht_vereint():
linien = [_linie((0.0, 0.0, 0.0), (0.0, 1000.0, 0.0)),
_linie((800.0, 1000.0, 0.0), (800.0, 2000.0, 0.0))]
assert len(dsc.linien_zusammenfassen(linien)) == 2
def _kreisel_d():
# Schleife oben (Kette unten y=15898.9), Radmitten per --kreisel-achse
return {"id": "K_D", "a": (27797.93, 16298.9), "u": (1.0, 0.0),
"laenge": 8908.0, "r": 400.0, "z_anwender": None}
def _kreisel_e():
# Schleife Mitte (Kette oben y=13493.9)
return {"id": "K_E", "a": (28772.93, 13093.9), "u": (1.0, 0.0),
"laenge": 6533.0, "r": 400.0, "z_anwender": None}
def test_flacher_plan_richtung_und_seiten_aus_as_es():
# Waagrechte Linie; AE-D sitzt 305 mm VOR dem oberen Ende auf der
# Kreisel-Kette, 180 mm links der Fahrtrichtung (Fahrt -y, links = +x).
# EE-R am unteren Ende 212 mm rechts davon.
linie = _linie((30455.93, 13893.9, 0.0), (30455.93, 15593.9, 0.0))
ae = {"familie": "schleuselement", "block": "AE-D",
"x": 30636.27, "y": 15898.9, "z": 0.0, "rot": 270.0}
ee = {"familie": "schleuselement", "block": "EE-R",
"x": 30243.76, "y": 13493.9, "z": 0.0, "rot": 90.0}
eintraege, belegt, _ = dsc.gf_eintraege_aus_linien(
[linie], [ae], [_kreisel_d(), _kreisel_e()], es_liste=[ee], flach=True)
assert len(eintraege) == 1
gf = eintraege[0]
assert gf["hz_grad"] == 270.0
assert gf["start_mm"][:2] == [30455.93, 15898.9]
assert gf["deltaL_mm"] == pytest.approx(2405.0, abs=0.01)
assert (gf["as_seite"], gf["es_seite"]) == ("links", "rechts")
assert (gf["kreisel_start"], gf["kreisel_ende"]) == ("K_D", "K_E")
assert belegt == {id(ae), id(ee)}
def test_flacher_plan_ohne_flach_schalter_keine_gf():
linie = _linie((30455.93, 13893.9, 0.0), (30455.93, 15593.9, 0.0))
ae = {"familie": "schleuselement", "block": "AE-D",
"x": 30636.27, "y": 15898.9, "z": 0.0, "rot": 270.0}
eintraege, _, _ = dsc.gf_eintraege_aus_linien([linie], [ae])
assert eintraege == []
def test_flacher_plan_ohne_as_keine_gf():
# Staulinie am Kreisel B (x=36348) - kein AS an einem Ende
linie = _linie((36347.6, 11313.9, 0.0), (36347.6, 14913.9, 0.0))
eintraege, _, hinweise = dsc.gf_eintraege_aus_linien([linie], [], flach=True)
assert eintraege == []
assert any("waagrechte" in h for h in hinweise)
def test_kurznamen_ae_ee():
assert dsc.familie_von("AE-D") == "schleuselement"
assert dsc.familie_von("EE-R") == "schleuselement"
assert dsc.mappe_block("AE-D")[0].startswith("AS_Element_90_")
assert dsc.mappe_block("EE-R")[0].startswith("ES_Element_90_")