Commit Graph
6 Commits
Author SHA1 Message Date
knso ca01141c5b fix(extract): Zebrabalken mittig verteilt, Kantenbreite gerundet
Befund 8, zwei kleine, aber datenwirksame Funde:

- Zebrastreifen: Der Startversatz (-halb + BAR/2, Takt 2*BAR) liess die
  Balkenreihe an einem Fahrbahnrand bündig sitzen und am gegenüber-
  liegenden bis zu eine Taktbreite frei (0,6 m bei Hauptstraße/Boulevard,
  0,4 m bei Wohnstraße), statt der laut Entwurf verlangten Aufteilung
  "Balken 60 cm, Lücke 60 cm" über die ganze Breite. n = floor((2*halb +
  BAR) / (2*BAR)) Balken, symmetrisch bei -(n-1)*BAR gestartet, lassen an
  beiden Rändern denselben Rest frei (nachgemessen: 0,3 m statt 0/0,6 m
  bei Hauptstraße, 0,2 m statt 0/0,4 m bei Wohnstraße), ohne die Balkenzahl
  je Arm zu ändern.
- edges[].breite (Median aus der Distanztransformation) kam ungerundet an
  (Werte wie 31.622776601683793), während jede andere Zahl in der Ausgabe
  auf 2 Stellen gerundet ist. fahrbahn bleibt unverändert, weil es schon
  eine der vier festen SECTION-Konstanten ist.

Zwei Tests, beide ohne die jeweilige Korrektur rot: die Zebrabalken einer
Kreuzungszufahrt lassen ungleiche Ränder (0,0/0,6 m statt 0,3/0,3 m), und
eine krumme Kantenbreite blieb ungerundet in der Ausgabe.
2026-09-18 07:09:15 +02:00
knso 83140f89e1 fix(extract): Markierungen folgen der Kante und stürzen nicht am Zickzack ab
Befund 3: In junction_marks() kam die Richtung einer Zufahrt aus
origin -> points[1], also nur aus dem ersten Segment der Kante. Haltelinie
und Zebrastreifen wurden aber bis reach + STOP_SETBACK + STOP_DEPTH (bis
16 m) auf dieser Geraden aufgespannt - knickte die Kante innerhalb dieser
Strecke ab, landete die Markierung daneben statt darauf. Am echten Netz
(gemessen über alle 144 committeten Chunks): 452,65 m² von 43.906 m²
Markierungsfläche (1,03 %) liegen außerhalb der Fahrbahn, davon 291,44 m²
Zebra und 147,68 m² Haltelinie; die schlimmsten Einzelfälle sind
vollständige Haltelinien mit 5,41 m². Die Richtung kommt jetzt aus
line.interpolate(min(reach, länge)) - dem tatsächlichen Punkt auf der
Kante bei Streckenlänge reach - statt aus dem zweiten Stützpunkt.

Befund 4: offset_curve() liefert bei einem engen Zickzack eine
MultiLineString statt einer LineString; substring() in _dashed()
akzeptiert nur LineString und wirft dann GeometryTypeError. Am heutigen
Mosaik tritt das nicht auf, aber eine geänderte Korrektur oder eine
eingehängte Kante mit engem Knick hätte den Vier-Minuten-Lauf abgebrochen.
Zweiter, stiller Ast: Eine sehr spitze Kehre lässt offset_curve() leer
zurückkommen; _solid() puffert das ungeprüft zu einem Nullflächen-Polygon.
_offset() normalisiert jetzt auf eine Liste von LineStrings (leer -> [],
MultiLineString -> ihre geoms), _dashed() und _solid() iterieren darüber;
longitudinal() flacht die jetzt listenwertigen _solid()-Aufrufe ab.

Beide Befunde mit Tests, die ohne die jeweilige Korrektur rot sind: der
Zickzack-Fall bricht am unkorrigierten Code mit GeometryTypeError ab, der
Kehre-Fall lieferte zwei Nullflächen-Polygone unter den Rand-/
Doppellinien.
2026-09-18 06:35:36 +02:00
knsoandClaude Sonnet 5 4bf670e0d0 fix(extract): Zebrastreifen und Haltelinie auf die Kantenlaenge begrenzen
reach kommt vom breitesten Arm der ganzen Kreuzung, wurde aber fuer jeden Arm
gleich verwendet. An einer Kreuzung, wo ein kurzer Arm auf einen breiten trifft,
reicht der kurze Arm dann nicht mehr bis reach (Zebrastreifen) oder bis
reach + STOP_SETBACK + STOP_DEPTH (Haltelinie) - die Markierung entstand trotzdem
und ragte ueber das Kantenende hinaus. junction_arms() in section.py schuetzt sich
dagegen laengst; junction_marks() jetzt auch, mit getrennter Pruefung je Markierung,
weil beide unterschiedlich viel Platz brauchen.

