lsa-planer
LSA-Planer Professional – Planungssoftware für Lichtsignalanlagen nach RiLSA 2015 und § 45 StVO. EUPL-1.2.
/ tests domain kreuzenUndLaengslauf.test.ts
| 1 | import { describe, expect, it } from 'vitest'; |
| 2 | import { |
| 3 | REGELBREITE, |
| 4 | konfliktbereich, |
| 5 | vermesseWege, |
| 6 | type Fahrlinie, |
| 7 | } from '@/domain/geometrie/vermessung'; |
| 8 | |
| 9 | /** |
| 10 | * Radweg laengs der Fahrbahn. Haltlinie bei x = -10, Verlauf nach Osten. |
| 11 | */ |
| 12 | const radweg: Fahrlinie = { |
| 13 | id: 'rad', |
| 14 | punkte: [ |
| 15 | { x: -10, y: 0 }, |
| 16 | { x: 50, y: 0 }, |
| 17 | ], |
| 18 | breite: REGELBREITE.rad, |
| 19 | }; |
| 20 | |
| 21 | /** |
| 22 | * Rechtsabbiegender Kfz-Strom: quert den Radweg bei x = 9,43 und faehrt danach |
| 23 | * ueber 30 m unmittelbar daneben weiter (Achsabstand 0,3 m bei einem |
| 24 | * Grenzabstand von (1,6+3,25)/2 = 2,425 m - die Korridore ueberdecken sich). |
| 25 | */ |
| 26 | const abbieger: Fahrlinie = { |
| 27 | id: 'kfz', |
| 28 | punkte: [ |
| 29 | { x: 0, y: -5 }, |
| 30 | { x: 10, y: 0.3 }, |
| 31 | { x: 40, y: 0.3 }, |
| 32 | ], |
| 33 | breite: REGELBREITE.kfz, |
| 34 | }; |
| 35 | |
| 36 | describe('Konfliktbereich bei Kreuzen und anschliessendem Laengslauf', () => { |
| 37 | it('fuehrt den Raeumweg des Radverkehrs bis zum Ende der Ueberlagerung, nicht bis kurz hinter den Schnittpunkt', () => { |
| 38 | // Sonst erlebt der Anwender: Der abbiegende Kfz-Strom faehrt noch 27 m im |
| 39 | // Korridor des Radwegs, der ausgewiesene Raeumweg endet aber bei 22,90 m - |
| 40 | // die Zwischenzeit faellt um rund 6,8 s zu kurz aus. |
| 41 | const wege = vermesseWege(radweg, abbieger); |
| 42 | expect(wege).not.toBeNull(); |
| 43 | expect(wege?.raeumweg).toBeCloseTo(50, 2); |
| 44 | }); |
| 45 | |
| 46 | it('fuehrt auch den Raeumweg des abbiegenden Kfz-Stroms bis zum Ende der Ueberlagerung', () => { |
| 47 | const wege = vermesseWege(abbieger, radweg); |
| 48 | expect(wege).not.toBeNull(); |
| 49 | // 11,318 m bis zum Knick + 30 m Laengslauf. |
| 50 | expect(wege?.raeumweg).toBeCloseTo(41.32, 2); |
| 51 | }); |
| 52 | |
| 53 | it('vereinigt Punktschnitt und Ueberlagerung zu einem Bereich', () => { |
| 54 | const bereich = konfliktbereich(radweg, abbieger); |
| 55 | expect(bereich).not.toBeNull(); |
| 56 | // Der Punktschnitt bleibt gezaehlt und bestimmt weiterhin den Beginn. |
| 57 | expect(bereich?.schnitte).toBe(1); |
| 58 | expect(bereich?.vonA).toBeCloseTo(15.964, 2); |
| 59 | expect(bereich?.bisA).toBeCloseTo(50, 3); |
| 60 | // Der Einfahrweg des Abbiegers verkuerzt sich auf die vordere Kante des |
| 61 | // Punktschnitts - die kleinere und damit sichere Angabe. |
| 62 | expect(bereich?.vonB).toBeCloseTo(8.969, 2); |
| 63 | expect(bereich?.bisB).toBeCloseTo(41.318, 2); |
| 64 | // Das Ende entlang A stammt aus dem Laengslauf; dort gibt es keinen |
| 65 | // Schnittwinkel. |
| 66 | expect(bereich?.ausUeberlappung).toBe(true); |
| 67 | expect(bereich?.winkel).toBe(0); |
| 68 | }); |
| 69 | |
| 70 | it('laesst den reinen Punktschnitt unveraendert', () => { |
| 71 | // Gegenprobe: Ohne gleichlaufendes Stueck bleibt es beim bisherigen Wert. |
| 72 | const ohneLaengslauf: Fahrlinie = { |
| 73 | id: 'kfz-quer', |
| 74 | punkte: [ |
| 75 | { x: 0, y: -5 }, |
| 76 | { x: 10, y: 0.3 }, |
| 77 | { x: 20, y: 5.6 }, |
| 78 | ], |
| 79 | breite: REGELBREITE.kfz, |
| 80 | }; |
| 81 | const wege = vermesseWege(radweg, ohneLaengslauf); |
| 82 | expect(wege?.raeumweg).toBeCloseTo(22.9, 2); |
| 83 | expect(wege?.konfliktbereich.ausUeberlappung).toBe(false); |
| 84 | }); |
| 85 | }); |