Commit Graph
172 Commits
Author SHA1 Message Date
knsoandClaude Opus 5 2afae81bce docs: Plan auf Rulings 24-29 umstellen (Palmen, Gebäude)
palm_points bekommt die Landflächen und verwirft, was nicht darauf liegt:
am echten Mosaik standen 218 von 2.433 Palmen im Wasser. regularize
vereinfacht nicht mehr ein zweites Mal und gröber als mask_polygons, was
202 von 2.085 Gebäuden verworfen hatte. Dazu die vier neuen Tests, der
Marker am einzelnen Test statt eines suiteweiten Filters, die Entdoppelung
der Palmenpunkte und die korrigierte Signatur von assign_heights.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-12 16:17:39 +02:00
knsoandClaude Sonnet 5 42f2a4415d fix(extract): Palmen nicht mehr im Wasser, regularize() nicht mehr doppelt vereinfacht
Fix-Runde 1, vier Befunde aus dem Review (Rulings 25-28):

Befund A (Critical): der Versatz nach außen konnte eine Palme über die
Uferlinie ins Wasser schieben (218 von 2.433 auf dem echten Mosaik).
palm_points() bekommt jetzt land_polys (vor seed), _verge_point() verwirft
einen Kandidaten, der nicht auf Land liegt.

Befund B (Important): regularize() vereinfachte im Rückfallzweig ein zweites
Mal und gröber (1,0 m statt der 0,5 m, die mask_polygons() schon angewandt
hatte) und prüfte erneut gegen MIN_AREA - das drückte kleine, treppenrandige
Grundrisse unter die Schwelle (202 von 2.085 gebaeude-, 9 von 267
spekulativ-Kandidaten). Der Rückfallzweig vereinfacht jetzt nur noch einmal,
mit 0,5 m, ohne zweite Flächenprüfung.

Befund C: der globale filterwarnings-Eintrag in pyproject.toml (Fix für die
oriented_envelope-RuntimeWarning aus der letzten Runde) war zu weit gefasst
und hätte auch eine echte künftige Division durch Null versteckt. Er gehört
nur auf den einen Test, der minimum_rotated_rectangle selbst aufruft -
pyproject.toml zurück auf den Stand davor, @pytest.mark.filterwarnings auf
test_l_shape_is_kept_not_boxed.

Befund D (Minor): vier doppelte Palmenpunkte entfernt (dict.fromkeys vor dem
return), zwei bisher ungetestete Zweige abgedeckt (spekulativ=True/False,
Park-Streuung mit Determinismus-Check).

Test zuerst für A und B, beide vor dem jeweiligen Fix rot gesehen (echte
Assertion-Fehler, keine Signatur-Fehler). 31/31 Tests grün, weiterhin ohne
Warnungen.

Auf dem echten Mosaik: 2.352 Gebäude (vorher 2.141, +211 - exakt die Zahl,
die Befund B vorher fallen ließ; 0 von regularize verworfen, siehe Bericht
für die Erklärung), 267 spekulativ. 2.133 Palmenpunkte (Referenz des
Koordinators von 2.176 war mit dem alten, kleineren Gebäudebestand
gemessen - mit dem isoliert nachgebauten alten Bestand komme ich auf 2.175,
die verbleibende Differenz von 1 ist im Bericht dokumentiert statt verschwiegen).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-12 16:14:56 +02:00
knsoandClaude Sonnet 5 6de4b81942 feat(extract): Gebäudepolygone, Höhen aus Wahrzeichen und Vierteln, Palmenpunkte
buildings.py regularisiert Gebäude-Maskenpolygone (gebaeude/spekulativ) zu
Rechtecken, wenn sie ihr gedrehtes Hüllrechteck zu mindestens 85 % ausfüllen,
sonst zu vereinfachten Grundrissen; zu kleine oder entartete Polygone liefern
None. heights.py weist Gebäuden eine Höhe zu (Wahrzeichen-Treffer schlägt
Viertel-Bereich, deterministisch geseedet) und platziert Palmenpunkte entlang
strandnaher Mittellinien: der Versatz vom Fahrbahnrand wird von innen nach
außen gesucht (PALM_VERGE), bis eine Position sowohl PALM_KERB von der
Fahrbahn als auch PALM_CLEARANCE von Gebäuden einhält; findet sich keine,
entfällt die Palme. Start bei halber PALM_SPACING verhindert doppelte Palmen
an Kreuzungen, wo Task 4 Mittellinien pro Ast trennt.

