docs: Task 6b für die Kartenbeschriftung, Löcher in Task 7
Die Sichtprüfung nach Task 6 hat gezeigt, dass die Beschriftungen der Originalkarte zu Geometrie werden — "VICE CITY (MIAMI)" steht als 1.600 m breiter Schriftzug in der Bucht. Task 6b entfernt sie, bevor Task 7 daraus Meshes baut. Der Brief nennt drei gemessene Sackgassen (Buntheit, Farbton, Zusammenhang nur der Straßenmaske) und den Weg, der trägt: auf Regionenebene über alle Nicht-Wasser-Klassen, wo die Buchstaben eigene Inseln ohne jedes natürliche Merkmal bilden. extrudePolygons und flatPolygons in Task 7 verarbeiten jetzt Ringlisten mit Löchern statt einzelner Ringe, passend zu Ruling 34. overview.py rendert den ganzen Ausschnitt aus den Chunk-Dateien; damit ist der Beschriftungsfehler überhaupt erst aufgefallen. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
ce90ea1d5f
commit
062a9af2fd
2 files changed
+302
-37
No files matched your search
@@ -0,0 +1,80 @@
|
||||
"""Gesamtansicht des Ausschnitts aus den fertigen Chunk-Dateien.
|
||||
|
||||
Zeichnet ausschließlich das, was wirklich ausgeliefert wird — kein Kartenbild darunter.
|
||||
Damit fallen Fehler auf, die kein Unit-Test sieht: gespiegelte Achsen, versetzte Chunks,
|
||||
Beschriftungen der Originalkarte, die als Geometrie durchgerutscht sind.
|
||||
|
||||
cd tools/extract && uv run python overview.py
|
||||
"""
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
from PIL import Image, ImageDraw
|
||||
|
||||
from leonida.coords import SLICE
|
||||
|
||||
OUT = Path("../../public/data/vice-a")
|
||||
DST = Path("debug/overview.png")
|
||||
SCALE = 0.5 # Pixel je Meter
|
||||
WATER = (36, 72, 104)
|
||||
LAND = (150, 162, 120)
|
||||
SURFACE = {"sand": (226, 210, 150), "park": (120, 160, 90), "urban": (176, 176, 172)}
|
||||
ROAD = (74, 74, 78)
|
||||
BRIDGE = (196, 92, 92)
|
||||
PALM = (40, 190, 70)
|
||||
TALL = 120.0 # Meter, ab der ein Gebäude die hellste Färbung bekommt
|
||||
|
||||
|
||||
def _to_px(ring, ox, oy):
|
||||
"""Chunk-lokale three.js-Koordinaten (x, z) -> Bildpixel."""
|
||||
return [((x + ox - SLICE["x0"]) * SCALE, (SLICE["y1"] - (oy - z)) * SCALE) for x, z in ring]
|
||||
|
||||
|
||||
def _draw(draw, rings, ox, oy, fill, outline=None):
|
||||
"""Außenring füllen, Löcher wieder mit Wasserfarbe ausstanzen."""
|
||||
draw.polygon(_to_px(rings[0], ox, oy), fill=fill, outline=outline)
|
||||
for hole in rings[1:]:
|
||||
draw.polygon(_to_px(hole, ox, oy), fill=WATER)
|
||||
|
||||
|
||||
def render(out_dir: Path, dst: Path) -> dict:
|
||||
size = int((SLICE["x1"] - SLICE["x0"]) * SCALE)
|
||||
img = Image.new("RGB", (size, size), WATER)
|
||||
draw = ImageDraw.Draw(img)
|
||||
chunks = [json.loads(f.read_text()) for f in sorted(out_dir.glob("chunk_*.json"))]
|
||||
stats = {"land": 0, "strassen": 0, "bruecken": 0, "gebaeude": 0, "palmen": 0}
|
||||
|
||||
# Ebene für Ebene über alle Chunks, damit nichts von einem Nachbarchunk überdeckt wird.
|
||||
for chunk in chunks:
|
||||
ox, oy = chunk["origin"][0], -chunk["origin"][1]
|
||||
for rings in chunk["land"]:
|
||||
_draw(draw, rings, ox, oy, LAND)
|
||||
stats["land"] += 1
|
||||
for chunk in chunks:
|
||||
ox, oy = chunk["origin"][0], -chunk["origin"][1]
|
||||
for surface in chunk["surfaces"]:
|
||||
_draw(draw, surface["poly"], ox, oy, SURFACE[surface["kind"]])
|
||||
for chunk in chunks:
|
||||
ox, oy = chunk["origin"][0], -chunk["origin"][1]
|
||||
for road in chunk["roads"]:
|
||||
_draw(draw, road["poly"], ox, oy, BRIDGE if road["bridge"] else ROAD)
|
||||
stats["bruecken" if road["bridge"] else "strassen"] += 1
|
||||
for chunk in chunks:
|
||||
ox, oy = chunk["origin"][0], -chunk["origin"][1]
|
||||
for building in chunk["buildings"]:
|
||||
t = min(1.0, building["height"] / TALL)
|
||||
shade = (int(70 + 170 * t), int(70 + 120 * t), int(80 + 60 * t))
|
||||
_draw(draw, building["poly"], ox, oy, shade, outline=(30, 30, 30))
|
||||
stats["gebaeude"] += 1
|
||||
for x, z in chunk["palms"]:
|
||||
px, py = _to_px([(x, z)], ox, oy)[0]
|
||||
draw.ellipse([px - 1.6, py - 1.6, px + 1.6, py + 1.6], fill=PALM)
|
||||
stats["palmen"] += 1
|
||||
|
||||
dst.parent.mkdir(parents=True, exist_ok=True)
|
||||
img.save(dst)
|
||||
return stats
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print(render(OUT, DST), "->", DST)
|
||||
Reference in new issue
Block a user