feat(extract): Mulde, Bordsteinlinien, Gehweg und Restflächen
Ein Prüfkörper korrigiert: Der Splitter in test_kleine_reststuecke_fallen_weg_grosse_bleiben lag direkt an derselben Korridorkante wie die Ausbuchtung und verschmolz dort schon bei unary_union() mit ihr, bevor der LOT_MIN-Filter überhaupt etwas zu tun bekam. Mit einer kleinen Lücke zum Rand bleibt er ein eigenständiges 2-m²-Polygon und fällt durch den Filter - der Test prüft jetzt tatsächlich das Wegfallen kleiner Reststücke, nicht nur, dass große bleiben. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
ee07a6bf2a
commit
45a1a62103
2 files changed
+151
No files matched your search
@@ -0,0 +1,69 @@
|
||||
"""Die Mulde: Löcher in der Bodenplatte, Bordsteinlinien, Gehwegflächen, Restflächen."""
|
||||
from __future__ import annotations
|
||||
|
||||
from shapely.geometry import Point, box
|
||||
from shapely.ops import unary_union
|
||||
|
||||
from leonida.roads import Edge, Graph, Node
|
||||
from leonida.section import SECTION
|
||||
from leonida.street import LOT_MIN, build_street, punch
|
||||
|
||||
|
||||
def strasse(klass: str = "wohnstrasse") -> Graph:
|
||||
return Graph(nodes=[Node((0.0, 0.0)), Node((100.0, 0.0))],
|
||||
edges=[Edge(0, 1, [(0.0, 0.0), (100.0, 0.0)], SECTION[klass].corridor, klass)])
|
||||
|
||||
|
||||
def korridor(klass: str = "wohnstrasse"):
|
||||
halb = SECTION[klass].corridor / 2
|
||||
return box(0, -halb, 100, halb)
|
||||
|
||||
|
||||
def test_gehweg_fuellt_genau_den_rest_des_korridors():
|
||||
street = build_street(strasse(), korridor(), bridges=[])
|
||||
section = SECTION["wohnstrasse"]
|
||||
# 100 m lang, zwei Streifen von 2,5 m. Die Enden sind offen, deshalb genau die Fläche.
|
||||
assert round(street.sidewalk.area) == round(100 * 2 * section.walk)
|
||||
assert street.sidewalk.intersection(street.carriageway).area < 0.01
|
||||
|
||||
|
||||
def test_gasse_bekommt_weder_gehweg_noch_bordstein():
|
||||
street = build_street(strasse("gasse"), korridor("gasse"), bridges=[])
|
||||
assert street.sidewalk.area < 0.01
|
||||
assert street.kerb == []
|
||||
|
||||
|
||||
def test_bordstein_laeuft_entlang_der_fahrbahnkante():
|
||||
street = build_street(strasse(), korridor(), bridges=[])
|
||||
gesamt = sum(line.length for line in street.kerb)
|
||||
# Zwei Längsseiten von 100 m; die kurzen Stirnseiten sind mit 7 m kaum der Rede wert.
|
||||
assert 190 < gesamt < 220
|
||||
|
||||
|
||||
def test_bruecken_bekommen_keinen_bordstein():
|
||||
bridge = box(40, -10, 60, 10)
|
||||
street = build_street(strasse(), korridor(), bridges=[bridge])
|
||||
for line in street.kerb:
|
||||
assert not bridge.buffer(-0.5).intersects(line), "über der Brücke bleibt die Kante frei"
|
||||
|
||||
|
||||
def test_loch_hat_genau_die_form_der_fahrbahn():
|
||||
platte = box(-50, -50, 150, 50)
|
||||
street = build_street(strasse(), korridor(), bridges=[])
|
||||
rest = punch([platte], street.carriageway)
|
||||
assert len(rest) == 1
|
||||
assert not rest[0].contains(Point(50, 0)), "die Fahrbahnmitte ist ausgeschnitten"
|
||||
assert rest[0].contains(Point(50, 20)), "daneben bleibt die Platte"
|
||||
assert abs(unary_union(rest).area + street.carriageway.area - platte.area) < 1.0
|
||||
|
||||
|
||||
def test_kleine_reststuecke_fallen_weg_grosse_bleiben():
|
||||
# Ein Korridor mit einer 30 x 30 m großen Ausbuchtung (ein Parkplatz) und einem Splitter.
|
||||
# Der Splitter braucht eine Lücke zum Korridorrand: Läge er wie die Ausbuchtung direkt an
|
||||
# y = 6 an, verschmölze schon unary_union() ihn mit ihr, weil beide dieselbe durchgehende
|
||||
# Kante berühren - dann bliebe für LOT_MIN unten gar nichts mehr zu filtern übrig.
|
||||
weit = unary_union([korridor(), box(40, 6, 70, 36), box(10, 8, 12, 9)])
|
||||
street = build_street(strasse(), weit, bridges=[])
|
||||
assert all(lot.area >= LOT_MIN for lot in street.lots)
|
||||
assert any(lot.area > 500 for lot in street.lots), "der Parkplatz bleibt"
|
||||
assert len(street.lots) == 2, "der 2 m² große Splitter ist tatsächlich herausgefallen"
|
||||
Reference in new issue
Block a user