Gelbe Mitte, Spurtrenner und Randlinien je Kante, zwischen den Kreuzungsraendern - Geometrie statt Textur, weil Haltelinie und Zebrastreifen (Task 9) quer zur Fahrtrichtung liegen und in einer laengs laufenden Kachel nicht unterzubringen waeren. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
68 lines
2.7 KiB
Python
68 lines
2.7 KiB
Python
"""Längsmarkierungen: Mittellinie, Spurtrenner, Randlinien."""
|
|
from __future__ import annotations
|
|
|
|
from collections import Counter
|
|
|
|
from leonida.roads import Edge, Graph, Node
|
|
from leonida.marking import DASH, GAP, WIDTH, longitudinal
|
|
from leonida.section import SECTION
|
|
|
|
|
|
def strecke(klass: str, length: float = 120.0) -> Graph:
|
|
return Graph(nodes=[Node((0.0, 0.0)), Node((length, 0.0))],
|
|
edges=[Edge(0, 1, [(0.0, 0.0), (length, 0.0)], SECTION[klass].corridor, klass)])
|
|
|
|
|
|
def arten(graph: Graph) -> Counter:
|
|
return Counter(art for _, art in longitudinal(graph))
|
|
|
|
|
|
def test_gasse_bekommt_keine_markierung():
|
|
assert longitudinal(strecke("gasse")) == []
|
|
|
|
|
|
def test_wohnstrasse_bekommt_eine_gestrichelte_gelbe_mitte():
|
|
zahl = arten(strecke("wohnstrasse"))
|
|
assert set(zahl) == {"gelb_gestrichelt"}
|
|
# 120 m in 12-m-Takten: zehn Striche.
|
|
assert zahl["gelb_gestrichelt"] == 10
|
|
assert DASH == 3.0 and GAP == 9.0
|
|
|
|
|
|
def test_hauptstrasse_bekommt_doppelte_mitte_und_zwei_randlinien():
|
|
zahl = arten(strecke("hauptstrasse"))
|
|
assert zahl["gelb_doppelt"] == 2, "zwei durchgezogene Linien nebeneinander"
|
|
assert zahl["weiss_rand"] == 2, "je eine an der Grenze zur Parkspur"
|
|
assert "weiss_gestrichelt" not in zahl, "zwei Spuren brauchen keinen Spurtrenner"
|
|
|
|
|
|
def test_boulevard_bekommt_zusaetzlich_spurtrenner():
|
|
zahl = arten(strecke("boulevard"))
|
|
assert zahl["gelb_doppelt"] == 2
|
|
assert zahl["weiss_rand"] == 2
|
|
assert zahl["weiss_gestrichelt"] == 20, "je Richtung ein gestrichelter Trenner, 10 Striche"
|
|
|
|
|
|
def test_randlinie_liegt_an_der_grenze_zur_parkspur():
|
|
section = SECTION["hauptstrasse"]
|
|
ränder = [poly for poly, art in longitudinal(strecke("hauptstrasse")) if art == "weiss_rand"]
|
|
abstände = sorted(round(abs(poly.centroid.y), 2) for poly in ränder)
|
|
erwartet = round(section.carriageway / 2 - section.parking, 2)
|
|
assert abstände == [erwartet, erwartet]
|
|
|
|
|
|
def test_linien_sind_zehn_zentimeter_breit():
|
|
poly = longitudinal(strecke("wohnstrasse"))[0][0]
|
|
x0, y0, x1, y1 = poly.bounds
|
|
assert round(y1 - y0, 3) == WIDTH
|
|
assert round(x1 - x0, 3) == DASH
|
|
|
|
|
|
def test_markierung_endet_am_kreuzungsrand():
|
|
graph = Graph(nodes=[Node((0.0, 0.0)), Node((120.0, 0.0)), Node((120.0, 60.0)), Node((180.0, 0.0))],
|
|
edges=[Edge(0, 1, [(0.0, 0.0), (120.0, 0.0)], 12.0, "wohnstrasse"),
|
|
Edge(1, 2, [(120.0, 0.0), (120.0, 60.0)], 12.0, "wohnstrasse"),
|
|
Edge(1, 3, [(120.0, 0.0), (180.0, 0.0)], 12.0, "wohnstrasse")])
|
|
ende = max(poly.bounds[2] for poly, _ in longitudinal(graph) if poly.bounds[2] < 120)
|
|
assert ende < 120 - SECTION["wohnstrasse"].carriageway / 2, "vor der Kreuzung ist Schluss"
|