pyproject.toml ergänzt einen gezielten filterwarnings-Eintrag: Shapelys
oriented_envelope (minimum_rotated_rectangle) meldet für bereits achsen-
parallele/rechtwinklige Polygone eine RuntimeWarning aus GEOS (Winkelterm
wird 0/0), obwohl das Ergebnis nachweislich korrekt bleibt – u.a. löst der
Briefs eigener L-Shape-Test das aus. Nur dieser eine Text+Kategorie-
kombinierte Fall wird gefiltert, jede andere Warnung bleibt sichtbar.

Auf dem echten Mosaik: 2141 Gebäudepolygone (258 spekulativ, 211 von
regularize verworfen), Höhen 6.0-15.0 m (nur "district", da data/skyline.json
und data/districts.json erst in Task 6 kommen), 2433 Palmenpunkte. Straßen-
und Mittellinienzahlen (475 Stücke/40 Brücken, 2323 Linien/Median 27 m)
decken sich exakt mit den in Task 4 unabhängig ermittelten Referenzwerten.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-12 15:43:10 +02:00
knsoandClaude Opus 5 11f6aa76fe docs: Palmenpunkte in Task 5 korrigieren (Rulings 20-23)
Die erste Palme startet bei halber Teilung, weil die Mittellinien seit
Task 4 an Kreuzungen getrennt sind und zwei gegenüberliegende Äste sonst
zwei Palmen in denselben Punkt setzen. Der feste Versatz von 4 m weicht
einer Suche vom Fahrbahnrand: am echten Mosaik stünden damit 60 % der
Palmen auf der Fahrbahn. Dazu zwei Tests, die es bisher nicht gab, und
die korrigierte Signatur im Interfaces-Block.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-12 15:27:37 +02:00
knsoandClaude Opus 5 830e9f87e0 docs: Plan auf Rulings 13-17 umstellen (Brücken, Mittellinien)
Brückenerkennung im Plan von der Bounding-Box auf die Verschneidung
umgestellt und um die Wassernähe ergänzt, Mittellinien über den
Pixelgraphen statt über Konturen. Der Plan zeigt jetzt den Code, der
in 120cafd tatsächlich gebaut wurde.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-12 15:17:25 +02:00
knsoandClaude Sonnet 5 120cafd7bf fix(extract): Brücke braucht Nähe zu Wasser, nicht nur Ferne von Land
Fix-Runde 2 (Ruling 17). Nachmessung am echten Mosaik zeigte: 143 der 190 aus
Fix-Runde 1 markierten Brücken (137.288 von 208.744 m² Fläche) hatten unter
10 % Wasser in ihrer Umgebung, darunter die beiden größten Stücke mit 2,4 %
und 0,1 % Wasser. Das waren breite Kreuzungs- und Parkflächen an Land: ihre
Mitte liegt allein deshalb weiter als LAND_REACH_PX von straßenfreiem Land
entfernt, weil dort ringsum nur Straße ist – kein Bezug zu Wasser. Ein
größeres LAND_REACH_PX heilt das nicht (ab 16 kippt der bestehende Test).

Straßenstücke jenseits von "Land" zählen jetzt nur noch als Brücke, wenn sie
zusätzlich innerhalb WATER_REACH_PX von Wasser liegen; neue Konstante
WATER_REACH_PX = 8, am echten Mosaik kalibriert (6-10 ein stabiles Plateau
bei ~40 Brücken, ab 14 bricht es weg und reißt wieder trockene Flächen mit).

Regressionstest zuerst rot gesehen (test_wide_road_area_on_land_is_not_a_bridge),
bestehende Tests unverändert und weiterhin grün. 17/17 Tests grün. Auf dem
echten Mosaik: 475 Straßenstücke, 40 Brücken, größtes Brückenstück 12.588 m² –
deckt sich mit den unabhängig ermittelten Referenzwerten der Prüfung.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-12 15:14:12 +02:00
knsoandClaude Sonnet 5 47c3cb98da fix(extract): Brückenerkennung per Verschneidung, Mittellinien ohne Dopplung
Fix-Runde 1, drei Befunde:

