Files
gta6/tools/extract/tests/test_pipeline_roads.py
T
knsoandClaude Sonnet 5 2201be37bd feat(extract): Pipeline baut Straßen aus dem Graphen
run.py baut jetzt aus dem Straßengraphen (Tasks 3-11) statt aus den nachgezeichneten
Straßenrändern: Fahrbahn, Bordstein, Gehweg und Restflächen aus build_street(),
amerikanische Markierungen aus markings(). fit_to_carriageway() bringt Bodenplatte und
Beläge auf dasselbe Loch wie die Fahrbahn und hält Palmen dabei von ihr fern - nach
derselben Regel, mit der apply_street() sie schon von der Jefferson Avenue fernhält.

split_by_chunk_all() bekommt dafür eine parametrisierbare Splittergrenze: Ein Strich der
gestrichelten Linien ist 3 m x 10 cm = 0,3 m² und wäre an der bisherigen 0,5-m²-Grenze für
Flächen verschwunden. Markierungen laufen deshalb über den neuen Helfer chunk_markings()
mit eigener, kleinerer Grenze; alle anderen Aufrufer bleiben bei 0,5 m².

Am echten Netz gemessen: 1.537 Knoten, 1.790 Kanten, 830 Bordsteinstücke, 171
Restflächen, 22.394 Markierungen, 56 Palmen an der Fahrbahn entfernt. Fahrbahn-, Gehweg-
und Restflächen sowie die Bordsteinlänge treffen die vorab am echten Netz gemessenen
Erwartungswerte auf 0,03-0,3 % genau.

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

74 lines
3.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Die Reihenfolge, in der die Straßen entstehen — ohne den vollen Lauf."""
from __future__ import annotations
from shapely.geometry import box
from shapely.ops import unary_union
from leonida.emit import chunk_box_of
from leonida.park import World
from leonida.roads import Edge, Graph, Node
from leonida.street import build_street, punch
from run import chunk_markings, fit_to_carriageway
def _gerade_wohnstrasse():
"""100 m Wohnstraße entlang y = 0: Fahrbahn 7 m breit, also von y = -3,5 bis 3,5."""
graph = Graph(nodes=[Node((0.0, 0.0)), Node((100.0, 0.0))],
edges=[Edge(0, 1, [(0.0, 0.0), (100.0, 0.0)], 12.0, "wohnstrasse")])
return graph, build_street(graph, box(0, -6, 100, 6), bridges=[])
def _welt(graph, *, surfaces=(), palms=()):
return World(land=[box(-20, -50, 120, 50)], surfaces=list(surfaces), roads=[], graph=graph,
buildings=[], palms=list(palms))
def test_boden_und_belag_bekommen_dasselbe_loch():
"""Vergisst run.py eine der beiden Schichten, liegt dort ein Belag über der Mulde oder die
Bodenplatte schließt sie."""
graph, street = _gerade_wohnstrasse()
platte = box(-20, -50, 120, 50)
welt = _welt(graph, surfaces=[(box(-20, -50, 50, 50), "urban"), (box(50, -50, 120, 50), "park")])
out = fit_to_carriageway(welt, street.carriageway)
boden = unary_union(out.land)
assert boden.intersection(street.carriageway).area < 0.01, "die Fahrbahn liegt im Loch"
loch = street.carriageway.intersection(platte).area
assert abs(platte.area - boden.area - loch) < 0.01, "das Loch ist nicht größer als die Fahrbahn"
for kind in ("urban", "park"):
belag = unary_union([poly for poly, k in out.surfaces if k == kind])
assert belag.intersection(street.carriageway).area < 0.01, f"kein Belag {kind} über der Mulde"
assert abs(unary_union([poly for poly, _ in out.surfaces]).area - boden.area) < 0.01, "dasselbe Loch"
def test_gehweg_liegt_nicht_im_loch():
graph, street = _gerade_wohnstrasse()
land = unary_union(punch([box(-20, -50, 120, 50)], street.carriageway))
assert street.sidewalk.difference(land).area < 0.5, "der Gehweg liegt auf der Bodenplatte"
def test_keine_palme_auf_oder_dicht_an_der_fahrbahn():
"""Entwurf, Ablauf Schritt 7: Palmen werden nach dem Straßenbau neu gesetzt. Am echten Netz
standen ohne diesen Schritt 24 Palmen auf der Fahrbahn und 32 weitere näher als PALM_KERB."""
graph, street = _gerade_wohnstrasse()
welt = _welt(graph, palms=[(50.0, 0.0), (50.0, 4.5), (50.0, 5.5)])
out = fit_to_carriageway(welt, street.carriageway)
assert out.palms == [(50.0, 5.5)], "auf der Fahrbahn und 1 m daneben weg, 2 m daneben bleibt"
def test_striche_ueberleben_den_zuschnitt():
"""Ein Strich der gestrichelten Mitte ist 3 m × 10 cm = 0,3 m². Mit der Splittergrenze der
Flächen (0,5 m²) fiel am echten Netz jeder einzelne der 4.363 Striche weg."""
zelle = chunk_box_of(0, 0)
x, y = zelle.centroid.x, zelle.centroid.y
stuecke = chunk_markings([(box(x, y, x + 3.0, y + 0.1), "gelb_gestrichelt")], 0, 0)
assert [art for _, art in stuecke] == ["gelb_gestrichelt"]
assert abs(stuecke[0][0].area - 0.3) < 1e-6
def test_strich_ueber_der_chunkgrenze_wird_geteilt_nicht_verworfen():
zelle = chunk_box_of(0, 0)
grenze, y = zelle.bounds[2], zelle.centroid.y # rechte Kante von Chunk (0, 0)
strich = [(box(grenze - 1.0, y, grenze + 2.0, y + 0.1), "weiss_gestrichelt")]
assert [round(poly.area, 6) for poly, _ in chunk_markings(strich, 0, 0)] == [0.1]
assert [round(poly.area, 6) for poly, _ in chunk_markings(strich, 1, 0)] == [0.2]