docs: GIS plan — 6 steps with diagrams + Blender render service

Each step has diagrams, input/output schemas, test cases.
Added Step 6: mother-blender-render — photorealistic 3D via
Blender on mother node. USB requests renders via MCP, same
pattern as build-colibri.sh. 1 GiB Blender stays on mother;
light nodes get PNGs back. ~30h total implementation estimate.
This commit is contained in:
Sam & Claude 2026-06-23 14:16:28 +02:00
parent 95deca5f1d
commit f5b4326731

View file

@ -1,101 +1,267 @@
# GIS Integration Plan — Geodesic Dome on Real Property
# GIS Integration — Step-by-Step Implementation Plan
2026-06-23 | Research phase | Not yet implemented
2026-06-23 | Specification phase | No code yet
## Goal
## Overview
Replace AI-invented farm backgrounds with real user property data. Given an
address in Slovenia, overlay a geodesic dome with correct orientation, scale,
and boundary constraints. Generate a site-specific bill of materials.
Six standalone MCP tools, each one layer of the stack. Each tool is
independently testable, accepts JSON-RPC on stdin, returns JSON on stdout.
All tools run on the mother node (OSA) and are registered in
`/usr/local/etc/colibri/external-mcp.json`.
## Data sources
---
### GURS — Geodetska Uprava Republike Slovenije (free, CC BY 4.0)
## Step 1: `gurs-address-lookup` — Address → Coordinates + Parcel ID
| Dataset | Endpoint | What it provides |
### Input
```json
{
"address": "Na vrtu 5",
"postal_code": "1000",
"municipality": "Ljubljana"
}
```
### Implementation
1. WFS GetFeature to GURS Register naslovov
- Filter: `ULICA='Na vrtu' AND HISNA_STEVILKA='5' AND POSTNA_STEVILKA='1000'`
- EPSG 3794 → reproject to EPSG 4326
2. Parse: coordinates, parcel ID, land use code
3. Multiple results: return all, let caller pick
4. No results: partial match, suggest alternatives
### Output
Lat/lon + parcel ID + cadastral municipality + land use code.
### Diagram
```
User "Na vrtu 5, 1000 LJ"
┌──────────────────────────┐
│ GURS Register naslovov │
│ WFS GetFeature │
│ │
│ → 46.0514, 14.5060 │
│ → parcel 1724/3 │
│ → stavbno zemljišče │
└──────────────────────────┘
```
---
## Step 2: `gurs-parcel-boundary` — Parcel ID → Boundary + Metadata
### Implementation
1. WFS GetFeature to GURS Kataster nepremičnin (collection: `parcele`)
2. Compute: area, centroid, inscribed circle, setback compliance
3. Query GJI for road/utility access
4. Check OPSI orthophoto availability
### Output
Boundary GeoJSON + area + inscribed circle + infrastructure distances + setbacks.
### Diagram
```
┌─────────────────────────────────┐
│ ┌───┐ │
│ │old│ existing building │
│ └───┘ │
│ · centroid │
│ ○ inscribed circle r=14.5m │
│ │
│ 850m², stavbno zemljišče │
│ road: 8m, power: 15m │
│ setback compliant for 5m dome │
└─────────────────────────────────┘
```
---
## Step 3: `dome-placement` — Optimal Dome Position
### Implementation
1. Inscribed circle search (binary search from centroid)
2. Orientation: entrance faces south, ramp fits within parcel
3. Ground slope from GURS DMR (optional)
4. Collision check against buildings/utilities
5. Sun path: winter solstice shadow analysis
### Output
Center coordinates + orientation + fit quality rating + conflicts + sun/shadow.
### Diagram
```
N
┌──────────────────────────┐
│ · · · parcel · · · · · │
│ · ┌───┐ · │
│ · │old│ ╭──────╮ · │
│ · │bld│ │ DOME │ · │
│ · └───┘ │ r=5m │ · │
│ · │ ▸ │ · │
│ · ╰──────╯ · │
│ · entrance · │
│ · SOUTH · │
└──────────────────────────┘
setback 4m ✓, no conflicts ✓
winter shadow: 8.2m → NW (away from neighbor)
```
---
## Step 4: `geodesic-dome-mcp` — Site-Context BOM
Already implemented: wireframes, BOM, strut constraint, construction layers.
New: site context from Steps 2-3.
### New output
- Foundation type based on frost depth + slope
- Access path length + gravel estimate
- Rebar updated with foundation starter bars
- Local Eurocode constants applied
### BOM Diagram
```
Item │ Qty │ Cost
──────────────────┼──────┼──────
FI12 rebar 6m │ 62 │ €372
Concrete C25/30 │ 3.1m³│ €310
Gravel 0-32mm │ 2.4t │ €48
Glass 4mm temper │196m² │€4910
5-way connectors │ 14 │ TBD
6-way connectors │ 44 │ TBD
──────────────────┼──────┼──────
Foundation depth: 0.9m (frost 0.8m)
Snow load: 1.5 kN/m² (zone A2)
Wind: 25 m/s (zone 2)
Seismic: 0.175g PGA
```
---
## Step 5: `dome-site-render` — Composite Visualization
### Three options
| Option | Cost | Quality | Effort |
|---|---|---|---|
| A: OPSI orthophoto overlay | Free | Good (2D site plan) | ~4h |
| B: Google 3D Tiles | Paid | Excellent (3D photoreal) | ~8h |
| C: Gemini AI-enhanced | ~$0.04 | Good (4K composite) | ~1h |
### Option C (quickest path)
1. Pass orthophoto + dome wireframe as Gemini reference images
2. Prompt: "Photorealistic vegetation matching Slovenian landscape..."
3. Output: 4K composite PNG
### Diagram
```
┌────────────────────────────────────┐
│ 3D Perspective — Dome on Site │
│ │
│ ╱▔▔▔╲ │
DOME ╲ │
r=5m ╲ │
╱▔▔▔▔▔▔▔╲ ╲ │
wireframe ╲ ╲ │
subdivision ╲ ╲ │
│ ╱▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔╲ │
│ ▕ ░░░░░░░░░░░░░░░░░░ ▏ │
│ ▕ ░░ actual terrain ░ ▏ │
│ ───────────────────────── │
│ │
│ Background: OPSI orthophoto │
│ Overlay: geodesic-dome-mcp │
│ Enhance: Gemini AI │
└────────────────────────────────────┘
```
---
## Step 6: `mother-blender-render` — Photorealistic 3D via Mother
Heavy nodes (USB) request renders from mother. Same MCP pattern as `build-colibri.sh`.
### Architecture
```
USB (light node) Mother (OSA, Blender 5.0)
│ │
│ MCP: blender_render({...}) │
├─────────────────────────────►│
│ ├─ blender --background --python dome_render.py
│ │ Cycles/EEVEE, 4K, materials, vegetation
│◄─────────────────────────────┤
│ image_path + metadata │
│ │
│ scp binary from mother │
└──────────────────────────────┘
```
### Capabilities
- Cycles path-traced rendering (photorealistic)
- EEVEE real-time rendering (fast previews)
- PBR materials (glass, steel, concrete, wood)
- Terrain + foundation extrusion
- Vegetation particle scattering
- Sun position + shadow study (any date/time)
- 360° turntable animation
- DXF/STL export (CNC-ready)
- 4K+ native resolution
### Render times (OSA, 6-core CPU, no GPU)
- Wireframe: ~5s (EEVEE)
- Materials + lighting: ~5min (Cycles 128)
- Full scene + vegetation: ~15-30min (Cycles 256, 4K)
### Blender render pipeline diagram
```
┌──────────────────────────────────────────┐
│ Mother Blender Render Pipeline │
│ │
│ Scene JSON ──► dome_render.py ──► PNG │
│ │ │
│ ▼ │
│ ┌──────────────┐ │
│ │ • icosphere │ │
│ │ • wireframe │ │
│ │ • materials │ │
│ │ • lighting │ │
│ │ • camera rig │ │
│ │ • terrain │ │
│ │ • vegetation │ │
│ └──────────────┘ │
│ │
│ Queue: /var/db/geodesic/render-queue/ │
│ Cache: /var/db/geodesic/renders/ │
│ TTL: 7 days │
└──────────────────────────────────────────┘
```
---
## Implementation Priority
| Step | Effort | Priority |
|---|---|---|
| Kataster nepremičnin | `wfs-si-gurs-kn` | Parcel boundaries, land use codes |
| Register prostorskih enot | `wfs-si-gurs-rpe` | Spatial units, cadastral districts |
| Zbirni kataster GJI | `wfs-si-gurs-kgi` | Public infrastructure (roads, utilities) |
| Register naslovov | `wfs-si-gurs-rn` | Address → coordinate lookup |
| Step 1: address lookup | ~2h | 1 — unlocks everything |
| Step 2: parcel boundary | ~3h | 2 |
| Step 3: dome placement | ~4h | 3 |
| Step 4: site BOM | ~2h | 4 |
| Step 5: AI render | ~1h | 5 |
| Step 5: orthophoto | ~4h | 6 |
| Step 6: Blender render | ~6h | 7 |
| Step 5: Google 3D | ~8h | 8 |
All available via OGC WFS at `ipi.eprostor.gov.si`. EPSG 3794 (D96/TM).
License: CC BY 4.0 — free for commercial use with attribution.
Total: ~30h for complete pipeline.
### Google Photorealistic 3D Tiles (paid)
## Slovenian building code (Eurocode)
- OGC 3D Tiles format, 2500 cities, 49 countries
- Slovenia coverage: likely Ljubljana, Maribor, major cities
- Cost: Google Maps Platform pricing (pay per tile request)
- Renderer: CesiumJS (open source), Three.js, or custom
### OPSI — Odprti Podatki Slovenije (free)
- National open data portal at `podatki.gov.si`
- DOF (digital orthophoto) available for download
- Building footprints, land use, environmental data
## Integration steps
### Phase 1: Address → parcel boundary (GURS WFS)
```
User provides: "Na vrtu 5, 1000 Ljubljana"
→ GURS Register naslovov → coordinates (EPSG 3794)
→ GURS Kataster nepremičnin → parcel polygon
→ Returns: boundary GeoJSON, area m², land use code
```
### Phase 2: Dome placement optimization
```
Input: parcel polygon, dome radius, minimum setbacks
→ Find largest inscribed circle → center point
→ Orient dome entrance to south (passive solar)
→ Check setbacks from parcel edges
→ Returns: optimal center coordinates, rotation angle, max radius
```
### Phase 3: Render overlay
```
Input: parcel boundary, dome geometry, background tiles
→ Generate dome wireframe at correct geo position
→ Overlay on orthophoto (OPSI DOF) or 3D Tiles (Google)
→ Export: site plan PNG, 3D perspective render
→ Returns: visualization, site plan with measurements
```
### Phase 4: Site-specific BOM
```
Input: dome geometry, parcel constraints, local material prices
→ Adjust foundation type based on land use code
→ Calculate access road length from nearest GJI road
→ Local vendor pricing (to be added per region)
→ Returns: adjusted BOM with site-specific costs
```
## What exists today
| Component | Status |
| Parameter | Central Slovenia |
|---|---|
| `geodesic-dome-mcp` | ✅ Working — wireframes, BOM, strut constraints, construction layers |
| GURS parcel lookup | ❌ Not yet — WFS endpoints documented, need MCP tool |
| Address → coordinates | ❌ Not yet — GURS Register naslovov WFS available |
| Google 3D Tiles render | ❌ Not yet — requires API key, CesiumJS integration |
| Parcel boundary polygon | ❌ Not yet — GURS Kataster WFS available |
| Dome placement optimizer | ❌ Not yet — simple algorithm, can be pure Python |
## Next steps
1. Build `gurs-parcel-mcp` — address → parcel boundary (GURS WFS client)
2. Build `dome-placement-mcp` — optimal dome position on parcel
3. Integrate with `geodesic-dome-mcp` — pass boundary constraints
4. Optional: Google 3D Tiles for photorealistic background
## Reference
- GURS WFS base: `https://ipi.eprostor.gov.si/wfs-si-gurs-kn/ogc/features`
- License: `https://creativecommons.org/licenses/by/4.0/`
- Attribution: "Geodetska uprava Republike Slovenije, [dataset name], [date]"
| Frost depth | 0.8m |
| Snow load | 1.5 kN/m² (≤500m) |
| Wind speed | 25 m/s |
| Seismic PGA | 0.175g |
| Setback | 4.0m |