Files
Gartenvisualisierung/README.md
T
admGitAICDSandClaude Opus 5 70d239fe9c Begehbare 3D-Visualisierung des Gartens Egglihaldenstrasse 9a
Geometrie massstaeblich aus dem Gartenplan-PDF (1:100) extrahiert: Belaege,
Mauern, Pflanzenstandorte und 46 Hoehenkoten. Wohnhaus nach Gartenplan und
den Fassadenplaenen von EHLE Architekten.

- tools/: Pipeline PDF -> Szenenmodell (MuPDF, Node)
- src/: three.js-Szene mit prozeduralen Texturen, Rundgang und Uebersicht
- Docker/Traefik fuer garten.aicds.ch, Gitea-Workflow auf main

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-08 22:59:37 +02:00

166 lines
6.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Gartenvisualisierung Egglihaldenstrasse 9a
Begehbare 3D-Visualisierung des geplanten Gartens von Jasmin und Damian
Kellenberger, Egglihaldenstrasse 9a, 9030 Abtwil SG.
Live: **https://garten.aicds.ch**
Die gesamte Geometrie ist **massstäblich aus dem Gartenplan** abgeleitet – nicht
nachmodelliert. Ein Node-Werkzeug liest die Vektordaten direkt aus dem Plan-PDF,
rechnet sie in Meter um und erzeugt daraus das Szenenmodell.
---
## Grundlagen
| Quelle | Inhalt |
|---|---|
| `Info Dateien/Gartenplan 1 …pdf` | Garten Design AG, 14.08.2026, Massstab 1:100, A1 |
| `Info Dateien/20210427 - Projektpläne Haus 9a.pdf` | EHLE Architekten AG, Grundrisse, Fassaden, Umgebung |
| `Info Dateien/WhatsApp Image …jpeg` | Fotos des Ist-Zustands (Fassade, Beläge, Nachbarschaft) |
Die DWG wird nicht benötigt – das PDF enthält dieselbe Vektorgeometrie.
### Koordinatensystem
Alles rechnet im **Site-Frame**, in Metern:
- **X** – Hausachse ENE, Peilung 61.1615° gegen Nord
- **Z** – senkrecht dazu, SSE, Peilung 151.1615°
- **Y** – Höhe über dem Fixpunkt `0.00` = **651.17 m ü. M.** (OK Fertigboden EG)
Der Nordpfeil des Plans zeigt exakt zur Blattoberkante, das Zeichnungsraster
liegt um −28.8385° gedreht dazu. Der Massstab ist über das Plattenraster
verifiziert: die Keramikplatten messen sich auf 0.600 m genau.
### Höhen
| Bezug | relativ | absolut |
|---|---|---|
| Feuerwehrzufahrt, Nordwestecke | −2.08 | 648.09 m |
| Nachbargarten Zollet (Haus 9, OK FB EG) | −1.70 | 649.47 m |
| Hauptsitzplatz Travertin | −0.30 … −0.02 | 650.87 … 651.15 m |
| Fixpunkt Hauseingang | 0.00 | 651.17 m |
| Ostseite beim Apfelbaum | +0.63 | 651.80 m |
| OK Fertigboden Obergeschoss | +2.90 | 654.07 m |
| OK Attika Haus 9a | +6.15 | 657.32 m |
---
## Datenpipeline
```bash
npm run data # extract-plan + build-site
```
1. **`tools/extract-plan.mjs`** – öffnet das Plan-PDF mit MuPDF (WASM) und
protokolliert alle Zeichenoperationen mit. Ergebnis: rund 5400 Polygone,
234 Pflanzenkreise, 229 Beschriftungen und 46 Höhenkoten, transformiert in
den Site-Frame. → `tools/out/plan-raw.json`
2. **`tools/authoring.mjs`** – handgepflegte Ergänzungen: Zuordnung der
Planfarben zu Belagsarten, Mauerachsen und -höhen, Gebäudekubatur,
Geländezonen, Standorte. Alles kommentiert und auf Plan oder
Architekturpläne zurückgeführt.
3. **`tools/build-site.mjs`** – klassiert die Flächen, leitet Pflanzen und
Leuchten ab, interpoliert das Geländeraster (0.25 m) aus den Höhenkoten je
Zone und schreibt `public/data/site.json` (rund 110 kB).
Zur Kontrolle: `node tools/debug-svg.mjs` zeichnet die extrahierte Geometrie als
SVG-Draufsicht, `node tools/inspect-colors.mjs` listet die Planfarben mit den
nächstgelegenen Beschriftungen.
### Warum Zonen statt eines einzigen Geländes
Das Grundstück fällt über rund 3.5 m ab, die Sprünge liegen aber nicht im
Gelände, sondern in den Stützbauten: Travertinmauer zum Nachbargrundstück,
Winkelelemente aus Beton entlang der Feuerwehrzufahrt, Betonmauer im Süden.
Deshalb wird je Zone getrennt interpoliert – über die Zonengrenze hinweg nie.
Die Mauern erhalten ihr Kronen- und Fussprofil aus dem Gelände beider Seiten.
---
## Anwendung
```bash
npm install
npm run dev # http://localhost:5173
npm run build # dist/, rund 640 kB
```
Stack: Vite + TypeScript + three.js. **Keine externen Assets** – sämtliche
Texturen (Travertin, Keramik, Tegula, Rasen, Kies, Beton, Holzschalung,
Scheiterwand) werden zur Laufzeit prozedural auf ein Canvas gezeichnet. Die UVs
sind weltbezogen, damit die Plattenraster über Flächengrenzen hinweg durchlaufen
– so wie auf dem Plan.
### Bedienung
| | |
|---|---|
| Rundgang | Klicken, dann `W` `A` `S` `D`, `Shift` zum Rennen, `Esc` gibt die Maus frei |
| Handy | links Joystick, rechts wischen zum Umsehen |
| Übersicht | ziehen zum Drehen, Mausrad zum Zoomen |
| Tageszeit | Regler oben rechts, Sonnenstand astronomisch für Abtwil SG gerechnet |
Der Rundgang folgt dem Gelände, steigt Stufen bis 45 cm und wird von Mauern,
Gebäuden, Hecken und Objekten aufgehalten. Ab Dämmerung schalten die 17 Leuchten
des Plans automatisch ein.
### Aufbau
```
src/
site.ts Datenmodell und Höhen-Sampler
scene/textures.ts prozedurale Beläge und Materialien
scene/geometry.ts Polygone auf das Gelände legen, Mauern extrudieren
scene/terrain.ts Geländeraster und Umland
scene/surfaces.ts Beläge
scene/structures.ts Mauern, Stelen, Objekte, Leuchten
scene/vegetation.ts Gehölze, Hecken, Gräser, Stauden
scene/building.ts Wohnhaus 9a und Nachbargebäude
scene/environment.ts Himmel, Sonnenstand, Licht
controls/walker.ts Begehen mit Kollision und Geländeführung
ui/hud.ts Bedienoberfläche
```
---
## Deployment
Push auf `main` löst den Gitea-Workflow aus; die App landet unter
`/opt/aicds/apps/Gartenvisualisierung/` und wird per `docker compose` gebaut.
Traefik-Router `garten`, Host `garten.aicds.ch`, Netzwerk `agent-net`.
```bash
docker compose config # Prüfung vor dem Push
docker compose up -d --build
```
Das Image enthält nur `dist/` hinter nginx – die Planunterlagen und Fotos aus
`Info Dateien/` werden über `.dockerignore` ausgeschlossen und gelangen nie in
den Webcontainer.
---
## Was bewusst interpretiert ist
Der Plan ist ein Situationsplan; einiges steht nur als Beschriftung darin. Diese
Annahmen stecken in `tools/authoring.mjs` und sind dort einzeln kommentiert:
- **Mauerhöhen** aus den Höhenkoten beidseits abgeleitet; die gelbe Kote `25`
bei der Sitzmauer als 25 cm Aufkantung gelesen, `35` bei den Heidelbeeren
analog.
- **Lamellenwand zum Sitzen** als senkrechte Holzlamellen im Planrhythmus
(10 cm breit, 35 cm tief, rund 90 cm Achsabstand), passend zum Foto des
Ist-Zustands.
- **Wohnhaus** in Kubatur und Öffnungen nach Gartenplan und Fassadenplänen,
Materialisierung nach den Fotos: vertikale Holzschalung graubraun, heller
Betonsockel, Flachdach mit extensiver Begrünung.
- **Nachbarhaus Zollet** als einfaches Kontextvolumen, 1.70 m tiefer liegend.
- **Solitärgehölze** mit den Kronenradien des Plans; Wuchshöhen als
Erfahrungswerte.
- **Gartenhaus, Spielhaus, Flammengrill, Bänkli** in Lage und Grundfläche nach
Plan, in der Ausformulierung frei.