Am echten Netz: 38 von 1.508 Armstummeln sind zu kurz fuer die Haltelinie, groesster
Ueberstand 10,6 m (Fixrunde 1 des Koordinators). Auf tatsaechliche Zufahrten
umgerechnet (Schleifen zaehlen doppelt) sind es 44 von 1.536 - die Differenz zur
Kantenzahl war anfangs unklar, ist jetzt aber nachgerechnet und im Kommentar
festgehalten. markings(graph) sinkt dadurch von 22.586 auf 22.336 Flaechen (-206
Zebrabalken, -44 Haltelinien) - genau das vorher falsch platzierte Material.

Dazu zwei bisher uebersehene Stellen mit demselben zu lockeren Testfilter
(abs(centroid.y) < 20) auf die halbe Fahrbahnbreite verengt, wie schon an den zwei
Schwesterstellen der vorigen Fixrunde - die Haltelinie des Suedarms erfuellte die
lockere Bedingung ebenfalls, next() traf bisher nur zufaellig zuerst auf den Ostarm.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-17 09:14:43 +02:00
knsoandClaude Sonnet 5 0c8e9c7ba0 feat(extract): Haltelinien und Zebrastreifen an Kreuzungen
Zebrastreifen im Miami-Balkenmuster und Haltelinie je Zufahrt, dazu markings(graph)
als Sammelfunktion fuer Task 10. Beim Nachrechnen der Pruefkoerper zwei Fehler im
Auftrag gefunden und vor der Uebernahme berichtigt:

Die Haltelinie lag auf der falschen Fahrbahnhaelfte. "across" ist schon als links von
"along" definiert (dieselbe Konvention wie offset_curve() in _offset()), und die Umkehr
der Fahrtrichtung an der Zufahrt braucht deshalb kein zusaetzliches Vorzeichen - der
Auftrag zog eins ab und landete damit auf der Gegenspur. Eine Probe mit offset_curve()
auf der Einfahrtlinie bestaetigt +across als die rechte Seite; alle vier Arme der
Testkreuzung ergeben danach das erwartete Windradmuster.

Zwei Testfilter (|x| bzw. |y| < 20) waren zu locker: An der vierarmigen Testkreuzung
liegen Balken benachbarter Arme nahe genug am Ursprung, um faelschlich mitgezaehlt zu
werden - falsches Gruen durch Verwechslung. Auf die halbe Fahrbahnbreite verengt.

Zusaetzlich gefunden und mit eigenem Test belegt: Eine Schleifenkante haengt mit beiden
Enden am selben Knoten und stellt zwei getrennte Zufahrten dar (wie junction_arms() in
section.py); ohne die zweite Richtung fehlten Haltelinie und Zebra auf einer Seite der
Schleife. Betrifft 28 von 690 Kreuzungen am echten Netz.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-17 08:40:07 +02:00
knsoandClaude Sonnet 5 e92d5b5ce8 fix(extract): Kommentarfehler doppelte Mitte, Rueckgabetyp, zwei Lagetests
Der Kommentar zu gelb_doppelt nannte den Achsabstand (2*WIDTH = 20 cm) als "Abstand der
Mitten", meinte damit aber die Luecke zwischen den gemalten Linien - die entsteht erst
nach der Pufferung um je WIDTH/2 und betraegt WIDTH = 10 cm, wie vom Entwurf verlangt.
Die Geometrie war immer richtig, nur der Satz dazu nicht.

longitudinal() versprach list[tuple[object, str]] statt der zugesagten
list[tuple[Polygon, str]] - Polygon war nicht einmal importiert.

Dazu zwei Tests, die die schon richtige Lage festhalten, damit ein Kommentarfehler wie
der obige naechstes Mal auffiele: gelb_doppelt liegt symmetrisch um die Achse mit 20 cm
Achsabstand und 10 cm Luecke, der Boulevard-Spurtrenner liegt bei genau ±LANE. Kein
TDD-Fall - beide liefen beim ersten Lauf gruen.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-17 08:03:31 +02:00
knsoandClaude Sonnet 5 3216e9407f feat(extract): amerikanische Laengsmarkierungen als Geometrie
Gelbe Mitte, Spurtrenner und Randlinien je Kante, zwischen den Kreuzungsraendern -
Geometrie statt Textur, weil Haltelinie und Zebrastreifen (Task 9) quer zur
Fahrtrichtung liegen und in einer laengs laufenden Kachel nicht unterzubringen waeren.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-17 07:32:20 +02:00