Standalone-Browser-Port von DOSSIER. Enthaelt das semantische Modell mit Plan-/3D-Ableitung, Zeichen- und Editierwerkzeuge, Rhino-artiges Befehlssystem, dockbares Panel-System, Resource-Manager, DXF/.lin/.pat-Import, i18n (de/en) sowie Projektdokumentation und Probe-Harness.
31 KiB
Swisstopo-Geodaten & SIA-Flächenstandards im Browser-BIM
Stand: 2026-06-29 · Recherche für das Standalone-Browser-BIM (React + TS + Three.js), Port von DOSSIER (Rhino-Plugin). Ziel: (A) Schweizer Geodaten (Höhenmodell, Orthofoto, 3D-Gebäude, Parzellen) direkt im Browser laden, (B) Standort-Kontext (Gelände + Parzelle + Nachbargebäude) für ein Projekt importieren, (C) SIA-416- Flächen/Volumen + Raumschemata berechnen wie in DOSSIER.
Bezug zur ROADMAP: Swisstopo/Terrain/OSM = Phase 4 (Kontext/Daten); SIA-416- Räume + Bilanz-CSV = Phase 2. Beide sind dort bereits als ⭐-Features gelistet.
Alle in diesem Dokument genannten geo.admin.ch-Endpunkte wurden am 2026-06-29 live gegen die echte API getestet (curl + CORS-Header-Check). Wo „verifiziert" steht, liegt eine echte Antwort vor.
Teil A — Swisstopo-APIs & Dienste aus dem Browser
A.0 Das Wichtigste vorweg: CORS & Lizenz
Zwei Fragen entscheiden, ob ein Dienst ohne Backend-Proxy aus einer reinen Browser-App nutzbar ist: CORS und Lizenz. Beide sind hier günstig.
CORS (live verifiziert): Alle relevanten Hosts senden access-control-allow-origin: *:
| Host | Dienst | CORS | Range-Requests |
|---|---|---|---|
api3.geo.admin.ch |
REST (height, profile, identify, find, search) | ✅ * |
— |
data.geo.admin.ch |
STAC-API + Daten-Assets (COG-GeoTIFF, XYZ.zip) | ✅ * |
✅ 206 Partial Content, accept-ranges/content-range vorhanden |
wmts.geo.admin.ch |
WMTS-Kacheln | ✅ * |
— |
3d.geo.admin.ch |
3D-Tiles (tileset.json + glTF) |
✅ * |
— |
→ Konsequenz: Höhenabfrage, Geocoding, Parzellen-Identify, Karten-/Orthofoto- Kacheln, COG-GeoTIFF-Höhenmodell per Range-Request und 3D-Tiles sind direkt aus dem Browser ohne eigenen Proxy abrufbar. Das ist ein großer Vorteil gegenüber vielen anderen nationalen Geodiensten.
Lizenz: swisstopo/geo.admin.ch ist Open Government Data: „The acquisition and
use of data or services is free of charge, subject to the provisions on fair use."
Kommerzielle Nutzung ist erlaubt, Einbindung in (auch kommerzielle) Web-Apps explizit
gedeckt. Pflicht-Attribution: © swisstopo (bzw. „© Data: swisstopo"). „Fair use"
= z.B. Web-App mit Ø 20'000 Nutzern/Tag ok; aggressives Bot-Scraping vermeiden. Haftung
ausgeschlossen, ~98% Verfügbarkeit. Terms of use FSDI
⚠️ Korrektur zu DOSSIER & zur Doku: Die offizielle REST-Doku notiert beim Height-Service „This service is not freely accessible (fee required)". Das ist in der Praxis falsch / veraltet: Der Endpunkt antwortet anonym, ohne Key, mit
200und CORS*(verifiziert, siehe A.1). DOSSIERs Aussage „alle APIs offen, ohne Auth, ohne Key" deckt sich mit der gemessenen Realität. Wir verlassen uns aber nicht blind darauf, sondern behandeln 402/429 defensiv (Retry/Backoff, Cache).
A.1 Höhenabfrage — Height-Service (Einzelpunkt)
Punkt-Höhe (DTM) aus swissALTI3D/DTM. Verifiziert:
GET https://api3.geo.admin.ch/rest/services/height?easting=2600000&northing=1200000&sr=2056
→ {"height":"555.5"}
Parameter:
easting,northing— LV95 (sr=2056) oder LV03 (sr=21781). Pflicht.sr—2056(LV95) angeben, sonst Default21781.elevation_model—DTM2(= swissALTI3D, 2 m),DTM25(Default),COMB. (Im Tal lieferten DTM2/DTM25/COMB denselben Wert; im Steilgelände kann DTM2 genauer sein.)callback— JSONP (brauchen wir wegen CORS nicht).
Nutzung im Tool: Projekt-Nullpunkt-Z bzw. „Gebäude auf Gelände setzen" — eine einzelne Höhe an der Projekt-Koordinate. Antwortzeit ~50–150 ms. Quelle: GeoAdmin REST – Height
A.2 Höhenprofil — Profile-Service (Schnittlinie)
Höhen entlang einer Polylinie — ideal für Geländeschnitt unter einem Gebäude-Schnitt. Verifiziert (echte Werte zurück):
GET https://api3.geo.admin.ch/rest/services/profile.json
?geom={"type":"LineString","coordinates":[[2600000,1200000],[2600200,1200000]]}
&sr=2056&nb_points=3
→ [{"alts":{"COMB":555.5,"DTM2":555.5,"DTM25":555.5},"dist":0,"easting":2600000,"northing":1200000},
{"alts":{...},"dist":100,...}, {"dist":200,...}]
Parameter: geom (GeoJSON-LineString, max 6'000 Punkte), sr, nb_points (Anzahl
Stützpunkte, Default 200), elevation_models, offset (Glättung). Auch als
profile.csv. → Für 2D-Geländeschnitte ohne Mesh-Download. Quelle:
GeoAdmin REST – Profile
A.3 swissALTI3D — Höhenmodell als COG-GeoTIFF (Mesh-Quelle) ⭐
Das ist der Schlüssel für das Gelände-Mesh im Browser. swissALTI3D ist das präzise
DTM der Schweiz (ohne Vegetation/Bebauung), Auflösung 0.5 m / 2 m, alle 6 Jahre
aktualisiert (swissALTI3D).
Bezug über die STAC-API (verifiziert — Tile swissalti3d_2019_2599-1198):
GET https://data.geo.admin.ch/api/stac/v1/collections/ch.swisstopo.swissalti3d/items
?bbox=<lonMin,latMin,lonMax,latMax>&limit=...
Jedes 1×1-km-Tile liefert pro Auflösung zwei Asset-Typen:
| Asset | Typ | Browser-tauglich? |
|---|---|---|
..._0.5_2056_5728.tif / ..._2_2056_5728.tif |
Cloud-Optimized GeoTIFF, EPSG:2056 | ✅ direkt via geotiff.js + Range |
..._0.5_2056_5728.xyz.zip / ..._2_..._xyz.zip |
ASCII-XYZ (E N Z) in ZIP | ✅ via fflate entpacken (so macht es DOSSIER) |
Verifiziert: data.geo.admin.ch liefert auf das .tif ein 206 Partial Content
mit content-range bei Range:-Header und CORS *. Das bedeutet: geotiff.js
liest nur den benötigten Ausschnitt eines COG per HTTP-Range, ohne das ganze File zu
laden — perfekt für eine Browser-App. Bbox in WGS84 für STAC, Tile-Daten dann in
LV95-Metern (kein Reprojizieren der Z-Werte nötig). Quelle:
STAC tech docs · COG-Tile live geprüft.
A.4 SWISSIMAGE / Karten — WMTS-Kacheln
Orthofoto (10 cm) und Landeskarten als Kacheln. RESTful-URL-Template:
https://wmts.geo.admin.ch/1.0.0/<Layer>/default/<Time>/<TileMatrixSet>/<z>/<TileCol>/<TileRow>.<ext>
Beispiel-Layer:
ch.swisstopo.swissimage— Orthofoto,.jpegch.swisstopo.pixelkarte-farbe— Landeskarte farbig,.jpegch.kantone.cadastralwebmap-farbe— Katasterplan (AV),.png
TileMatrixSets: 2056 (LV95), 21781, 3857 (Web-Mercator), 4326. Zoom 0–28
(4000 m → 0.1 m); Zoom 27/28 nur für wenige Layer (swissimage, Kataster). Für 3D in
Three.js am einfachsten 3857 (Standard-Slippy-Map-Schema, z/x/y), z.B.
https://wmts.geo.admin.ch/1.0.0/ch.swisstopo.swissimage/default/current/3857/{z}/{x}/{y}.jpeg
Für planimetrisch exakte 2D-Arbeit besser 2056. CORS * (verifiziert). Quellen:
WMTS docs ·
WMTS service ·
WMTS EPSG:2056 CodePen.
Es gibt zusätzlich klassisches WMS (
https://wms.geo.admin.ch/, GetMap mit beliebiger BBox/Größe, ebenfalls EPSG:2056). Für ein einzelnes georeferenziertes Orthofoto-Rechteck unter dem Modell ist ein WMS-GetMap manchmal praktischer als WMTS-Kacheln zu stitchen. WMS docs
A.5 swissBUILDINGS3D — Nachbargebäude (3D)
Zwei Wege:
(a) 3D-Tiles (Streaming, Cesium-Format) — glTF/tileset.json, für große Gebiete:
https://3d.geo.admin.ch/<Layer>/<Version>/<Time>/tileset.json
Layer u.a. ch.swisstopo.swissbuildings3d.3d, ch.swisstopo.swisstlm3d.3d,
ch.swisstopo.swissnames3d.3d, ch.swisstopo.vegetation.3d. Version = v1, Time
optional (ISO YYYYMMDD, weglassen = aktuellste). CORS * (verifiziert auf
tileset.json). Direkt für CesiumJS gedacht; in reinem Three.js über
@loaders.gl/3d-tiles oder den 3DTilesRendererJS (NASA-AMMOS/three.js-Community)
ladbar. 3D-Tiles docs ·
Switzerland in 3D
(b) STAC-Tiles als CAD/Mesh-Datei (Download pro Tile) — so macht es DOSSIER:
Collections ch.swisstopo.swissbuildings3d_3_0 (neu; in Städten z.T. >700 MB Tiles)
und ch.swisstopo.swissbuildings3d_2 (1-km-Tiles, ~50 MB, stabil). Assets in
.dxf/.dwg/.obj/.ifc (+ .zip), Varianten solid/separated. Für den Import als
echte, editierbare Massen ins eigene Modell ist der OBJ/IFC-Tile-Weg besser als
3D-Tiles (die sind read-only Visualisierung). swissBUILDINGS3D: >3 Mio Gebäude,
Lage-/Höhengenauigkeit 30–50 cm.
→ Empfehlung: Für „Nachbarschaft als Kontext anzeigen" (Phase 4 Start) 3D-Tiles streamen (kein Download, kein Parsing). Wenn der Nutzer Nachbargebäude als Geometrie braucht (Verschattung, Abstand), STAC-OBJ-Tile laden und als Mesh importieren.
A.6 Parzelle / Kataster (AV) — Identify-Service ⭐
Verifiziert — Parzellen-Polygon aus einer Koordinate, in LV95:
GET https://api3.geo.admin.ch/rest/services/api/MapServer/identify
?geometry=2600423,1199521&geometryType=esriGeometryPoint
&imageDisplay=100,100,96&mapExtent=2600323,1199421,2600523,1199621
&tolerance=2&layers=all:ch.kantone.cadastralwebmap-farbe
&returnGeometry=true&geometryFormat=geojson&sr=2056
→ {"results":[{"type":"Feature","bbox":[...],
"geometry":{"type":"Polygon","coordinates":[[ [2600377.1,1199523.7], ... ]]},
"attributes":{"number":"698","egris_egrid":"CH507635214670","ak":"BE", ...}}]}
- Parzellen-Layer:
ch.kantone.cadastralwebmap-farbe(liefertnumber,egris_egrid= EGRID, Kanton; mitreturnGeometry=true&geometryFormat=geojsondas Parzellen-Polygon in LV95-Metern → direkt als Grundstücksgrenze importierbar). - Gebäudeadressen:
ch.swisstopo.amtliches-gebaeudeadressverzeichnis; Gebäude-/ Wohnungsregisterch.bfs.gebaeude_wohnungs_register(EGID). - Pflichtparameter:
geometry,geometryType(esriGeometryPoint|...Polygon|...Envelope),mapExtent,imageDisplay,tolerance;sr=2056; max 50 Features/Request.
Quellen: Identify features · GeoAdmin REST – Identify/Find · Live-Antwort oben.
A.7 Geocoding — SearchServer (Adresse → LV95)
Verifiziert (Adresse → Koordinate, deckt sich mit DOSSIERs geocode()):
GET https://api3.geo.admin.ch/rest/services/api/SearchServer
?searchText=Bundesplatz 3 Bern&type=locations&origins=address&sr=2056&limit=1
→ results[0].attrs: { label:"Bundesplatz 3 <b>3011 Bern</b>", lat:46.94677, lon:7.44419,
geom_st_box2d:"BOX(2600423.26 1199521.11, ...)", origin:"address", ... }
type=locations,originsaus{address, parcel, gg25, gazetteer, zipcode, district, kantone},sr=2056. Im LV95-Modus liefert die Geo-Admin-Konventiony=East,x=North (DOSSIER liest genau so:e=attrs.y,n=attrs.x). Labels enthalten<b>-Tags (strippen).type=featuresearch+features=<layer>durchsucht Attribute (z.B. Parzellennummer).
Quelle: Search · Live-Antwort oben.
A.8 Koordinatensystem LV95 / EPSG:2056 & Transformationen
Intern rechnet das BIM-Tool in Metern (ROADMAP-Konvention) und verschiebt den
Projekt-Ursprung nahe (0,0,0); LV95-Koordinaten sind ~2.6 Mio / 1.2 Mio Meter groß und
würden bei float32 (Three.js) zu Jitter führen → Origin-Shift Pflicht (siehe B.3).
DOSSIER macht genau das (origin_shift/shift_lv95, typ. bbox-Center → 0/0/0).
Transformations-Optionen:
-
proj4(npmproj4@2.20.9) — universell, exakt. EPSG:2056-Definition:proj4.defs("EPSG:2056", "+proj=somerc +lat_0=46.9524055555556 +lon_0=7.43958333333333 +k_0=1 "+ "+x_0=2600000 +y_0=1200000 +ellps=bessel "+ "+towgs84=674.374,15.056,405.346,0,0,0,0 +units=m +no_defs +type=crs"); const [e,n] = proj4("EPSG:4326","EPSG:2056",[lon,lat]); // WGS84→LV95Genauigkeit mit dieser 3-Parameter-
towgs84~1 m (für Kontext-Import völlig ausreichend). Types:@types/proj4. Quellen: epsg.io/2056 · proj4js. -
Näherungsformeln (CH1903→WGS84, swisstopo) — DOSSIERs Ansatz, ~1 m genau, 0 Dependencies (zwei kleine Funktionen
lv95_to_wgs84/wgs84_to_lv95). 1:1 nach TS portierbar; gut, wenn manproj4nicht ziehen will. Reicht, weil STAC-Queries ohnehin nur eine grobe WGS84-Bbox brauchen und alle Daten schon in LV95 kommen. -
swisstopo REFRAME Web-API — cm-genaue offizielle Umrechnung (LV95↔WGS84, LN02↔Bessel). Nur nötig, wenn Vermessungs-Genauigkeit verlangt wird. REST, online. REFRAME Web
Empfehlung: proj4 mit fester EPSG:2056-Def (eine Abhängigkeit, exakt genug,
wartungsarm) — oder, wenn Dependency-Geiz, DOSSIERs Formeln portieren. REFRAME nur bei
Bedarf nachrüsten.
A.9 Endpoint-Übersicht (Spickzettel)
| Zweck | Endpoint | Frei/CORS | Format |
|---|---|---|---|
| Punkt-Höhe | api3…/rest/services/height |
✅ ✅ | JSON |
| Höhenprofil (Schnitt) | api3…/rest/services/profile.json |
✅ ✅ | JSON/CSV |
| Gelände-Mesh (COG) | STAC …/swissalti3d/items → .tif (COG, 2056) |
✅ ✅ Range | GeoTIFF |
| Gelände (ASCII) | STAC …/swissalti3d → .xyz.zip |
✅ ✅ | XYZ in ZIP |
| Orthofoto/Karte | wmts…/1.0.0/<layer>/…/{z}/{x}/{y}.jpeg |
✅ ✅ | Kacheln |
| 3D-Nachbargebäude (stream) | 3d…/ch.swisstopo.swissbuildings3d.3d/v1/tileset.json |
✅ ✅ | 3D-Tiles/glTF |
| 3D-Gebäude (Datei) | STAC …/swissbuildings3d_2 → .obj/.ifc |
✅ ✅ | OBJ/IFC |
| Parzelle/Kataster | api3…/MapServer/identify layers=all:ch.kantone.cadastralwebmap-farbe |
✅ ✅ | GeoJSON |
| Geocoding | api3…/SearchServer?type=locations |
✅ ✅ | JSON |
Teil B — Standort-Kontext importieren (Terrain + Parzelle + Nachbargebäude)
So bekommt ein Projekt seinen realen Kontext „auf Knopfdruck". Der Ablauf folgt
DOSSIER (rhino/swisstopo.py), übersetzt auf Browser-Libs.
B.1 Pipeline (End-to-End)
Adresse/Parzelle ──SearchServer──▶ Zentrum (E,N) in LV95
│
├─ radius r ──▶ bbox_LV95 (E±r, N±r) ──proj4/Formeln──▶ bbox_WGS84
│
├─[Parzelle] identify(cadastralwebmap, point) ─▶ Polygon (LV95) ─▶ Grundstücksgrenze (Ebene 01 Vermessung)
│
├─[Gelände] STAC(swissalti3d, bbox_WGS84) ─▶ COG .tif(2056)
│ └─ geotiff.js readRasters(window) ─▶ Höhen-Grid (E,N,Z, m)
│ └─ Three.js BufferGeometry (Grid→Mesh) [optional: TIN, Höhenlinien, Volumen]
│
├─[Orthofoto] WMTS swissimage ─▶ Textur auf Gelände-Mesh ODER georef. Plane
│
└─[Nachbarn] 3D-Tiles streamen (Anzeige) ODER STAC swissbuildings3d_2 .obj ─▶ Mesh-Import
(Weltweit/ausserhalb CH: OSM-Overpass als Fallback, siehe B.5)
──▶ alle Geometrien um origin_shift (bbox-Center→0/0/0) verschoben, Z aus ALTI3D
B.2 Gelände-Mesh aus swissALTI3D (Kern, Phase 4)
Empfohlener Browser-Weg (COG + geotiff.js):
- STAC-Query mit
bbox_WGS84→ Liste der überlappenden Tiles; pro Tile das gewünschte COG-Asset (_2_2056_für 2 m,_0.5_2056_für 0.5 m). geotiff.js:const tiff = await fromUrl(href)→ COG;image.readRasters({window})liest nur den Ausschnitt (Range-Requests, da CORS+Range bestätigt). Ergebnis ist ein reguläres Z-Raster mit bekanntem Origin/PixelScale (LV95-Meter) aus den GeoKeys/image.getOrigin()/image.getResolution().- Raster →
THREE.BufferGeometry: ein Vertex pro Rasterpunkt(E−shiftE, N−shiftN, Z−shiftZ), Faces als zwei Dreiecke pro Zelle (DOSSIER:mesh_from_grid, gleiche Logik),computeVertexNormals(). Bei 0.5 m wird das Mesh groß → bei Bedarf raumräumlich sub-samplen (DOSSIER macht ganzzahliges Sub-Sampling auf dem globalen LV95-Raster, damit Nachbar-Tiles nahtlos zusammenpassen). - Mehrere Tiles: erst zu einem Grid mergen (gemeinsamer Origin/Step), dann meshen —
sonst entstehen Nähte (DOSSIER:
merge_grids).
Alternativweg (XYZ, exakt wie DOSSIER): .xyz.zip laden → mit fflate
(npm, schnellster Inflate im Browser) entpacken → ASCII E N Z parsen → gleiches Grid.
Robust, aber überträgt mehr Bytes als der COG-Range-Weg. Für den Port empfehle ich
COG primär, XYZ als Fallback.
Bibliotheken: geotiff@3.0.5, fflate (XYZ-Variante), three@0.185.0.
geotiff.js ·
3D-Terrain aus GeoTIFF mit Three.js.
Ableitungen wie in DOSSIER (alle aus dem Grid, in Phase 4 portierbar):
- Höhenlinien (Marching-Squares auf dem Grid; npm
d3-contourodermarchingsquares) — für 2D-Plan. - TIN / Patch (Delaunay aus den Punkten; npm
delaunator) — alternatives Mesh. - Geschlossenes Gelände-Volumen (Boden N m unter tiefstem Punkt) → gefüllte
Querschnitte beim Schnitt-Cut (DOSSIER
terrainVolume/terrainVolumeDepth).
B.3 Origin-Shift (Pflicht)
LV95-Koordinaten (~2.6e6) sprengen float32. Beim Import einmal
shift = (eCenter, nCenter, zRef) festlegen, alle Geometrien −shift rechnen, und
shift am Projekt persistieren (für Re-Import / Geo-Referenz / Norden). DOSSIER:
origin_shift/shift_lv95, plus „Auto-Zoom auf Import" (ROADMAP §11). Damit bleibt das
Modell metergenau und der Rückweg in echte LV95-Koordinaten (Export, weitere
swisstopo-Abfragen) ist + shift.
B.4 Parzelle + Orthofoto
- Parzelle:
identify(...cadastralwebmap..., returnGeometry=true, geometryFormat=geojson)→ Polygon (LV95) →−shift→ als geschlossene Polylinie auf Ebene01 Vermessung. Attributenumber/egris_egridam Objekt/Projekt speichern. - Orthofoto: WMTS
swissimage-Kacheln über die Modell-Bbox stitchen → eine Textur, als Material auf das Gelände-Mesh oder auf eine georeferenzierte Plane (DOSSIER:add_ortho_plane, mit UV-Shift gegen Tile-Nähte). Für 3D ist3857einfacher, für exakte 2D-Lage2056.
B.5 OSM-Overpass als weltweiter Fallback (Phase 4)
Ausserhalb der Schweiz (oder wenn nur 2D-Footprints/Straßen reichen): DOSSIER hat einen
Overpass-Importer (https://overpass-api.de/api/interpreter, POST) mit 7 Kategorien
(Straßen/Gebäude/Wasser/Wasserläufe/Grün/Wege). Liefert OSM-Ways → Polylinien. Im
Browser identisch nutzbar (fetch POST). Overpass koordiniert in WGS84 → mit
proj4→LV95→−shift. Hinweis: Overpass-CORS ist beim Haupt-Server meist offen, kann
aber je nach Mirror variieren; ggf. anderen Mirror wählen.
Overpass API.
B.6 Was sich von DOSSIER nicht 1:1 portieren lässt
- Rhino-
_-Importfür DXF/DWG/OBJ und_-MeshPatch/Delaunay-Commands gibt es im Browser nicht → ersetzen durch JS-Parser/Algorithmen (OBJ:three-OBJLoader; Delaunay:delaunator; Contours:d3-contour). - Filesystem-Cache neben der
.3dm→ Browser: IndexedDB-Cache (Cache-API für Kacheln). Passt zur ROADMAP-Phase 5 (IndexedDB-Persistenz). - IFC-Import von swissBUILDINGS3D 3.0 → über web-ifc (ohnehin im Stack, Phase 4).
Teil C — SIA 416 (Flächen/Volumen) & SIA 421 + DOSSIER-Logik
C.1 SIA 416 — Flächen- und Volumenhierarchie
SIA 416:2003 „Flächen und Volumen von Gebäuden" ist die in der CH gültige Norm und Berechnungsbasis für Kostenplanung/Flächennachweise. Sie kennt vier Bereiche: GSF (Grundstück), GF (Geschossflächen), AGF (Aussengeschossflächen), GV (Volumen). Maßgeblich ist die effektive Geometrie (keine fiktiven Zuschläge mehr). Quellen: SIA 416 Übersicht (siworks/DBV) · SIA-Shop 416/2003 · Flächenkennzahlen SIA 416 (Ginesta, PDF).
Hierarchie & Formeln (verifiziert):
GSF Grundstücksfläche
GF Geschossfläche = KF + NGF
├─ KF Konstruktionsfläche (Wände/Stützen; tragend KFT + nicht tragend KFN)
└─ NGF Nettogeschossfläche = NF + VF + FF
├─ NF Nutzfläche = HNF + NNF
│ ├─ HNF Hauptnutzfläche (zweckbestimmte Hauptnutzung: Wohnen, Büro …)
│ └─ NNF Nebennutzfläche (Lager, Bad/WC, Abstell-, Nebenräume)
├─ VF Verkehrsfläche (Erschließung: Flure, Treppen, Lifte)
└─ FF Funktionsfläche (Gebäudetechnik: Heizung, Lüftung, Technik)
AGF Aussengeschossfläche (Balkone, Terrassen, gedeckte Aussenflächen)
GV Gebäudevolumen [m³]
| Abk. | Deutsch | Inhalt (Kurz) |
|---|---|---|
| GSF | Grundstücksfläche | Parzellenfläche (aus Kataster, Teil A.6) |
| GF | Geschossfläche | allseits umschlossene + überdeckte Grundrissflächen, geschossweise |
| KF | Konstruktionsfläche | Bauteile (Wände/Stützen), nicht begehbar; KFT tragend / KFN nicht tragend |
| NGF | Nettogeschossfläche | begehbare Fläche innerhalb der Umschließung = NF+VF+FF |
| NF | Nutzfläche | tatsächlich nutzbar = HNF+NNF |
| HNF | Hauptnutzfläche | zweckbestimmte Hauptnutzung |
| NNF | Nebennutzfläche | dienende Nebenräume (Lager, Bad, WC) |
| VF | Verkehrsfläche | horizontale/vertikale Erschließung |
| FF | Funktionsfläche | Gebäudetechnik |
| AGF | Aussengeschossfläche | Balkone/Terrassen u.ä. |
| GV | Gebäudevolumen | umbauter Raum [m³] |
Versionshinweis: Es kursiert eine Revision SIA 416:2017 mit präzisierten Begriffen, in der Praxis wird aber breit weiter 416:2003 referenziert. Für unser Tool reicht die Klassifikation HNF/NNF/VF/FF/GF/AGF + Bilanz; die genaue Auflage nur als Label dokumentieren. Verbindliche Definitionen stehen im kostenpflichtigen Normtext (SIA-Shop) — die hier zitierten freien Quellen stimmen in der Struktur überein.
C.2 SIA 421 — Flächengliederung für Bewirtschaftung/Vermietung
SIA 421:2006 „Flächengliederung und Mengenangaben" (Korrigenda C1:2014) baut auf der SIA-416-Systematik auf und gliedert Flächen für Immobilien-Bewirtschaftung und Vermietung (Mietflächen, Nutzungseinheiten, Zuordnung von VF/FF zu Mietern). Relevant, sobald wir Mietflächen-/Bewirtschaftungs-Auswertungen wollen (über den reinen Architektur-Nachweis hinaus). Für den ersten Wurf nicht zwingend — SIA 416 reicht für Flächennachweis und Raumschema. SIA 421 ist die natürliche Erweiterung, wenn Property-Management-Features kommen. Quellen: SIA 421:2006 (PDF Inhalt) · Korrigenda C1:2014 (PDF).
C.3 Wie DOSSIER SIA macht (Vorlage für den Port)
Quellcode: rhino/elemente.py (Räume) + rhino/elemente_uebersicht.py (Bilanz/CSV).
Kernpunkte, die wir 1:1 übernehmen:
Datenmodell pro Raum. Ein Raum ist eine geschlossene Outline-Curve + ein
Text-Stempel. Klassifikation über das Feld dossier_raum_sia mit Werten
{"", hnf, nnf, vf, ff, gf, agf} (_RAUM_SIA_KINDS). Weitere Felder: name, nummer,
funktion (wohnen|schlafen|bad|kueche|essen|flur|…), personen (für
Personenbelegung/Brandschutz), Rundung, Stempel-Layout.
Flächen-/Umfangsberechnung (_raum_amp): Fläche aus AreaMassProperties (≙ in JS
Shoelace-Formel über das Polygon), Umfang = Kurvenlänge, plus Zentroid für den
Stempel. Im Browser: Polygon-Fläche selbst rechnen (Shoelace), kein Mesh nötig — exakt
und schnell. Rundungsstufen (_format_area): exakt|0.01|0.1|0.5|1 (z.B. 0.5 =
round(a*2)/2).
SIA-Bilanz (compute_sia_bilanz, scope = total | geschoss:<id>): summiert
Raumflächen je Klasse, dann:
NF = HNF + NNF
NGF = NF + VF + FF (GF/AGF separat aggregiert, zählen nicht in NGF)
(genau die Formeln aus C.1). Ergebnis je Geschoss + Total.
Farb-/Darstellungs-Konvention (_SIA_COLORS_HEX, Pastell): HNF rot #e8a8a8,
NNF orange #e8c498, VF gelb #e8d878, FF hellblau #a8c8e0, GF grau #d0d0d0,
AGF hellgrün #c0d8c0. Umgesetzt als regelbasierte Overrides (_build_sia_preset_rules,
Preset „SIA-Raeume"): Bedingung user_string == code → Outline-Farbe + Solid-Hatch.
→ Passt 1:1 zur geplanten Overrides-Engine (ROADMAP §2c/§11).
Export (_cmd_export_raeume, _export_bilanz): CSV, Semikolon + UTF-8-BOM
(CH/DE-Excel), Dezimal-Komma. Raumliste: Nummer; Name; Geschoss; Funktion; SIA; Fläche;
Fläche gerundet; Umfang. Bilanz: eine Spalte je Geschoss + Total, Zeilen je Kategorie.
→ Im Browser: Blob + Download (kein SaveFileDialog), gleiche CSV-Struktur. Optional
direkt .xlsx via sheetjs/exceljs.
Layer-Routing: GF→61_GF, AGF→62_AGF, Rest→60_RAEUME (_layer_path_for_raum_sia)
— damit Geschossflächen-Outlines getrennt schalt-/exportierbar sind. Übersetzt sich auf
unsere Ebenen-Codes (60 Räume).
Was wir im Port besser/anders machen:
- Fläche per Shoelace statt Rhino-Mass-Props (0 Deps).
- Bilanz reaktiv aus dem semantischen Modell (Zustand-Store) statt Doc-Scan.
- Space = Slab-/Raum-Polygon mit
siaClassim Datenmodell (ROADMAP:Space { boundary, name }), Bilanz als abgeleitete Sicht.
Teil D — Umsetzungsplan (Endpunkte · Libs · Phase)
Reihenfolge orientiert sich an der ROADMAP (SIA = Phase 2, Geo = Phase 4) und an „größter Nutzen zuerst, geringste Abhängigkeit zuerst".
Phase 2 — SIA-Räume (kein Netz, reine Logik) ⭐
Endpunkte: keine. Libs: keine (Shoelace selbst), optional exceljs/sheetjs für
.xlsx.
Space-Modell:{ boundary[], geschossId, name, nummer, funktion, siaClass∈{hnf,nnf,vf,ff,gf,agf}, personen }.computeArea(Shoelace) + Umfang; Rundungsstufen (exakt|0.01|0.1|0.5|1) wie DOSSIER_format_area.computeSiaBilanz(scope)→{hnf,nnf,nf,vf,ff,ngf,gf,agf,count,personen}mitnf=hnf+nnf,ngf=nf+vf+ff.- SIA-Farbpalette + Stil-Override (Outline-Farbe/Solid-Fill) in der Overrides-Engine.
- Raumstempel-Renderer (Felder-Layout) + CSV-Export (Semikolon, UTF-8-BOM, Komma) für Raumliste und Bilanz. Ergebnis: SIA-416-Flächennachweis + Raumschema, Excel-kompatibel — vor jeder Geo-Arbeit nutzbar.
Phase 4a — Geo-Grundlage: Koordinaten + Standortabfrage
Endpunkte: SearchServer (Geocoding), height (Punkt-Z), identify
(Parzelle, cadastralwebmap-farbe). Libs: proj4@2.20.9 (+ @types/proj4).
proj4-EPSG:2056-Def + Helferlv95↔wgs84,bboxLv95→bboxWgs84(DOSSIER-Logik).- Origin-Shift-Mechanik + Persistenz am Projekt (
shift = bbox-Center), Auto-Zoom. - Adresssuche → Zentrum; „Gelände-Höhe holen" (height); „Parzelle holen" → Polygon auf
Ebene
01 Vermessung(+ EGRID/Nummer am Projekt). Ergebnis: Projekt ist georeferenziert; Parzelle + Adresse + Geländehöhe vorhanden.
Phase 4b — Gelände-Mesh + Orthofoto
Endpunkte: STAC swissalti3d (COG .tif, 2056) + profile.json; WMTS swissimage.
Libs: geotiff@3.0.5, three@0.185.0, optional fflate (XYZ-Fallback),
d3-contour/marchingsquares (Höhenlinien), delaunator (TIN).
- STAC-Query (bbox) → COG-Tiles;
geotiff.jsRange-Read → Grid; Tiles mergen. - Grid →
THREE.BufferGeometry(DOSSIERmesh_from_grid/merge_grids); Sub-Sampling auf globalem LV95-Raster; Normalen. - Optional: Höhenlinien (2D-Plan), TIN, geschlossenes Volumen (Schnitt-Füllung).
- WMTS-
swissimage-Kacheln → Textur auf Mesh/Plane (DOSSIERadd_ortho_plane). - Geländeschnitt im 2D-Plan via
profile.jsonentlang der Schnittlinie. Ergebnis: echtes Gelände mit Orthofoto unter dem Gebäude; Geländeschnitte.
Phase 4c — Nachbargebäude + weltweiter Fallback
Endpunkte: 3D-Tiles ch.swisstopo.swissbuildings3d.3d/v1/tileset.json (Anzeige)
oder STAC swissbuildings3d_2 .obj/.ifc (Import); OSM overpass-api.de.
Libs: @loaders.gl/3d-tiles@4.4.3 oder 3DTilesRendererJS; three-OBJLoader;
web-ifc (für 3.0-IFC); proj4.
- Kontext-Anzeige: 3D-Tiles in den Three-Scenegraph streamen (kein Download).
- Bedarf an echter Geometrie (Verschattung/Abstand): STAC-OBJ-Tile → Mesh-Import →
−shift. - Ausserhalb CH / nur 2D: Overpass-POST → Ways → Polylinien (Ebene
70 OSM). Ergebnis: Nachbarschaftskontext (CH 3D, weltweit OSM).
Querschnitt (alle Geo-Phasen)
- Caching: IndexedDB für STAC-Antworten + COG-Bytes + Kacheln (ersetzt DOSSIERs Disk-Cache); Cache-Schlüssel = Tile-ID/URL.
- Defensive HTTP: Timeouts, Retry/Backoff, 402/429 abfangen, Größen-Limit pro Tile (DOSSIER: 200-MB-Guard).
- Attribution: „© swisstopo" sichtbar einblenden, „© OpenStreetMap-Mitwirkende" bei OSM.
- Worker: GeoTIFF-Parsing + Mesh-Bau im Web-Worker (Comlink, ROADMAP-Stack), UI bleibt flüssig.
Empfohlener Library-Satz (npm, aktuell)
proj4@2.20.9 · geotiff@3.0.5 · three@0.185.0 · fflate (XYZ) ·
@loaders.gl/3d-tiles@4.4.3 oder 3DTilesRendererJS · delaunator ·
d3-contour · web-ifc (im Stack) · exceljs/sheetjs (optional, .xlsx).
Quellen
- GeoAdmin REST (height/profile/identify/find/search): https://geoadmin.readthedocs.io/en/latest/services/sdiservices.html
- GeoAdmin Tech-Docs (Hub): https://docs.geo.admin.ch/
- Identify Features: https://docs.geo.admin.ch/access-data/identify-features.html
- Search: https://docs.geo.admin.ch/access-data/search.html
- WMTS: https://docs.geo.admin.ch/visualize-data/wmts.html · https://wmts.geo.admin.ch/
- WMS: https://docs.geo.admin.ch/visualize-data/wms.html
- 3D-Tiles: https://docs.geo.admin.ch/visualize-data/3d-tiles.html
- swissALTI3D: https://www.swisstopo.admin.ch/en/height-model-swissalti3d
- Switzerland in 3D / swissBUILDINGS3D: https://www.swisstopo.admin.ch/en/switzerland-in-3d
- Terms of use (FSDI / OGD): https://www.geo.admin.ch/en/general-terms-of-use-fsdi
- REFRAME Web-API: https://www.swisstopo.admin.ch/en/rest-api-geoservices-reframe-web
- EPSG:2056 Definition: https://epsg.io/2056
- proj4js: https://github.com/proj4js/proj4js
- geotiff.js: https://github.com/geotiffjs/geotiff.js/
- Three.js-Terrain aus GeoTIFF: https://spatial-dev.guru/2024/11/30/creating-3d-terrain-maps-from-geotiff-files-with-three-js/
- WMTS EPSG:2056 Beispiel: https://codepen.io/geoadmin/pen/GZKEam
- Overpass API: https://overpass-api.de/
- SIA 416 (Übersicht): https://diebauherrenvertretung.ch/sia146/ · https://shop.sia.ch/normenwerk/architekt/sia%20416/dfi/D/Product
- SIA 416 Flächenkennzahlen (PDF): https://www.ginesta.ch/resources/public/lava3/media/kcfinder/files/Fl%C3%A4chenkennzahlen%20SIA%20416%20Norm.pdf
- SIA 421:2006 (PDF) + Korrigenda C1:2014: https://shop.sia.ch/d475e3f9-10c9-48aa-9be8-657784ea519b/F/DownloadAnhang · https://www.sia.ch/fileadmin/content/download/sia-norm/korrigenda_sn/421-C1_2014_d.pdf
- DOSSIER-Quellcode (Vorlage):
rhino/swisstopo.py,rhino/osm.py,rhino/elemente.py(Räume/SIA),rhino/elemente_uebersicht.py(Bilanz/CSV)