"""Kanten an einer Sperrfläche schneiden und neue Kanten anhängen.""" from __future__ import annotations from shapely.geometry import LineString, box from leonida.roads import Edge, Graph, MIN_EDGE, Node, attach, cut_edges def strecke() -> 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)], 12.0, "wohnstrasse")]) def test_schnitt_in_der_mitte_gibt_zwei_kanten(): out = cut_edges(strecke(), box(40, -5, 60, 5)) assert len(out.edges) == 2 längen = sorted(round(LineString(e.points).length) for e in out.edges) assert längen == [40, 40] def test_reste_unter_der_mindestlaenge_fallen_weg(): # Schnitt bei 90..96: übrig bleiben 90 m; das 4-m-Stück von 96 bis 100 liegt unter MIN_EDGE # und fällt weg. (Ein Schnitt bis ans Streckenende, z.B. 96..104, verschluckt den Rest schon # geometrisch mit - das würde den MIN_EDGE-Filter gar nicht prüfen, weil dann kein Stück unter # der Grenze übrig bliebe, das erst noch verworfen werden müsste.) out = cut_edges(strecke(), box(90, -5, 96, 5)) assert len(out.edges) == 1 assert round(LineString(out.edges[0].points).length) == 90 assert MIN_EDGE == 5.0 def test_ganz_verdeckte_kante_verschwindet(): assert cut_edges(strecke(), box(-10, -10, 110, 10)).edges == [] def test_unberuehrte_kante_bleibt_wie_sie_ist(): out = cut_edges(strecke(), box(200, -5, 220, 5)) assert out.edges[0].points == [(0.0, 0.0), (100.0, 0.0)] assert out.edges[0].klass == "wohnstrasse" def test_kurze_reststuecke_werden_keine_schleifen(): # Genau das Fenster, das die Senkung von MIN_CENTERLINE (15 m) auf MIN_EDGE (5 m) geöffnet # hat: ein 6-m-Rest liegt noch im 8-m-Anhängeradius seines eigenen alten Endpunkts. Ein # Schnitt, der beide Enden über attach() sucht, würde dort denselben Knoten zweimal finden # und aus dem geraden Stummel eine Schleife machen (Edge mit a == b). out = cut_edges(strecke(), box(6, -5, 94, 5)) assert len(out.edges) == 2 assert all(e.a != e.b for e in out.edges), "ein gerader Stummel darf keine Schleife werden" längen = sorted(round(LineString(e.points).length) for e in out.edges) assert längen == [6, 6] def test_attach_findet_einen_nahen_knoten(): graph = strecke() assert attach(graph, (100.0, 3.0)) == 1, "3 m entfernt: derselbe Knoten" assert len(graph.nodes) == 2 def test_attach_legt_sonst_einen_neuen_knoten_an(): graph = strecke() neu = attach(graph, (100.0, 40.0)) assert neu == 2 assert graph.nodes[neu].point == (100.0, 40.0)