fix(extract): Chunk-Ausgabe lauf-stabil, Eckenprüfung in beide Richtungen

emit.py normalisiert jede ausgegebene Fläche und sortiert die Listen nach der
Ausgabestruktur selbst. unary_union() in apply_street() gab das kartenweite
Straßenpolygon mit anderem Ringstartpunkt und an anderer Listenstelle zurück und
änderte damit 88 Chunkdateien, in denen sich geometrisch nichts bewegt hatte
(symmetrische Differenz 0,00 m²). Belagsarten und Mittellinien behalten ihre
Reihenfolge: overview.py malt die Beläge in Listenreihenfolge übereinander, und
vergeLampPoints() hängt an Reihenfolge und Laufrichtung der Mittellinien —
Sortieren verschöbe dort 1.848 von 3.921 Laternen auf die andere Straßenseite.

check_corners() misst gegen den Straßenrand statt gegen die Straßenfläche. Alle
vier Ecken liegen in der Fahrbahn, ihr Flächenabstand ist 0,000 m; die alte
Prüfung schlug deshalb nur an, wenn eine Straße sich zurückzieht. Eine nach
innen verbreiterte Straße hätte apply_park() still auf das veraltete Viereck
zurückgeschnitten.

Die Parkwege werden am Parkviereck abgeschnitten — die runden Kappen von
LineString.buffer() lagen mit 95,96 m² darüber hinaus, rund 41 m² davon sichtbar
als Betonzungen auf den umgebenden Belägen. load_elements() prüft den OSM-Abzug
so streng wie die Parkdatei, mit Dateiname statt nacktem KeyError.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
knsoandClaude Opus 5 committed 2026-09-16 13:43:01 +02:00
1 parent a3504df43d
commit 3c74202b5e
10 files changed
+333 -102

No files matched your search

+14
View File
@@ -53,6 +53,20 @@ def test_path_is_cut_at_the_real_park_edge():
assert path.bounds[3] <= 1400 + 1.5 + 1e-6
def test_paths_stop_at_the_park_edge_instead_of_bulging_over_it():
"""LineString.buffer() setzt an jedes Wegende eine runde Kappe von einer halben Wegbreite.
Der letzte Stützpunkt liegt schon auf der Parkkante (_extend zielt dorthin), die Kappe ragte
also bis zu 1,5 m (Fußweg) bzw. 3 m (Hauptweg) darüber hinaus und lag als Betonzunge auf dem
Belag daneben — an den echten Daten 95,96 m² außerhalb des Vierecks.
"""
cfg = config()
quad = ParkFit(cfg).game_quad
(path,) = build_layout([way({"highway": "footway"}, (50, 150), (50, 260))], cfg, ParkFit(cfg)).paths
assert path.difference(quad).area == 0
assert path.bounds[3] == pytest.approx(1400.0)
def test_path_ending_near_the_west_edge_runs_on_to_the_road():
(path,) = layout([way({"highway": "footway"}, (40, 100), (3, 100))]).paths
assert path.contains(Point(1001, 1200))