- road_polygons: Straßennetz ist ein zusammenhängendes Polygon über den ganzen
  Ausschnitt; eine Fensterprüfung um seine Bounding-Box sieht daher zwangsläufig
  Wasser und meldet fast alles als Brücke. Ersetzt durch Verschneidung jedes
  Straßenpolygons mit der Landfläche (Ruling 13). Die wörtlich vorgegebene
  Landberechnung (unary_union(land_polygons(labels))) besteht die bestehenden
  Tests nicht: eine Straße ist nie "wasser", also zählt land_polygons() sie
  selbst als Land, und ein Damm quer durchs Meer überlappt dann mit sich selbst
  statt als Brücke aufzufallen (siehe Fix-Bericht für den Nachweis). Land wird
  stattdessen ohne die Straßenklasse berechnet und um LAND_REACH_PX gewachsen,
  damit eine Straße, die direkt an Land beginnt, dort noch erkannt wird. Der
  Radius wurde am echten Mosaik kalibriert: unter 8 px verkettet sich eine
  gewöhnliche Küstenstraße mangels Berührung mit "Land" erneut zu einem
  kartenweiten Brückenstück; 10 px behebt das mit Sicherheitsabstand zur
  Wasserlücke des bestehenden Tests.

- centerlines: eine Kontur um das ein Pixel breite Skelett lief auf beiden
  Seiten des Bandes hin und zurück und lieferte jede Linie doppelt; an
  Kreuzungen ergab das eine einzelne Schleife statt getrennter Äste (Ruling 14,
  neue Tests zuerst rot gesehen). Ersetzt durch einen Pixelgraphen (networkx):
  Skelettpixel als Knoten, 8er-Nachbarschaft als Kanten, Pfade zwischen Knoten
  mit Grad ungleich 2 je Zusammenhangskomponente, reine Ringe einmal umlaufen.

- mask_polygons: Polygon(ring).buffer(0) kann bei selbstschneidenden Konturen
  ein MultiPolygon liefern; das schlug später mit AttributeError fehl. Beim
  Einsortieren in outers/holes wird jetzt nur noch ein sauberes Polygon
  akzeptiert (Ruling 15).

16/16 Tests grün. Auf dem echten Mosaik: 469 Straßenstücke (190 Brücken,
größtes Brückenstück 26.294 m² auf einer lokalen Fläche von 643 x 564 m,
nicht mehr kartenweit).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-12 15:07:46 +02:00
knsoandClaude Opus 5 fb898b03b3 docs: zwei Fehler im Referenzcode von Aufgabe 4 korrigiert
- Löcher werden über das Vorzeichen der Shoelace-Summe erkannt; die Stichprobe am
  Konturmittelpunkt versagt bei einer Insel mit Lagune
