Files
gta6/tools/extract/tests/test_junction.py
T
knsoandClaude Sonnet 5 f91b5ab7c6 fix(extract): Schleifen-Kante bekommt zwei Stummel in junction_area()
incident() liefert eine Schleife (a == b) nur einmal, und edge.a == node ist bei ihr immer
wahr - die zweite Abgangsrichtung bekam deshalb nie einen eigenen Arm im Kreuzungsfächer.
Das war kein Schönheitsfehler, sondern ein Loch in der Fahrbahn genau dort, wo das
zurückgeschnittene Schleifenband auf die Kreuzungsfläche trifft: 179 von 196 Schleifen
sitzen an einem Knoten mit Grad >= 3 und waren betroffen.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-17 02:53:15 +02:00

62 lines
3.0 KiB
Python

"""Kreuzungsflächen und die Fahrbahn als Ganzes."""
from __future__ import annotations
from shapely.geometry import Point
from leonida.roads import Edge, Graph, Node
from leonida.section import FILLET, carriageway_area, junction_area
def kreuzung(klass: str = "hauptstrasse", arm: float = 60.0) -> Graph:
return Graph(
nodes=[Node((0.0, 0.0)), Node((arm, 0.0)), Node((-arm, 0.0)), Node((0.0, arm)), Node((0.0, -arm))],
edges=[Edge(0, i, [(0.0, 0.0), p], 18.0, klass)
for i, p in ((1, (arm, 0.0)), (2, (-arm, 0.0)), (3, (0.0, arm)), (4, (0.0, -arm)))])
def test_kreuzung_deckt_den_knoten_ab():
area = junction_area(kreuzung(), 0)
assert area.contains(Point(0, 0))
def test_einspringende_ecke_ist_gerundet():
area = junction_area(kreuzung(), 0)
# Ohne Rundung endete die Fläche an der Ecke (6, 6) scharf - halbe Fahrbahn in beide
# Richtungen. Mit 6 m Radius ist die einspringende Ecke ausgefüllt.
assert area.contains(Point(6.5, 6.5))
assert FILLET == 6.0
def test_zwei_parallele_strassen_verschmelzen_nicht():
# Zwei Wohnstraßen mit 10 m Abstand der Mittellinien: Fahrbahn je 7 m, dazwischen 3 m Lücke.
# Ein global angewandtes Schließen mit 6 m würde sie zu einer Fläche verkleben.
graph = Graph(nodes=[Node((0.0, 0.0)), Node((100.0, 0.0)), Node((0.0, 10.0)), Node((100.0, 10.0))],
edges=[Edge(0, 1, [(0.0, 0.0), (100.0, 0.0)], 12.0, "wohnstrasse"),
Edge(2, 3, [(0.0, 10.0), (100.0, 10.0)], 12.0, "wohnstrasse")])
area = carriageway_area(graph)
assert len(area.geoms) == 2, "getrennte Straßen bleiben getrennt"
def test_fahrbahn_enthaelt_baender_und_kreuzung():
area = carriageway_area(kreuzung())
assert area.contains(Point(0, 0)), "die Kreuzung selbst"
assert area.contains(Point(40, 0)), "ein Band"
assert not area.contains(Point(40, 40)), "die Ecke zwischen zwei Armen bleibt frei"
def test_schleife_bekommt_zwei_stummel_kein_loch_im_belag():
# Eine Schleife hängt mit beiden Enden am selben Knoten. incident() liefert sie nur einmal,
# und edge.a == node ist bei ihr immer wahr - ohne einen zweiten Stummel für die zweite
# Abgangsrichtung bliebe zwischen dem zurückgeschnittenen Schleifenband und der
# Kreuzungsfläche ein Loch. Zwei gerade Arme sorgen dafür, dass der Knoten überhaupt als
# Kreuzung (Grad >= 3) zählt.
graph = Graph(
nodes=[Node((0.0, 0.0)), Node((-100.0, 0.0)), Node((0.0, -100.0))],
edges=[Edge(0, 0, [(0.0, 0.0), (0.0, 20.0), (20.0, 20.0), (20.0, 0.0), (0.0, 0.0)], 18.0, "hauptstrasse"),
Edge(0, 1, [(0.0, 0.0), (-100.0, 0.0)], 18.0, "hauptstrasse"),
Edge(0, 2, [(0.0, 0.0), (0.0, -100.0)], 18.0, "hauptstrasse")])
area = carriageway_area(graph)
# Zwischen der Kreuzungsfläche (endet bei halber Fahrbahn = 6 m) und dem zurückgeschnittenen
# Schleifenband (beginnt beim Setback = 8 m) liegt (7, 0) - ohne den zweiten Stummel außerhalb.
assert area.contains(Point(7.0, 0.0))