feat(extract): Flamingo Park hängt seine Straße an den Graphen
World.centerlines wird zu World.graph: apply_street() und apply_park() schneiden und verlängern jetzt den Straßengraphen statt einer losen Liste von Mittellinien, mit den neuen roads.cut_edges()/attach() als Gegenstück zum bestehenden Schneiden der Straßenflächen. apply_park() schneidet dabei einmal am Parkviereck (nicht je Sperrfläche - das schneidet tatsächlich nichts, was der Parkumriss nicht schon geschnitten hätte). check_corners() bleibt unverändert gegen world.roads (den Korridor) messen, mit einem erklärenden Docstring-Absatz und einer Regressionswache dafür in den Tests. MIN_CENTERLINE (15 m) entfällt zugunsten von MIN_EDGE (5 m): Der alte Grund - Laternen wählten ihre Straßenseite über den Listenindex - fällt weg, sobald eine spätere Aufgabe die Seite aus der Geometrie bestimmt. test_park_street.py dokumentiert das jetzt: die beiden 11-m-Enden der geschnittenen Gasse bleiben deshalb stehen, statt wie vorher zu verschwinden. Beim Nachrechnen der Prüfkörper aus dem Auftrag fielen zwei echte Fehler auf: Der Reste-unter- Mindestlänge-Test schnitt ursprünglich bis übers Streckenende hinaus, sodass der Rest schon geometrisch verschwand und der MIN_EDGE-Filter nie geprüft wurde - jetzt schneidet er innerhalb der Strecke, sodass tatsächlich ein zu kurzes Stück verworfen wird. Und die neue Korridor-Regressionswache verglich (12-7)/2 > 2.5, was mit den echten Maßen immer falsch ist (2.5 > 2.5); korrigiert auf >=, denn die Halbdifferenz trifft die Toleranz exakt. Ausserdem musste eine Test-Fixture in test_park_apply.py von einem 5-m-Reststück (exakt an der neuen MIN_EDGE-Grenze, hätte also entgegen der ursprünglichen Testabsicht überlebt) auf 3 m verkürzt werden, damit der Test weiterhin prüft, dass echte Kurzreste wegfallen. run.py bleibt unangetastet: Es ist bereits durch eine frühere Aufgabe gebrochen und wird von der nächsten Aufgabe repariert. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
8283109ceb
commit
8bc8ca19fc
5 files changed
+162
-23
No files matched your search
@@ -2,6 +2,7 @@ from shapely.geometry import LineString, Point, box
|
||||
from shapely.ops import unary_union
|
||||
|
||||
from leonida.park import Street, World, apply_street
|
||||
from leonida.roads import MIN_EDGE, Edge, Graph, Node
|
||||
|
||||
STREET = Street(start=(150.0, 660.0), end=(150.0, 320.0), width=12.0,
|
||||
remove_buildings=((155.0, 615.0),),
|
||||
@@ -15,8 +16,11 @@ def world():
|
||||
land=[box(-100, 200, 300, 800)],
|
||||
surfaces=[(box(0, 340, 95, 640), "urban"), (box(105, 340, 200, 640).difference(removed), "urban")],
|
||||
roads=[(unary_union([box(0, 640, 200, 660), box(0, 320, 200, 340), box(95, 340, 105, 640)]), False)],
|
||||
centerlines=[LineString([(0, 650), (200, 650)]), LineString([(0, 330), (200, 330)]),
|
||||
LineString([(100, 650), (100, 330)])],
|
||||
graph=Graph(nodes=[Node((0.0, 650.0)), Node((200.0, 650.0)), Node((0.0, 330.0)), Node((200.0, 330.0)),
|
||||
Node((100.0, 650.0)), Node((100.0, 330.0))],
|
||||
edges=[Edge(0, 1, [(0.0, 650.0), (200.0, 650.0)], 12.0, "wohnstrasse"),
|
||||
Edge(2, 3, [(0.0, 330.0), (200.0, 330.0)], 12.0, "wohnstrasse"),
|
||||
Edge(4, 5, [(100.0, 650.0), (100.0, 330.0)], 6.0, "gasse")]),
|
||||
buildings=[(removed, {"height": 20.9, "source": "district"}, False),
|
||||
(box(20, 400, 60, 450), {"height": 10.8, "source": "district"}, False),
|
||||
(box(84, 450, 93, 470), {"height": 8.0, "source": "district"}, False)],
|
||||
@@ -41,11 +45,19 @@ def test_alley_is_cut_and_the_straight_street_joins_both_cross_streets():
|
||||
assert on_road(result, 150, 650) and on_road(result, 150, 330)
|
||||
|
||||
|
||||
def test_alley_centerline_and_short_stubs_go_and_the_street_gets_its_own():
|
||||
def test_alley_centerline_shrinks_to_its_stubs_and_the_street_gets_its_own():
|
||||
"""Früher (MIN_CENTERLINE=15) verschwand die geschnittene Gasse ganz, weil ihre beiden Enden
|
||||
nur 11 m lang sind. cut_edges() kennt nur noch MIN_EDGE (5 m): der alte Grund - Laternen
|
||||
wählten ihre Straßenseite über den Listenindex und liefen an der Kreuzung sonst ins Leere -
|
||||
entfällt, sobald eine spätere Aufgabe die Seite aus der Geometrie bestimmt statt aus der
|
||||
Liste. Die beiden 11-m-Enden bleiben deshalb jetzt als eigene, kurze Kanten stehen.
|
||||
"""
|
||||
result = apply_street(world(), STREET)
|
||||
assert all(line.distance(Point(100, 500)) > 40 for line in result.centerlines)
|
||||
assert LineString([(150, 660), (150, 320)]) in result.centerlines
|
||||
assert all(line.length >= 15 for line in result.centerlines)
|
||||
lines = [LineString(e.points) for e in result.graph.edges]
|
||||
assert sorted(round(line.length) for line in lines if line.length < 15) == [11, 11]
|
||||
assert all(line.distance(Point(100, 500)) > 40 for line in lines)
|
||||
assert any(e.points == [tuple(STREET.start), tuple(STREET.end)] for e in result.graph.edges)
|
||||
assert all(line.length >= MIN_EDGE for line in lines)
|
||||
|
||||
|
||||
def test_freed_ground_becomes_urban_but_not_under_the_street_buildings_or_old_urban():
|
||||
|
||||
Reference in new issue
Block a user