- das Brückenfenster braucht einen Rand, sonst enthält es nur Straßenpixel und die
  Erkennung löst nie aus

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-12 14:40:59 +02:00
knsoandClaude Sonnet 5 6452223c24 docs(extract): Brückenrand-Konstante besser begründet
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-12 14:38:19 +02:00
knsoandClaude Sonnet 5 ab1d64a1c2 feat(extract): Küste, Straßenflächen, Brückenerkennung, Mittellinien
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-12 14:37:13 +02:00
knsoandClaude Sonnet 5 38aed38b02 fix(extract): Wasserfarbe und Delta-E-Schwelle nach Nachmessung korrigiert
Ruling 10: wasser war auf die tiles.py-Kompositionsfarbe (44,103,164) gesetzt statt auf die
tatsächlich gerenderte, im Tiefenverlauf variierende Wasserfarbe. Auf (48,144,192) korrigiert,
MAX_DELTA_E von 14 auf 22 angehoben, um den Verlauf abzudecken. Unbekannter Pixelanteil im
echten Mosaik faellt damit von 37,4 % auf 3,5 %, unter die 5-%-Abbruchschwelle aus Aufgabe 6.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-12 14:19:51 +02:00
knsoandClaude Opus 5 162e018925 docs: Palette und Toleranzen an das echte Mosaik angepasst
Wasser ist #3090c0, nicht #2c67a4; der alte Wert war die Kompositionsfarbe aus tiles.py.
Mit Schwelle 22 fallen die unbekannten Pixel von 37,4 auf 3,5 Prozent. Die Sollanteile für
Straße und Gebäude stammten aus einer Messung mit anderer Klasseneinteilung und werden
auf die gemessenen Bänder gesetzt.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-12 14:17:15 +02:00
knsoandClaude Sonnet 5 593ccf217f feat(extract): Pixel-Klassifizierung mit Lab-Palette
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-12 14:13:35 +02:00
knsoandClaude Opus 5 d40d96a800 docs: classify meldet auf Wunsch den Anteil unbekannter Pixel
Aufgabe 6 braucht den Anteil für den Abbruch über 5 Prozent; die Signatur in Aufgabe 3
kannte ihn bisher nicht.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-12 14:07:30 +02:00
knsoandClaude Opus 5 a94c09e279 docs: Plan an zwei Befunde aus Aufgabe 2 angepasst
- pyproject.toml braucht pythonpath, sonst ist das lokale Paket im Test nicht importierbar
- der Mosaik-Test prüft jetzt den exakten Zuschnitt-Versatz statt nur der Eckkacheln

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-12 14:05:19 +02:00
knsoandClaude Sonnet 5 1e089df4b4 test(extract): Mosaik-Test auf exakten Zuschnitt-Versatz verschärfen
Einfarbige Fake-Kacheln erkannten nur die Herkunftskachel eines Pixels,
nicht den Versatz innerhalb der Kachel (72px Spielraum je Achse zwischen
3072px Kachelraster und 3000px Zuschnitt). fake_tile kodiert jetzt die
globale Pixelposition, ein neuer Test nagelt mosaic_origin_px() == (24, 60)
fest und prüft drei Pixel gegen den daraus berechneten globalen Index.
Produktionscode unverändert (Ruling 8).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-12 14:04:39 +02:00
knsoandClaude Sonnet 5 3d112e98cd feat(extract): Koordinaten, Kachel-Download und Mosaik
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-12 13:50:20 +02:00
knsoandClaude Opus 5 2280617d9e docs: zwei Planfehler in Aufgabe 1 korrigiert
- controls ist eine Pflichtoption von player.init; der Beispielcode übergab sie nicht,
  wodurch die App mit einem TypeError startete
- der git-add-Befehl hätte den Submodul-Pin still auf den lokalen Branch-Commit umgesetzt

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-12 13:44:53 +02:00
knsoandClaude Sonnet 5 fbe9b18b5e fix: Pflichtoption controls an player.init übergeben
player.init wirft ohne controls einen TypeError, da CameraSystem und
InputSystem intern auf controls.domElement/.target zugreifen (siehe
three-player-controller/src/systems/CameraSystem.ts,
three-player-controller/src/systems/InputSystem.ts). Eine
OrbitControls-Instanz auf renderer.domElement schließt die Lücke; der
Controller übernimmt die eigentliche Kamerasteuerung ohnehin selbst.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-12 13:42:11 +02:00
knsoandClaude Sonnet 5 b27b9b7a61 feat: App-Gerüst mit Spieler auf Testfläche
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-12 13:28:09 +02:00
knsoandClaude Opus 5 a523dce676 Umsetzungsplan für den Vice-City-Ausschnitt
12 Aufgaben mit 88 Schritten, von der Python-Extraktion über den
Geometrie-Baustein und das Chunk-Streaming bis zur Abnahme.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-12 13:19:52 +02:00
knsoandClaude Opus 5 a6662416a1 Design-Spec für den spielbaren Vice-City-Ausschnitt
Ausschnitt A (X -1000..2000, Y -500..2500) aus der Community-Karte YANIS v15;
Kartendaten von map.gtadb.org unter CC BY 4.0. Die Spec beschreibt Rechtslage,
Koordinaten, Projektstruktur, die siebenstufige Extraktion, die Laufzeit mit
Chunk-Streaming, Aussehen, Fehlerbehandlung, Tests und Budgets.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-12 13:07:21 +02:00