feat(extract): Straßennetz als Graph aus dem Skelett

centerlines() verwirft alles unter 15 m und zerlegt das Netz damit an jeder
Kreuzung: von 3.038 Linienenden treffen sich nur 81. Der neue Graph lässt
das Skelett ungefiltert, macht aus den 5.970 Pixeln mit Grad >= 3 durch
Verschmelzen im Umkreis von 8 m die 862 Kreuzungen und hängt die Kanten
dort ein.

_skeleton_graph/_to_world in vectors.py sind jetzt öffentliche Schnittstelle
für roads.py (skeleton_graph/to_world); inpaint.py zieht seinen einzigen
Aufruf von skeleton_graph mit, sonst bräche dessen Import.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
knsoandClaude Sonnet 5 committed 2026-09-17 00:36:40 +02:00
1 parent 505b1969ec
commit 3fe3cd5c45
4 files changed
+182 -7

No files matched your search

+2 -2
View File
@@ -19,7 +19,7 @@ from skimage.draw import polygon as fill_polygon
from skimage.morphology import skeletonize
from .classify import CLASSES
from .vectors import _skeleton_graph
from .vectors import skeleton_graph
ROAD_ORDER = ("weg", "spekulativ", "strasse") # Malreihenfolge: später gemalt gewinnt
AREA_CLASSES = ("wasser", "land", "gruen", "sand", "stadt")
@@ -140,7 +140,7 @@ def _plan_roads(L, M, B, edges, stats):
# Die Maske zählt beim Skelettieren als Straße: sonst schrumpft die Mittellinie einer
# abgeschnittenen Straße um ihre Halbbreite und erreicht die 10-m-Zone nie.
skeleton = skeletonize(visible | M) & ~M
graph = _skeleton_graph(skeleton)
graph = skeleton_graph(skeleton)
width = ndi.distance_transform_edt(visible)
ends = [e for e in _road_ends(graph, dist_mask, width) if not _near_edge(e, M.shape, edges)]
pairs, single = _pair_ends(ends, M | any_road)