---
title: Lodapi mit CesiumJS
summary: Cesium-Viewer mit Lodapi-Buildings + Terrain in ~20 Zeilen.
---
# Lodapi mit CesiumJS

[CesiumJS](https://cesium.com/platform/cesiumjs/) ist der Mainstream-3D-Globe-Renderer für Web. Lodapi exponiert alle Buildings als 3D-Tiles-1.1-Tilesets, die Cesium nativ konsumieren kann. Das DGM1-Terrain ist ebenfalls als 3D-Tiles-Mesh verfügbar (Phase 2 beta).

## Minimal-Setup

```html
<!doctype html>
<html>
<head>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/cesium@1.130/Build/Cesium/Widgets/widgets.css">
  <style>html, body, #c { width: 100%; height: 100%; margin: 0; }</style>
</head>
<body>
<div id="c"></div>
<script type="module">
import * as Cesium from "https://cdn.jsdelivr.net/npm/cesium@1.130/Build/Cesium/index.js";

// Ohne Ion-Key: ein leerer Standard-Imagery-Layer + Cesium-Default-Terrain.
const viewer = new Cesium.Viewer("c", {
  baseLayerPicker: false,
  geocoder: false,
  timeline: false,
  animation: false,
});

// 1. Lodapi-Tilesets in der Frankfurter Innenstadt holen.
const bbox = "8.65,50.10,8.70,50.12";
const r = await fetch(`https://api.lodapi.de/v1/tilesets?bbox=${bbox}`);
const { tilesets } = await r.json();

// 2. Tilesets in den Cesium-Viewer hängen.
for (const t of tilesets) {
  const ts = await Cesium.Cesium3DTileset.fromUrl(t.tileset_url);
  viewer.scene.primitives.add(ts);
}

// 3. Kamera auf die Tilesets fliegen.
if (tilesets.length > 0) {
  viewer.zoomTo(viewer.scene.primitives.get(0));
}
</script>
</body>
</html>
```

Speichere als `index.html`, öffne in einem Browser. Du hast LoD2-Frankfurt in einem laufenden Cesium-Viewer.

## Terrain dazu

```ts
// Terrain-Mesh-Tilesets sind separate 3D-Tilesets, KEIN Cesium-Terrain-Provider.
// Building-Z ist absolut aus dem CityGML — beide Layer liegen ohne Provider-Magic
// koordinaten-korrekt übereinander.
const r2 = await fetch("https://api.lodapi.de/v1/terrain-mesh/datasets");
const { datasets } = await r2.json();
for (const t of datasets) {
  const ts = await Cesium.Cesium3DTileset.fromUrl(t.tileset_url);
  viewer.scene.primitives.add(ts);
}
```

## Attribution einbinden

Lodapi liefert pro Antwort einen `lodapi.attribution[]`-Block. Cesium zeigt Credits in seiner unteren Toolbar — füge die Lodapi-Quellen hinzu:

```ts
const attrs = tilesets.length > 0 ? (await fetch(
  `https://api.lodapi.de/v1/tilesets?bbox=${bbox}`
)).then(r => r.json()).then(d => d.lodapi.attribution) : [];

for (const a of attrs) {
  viewer.scene.creditDisplay.addStaticCredit(
    new Cesium.Credit(`${a.source} (${a.license})`, true)
  );
}
```

## Building anklicken → Detail-API

Cesium-3D-Tilesets unterstützen Per-Building-Picking. Die `feature.gmlid` ist als Batch-Table-Property eingebettet und matched die Lodapi-API:

```ts
viewer.screenSpaceEventHandler.setInputAction(async (movement) => {
  const f = viewer.scene.pick(movement.position);
  if (f instanceof Cesium.Cesium3DTileFeature) {
    const gmlid = f.getProperty("gmlid");
    if (!gmlid) return;
    const detail = await fetch(`https://api.lodapi.de/v1/buildings/${gmlid}`).then(r => r.json());
    console.log("Building:", detail.building_id, "BL:", detail.bundesland_code, "LoD:", detail.lod);
  }
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
```

## Performance-Tipps

- **`maximumScreenSpaceError`** auf 8–16 setzen (Default 16). Niedriger = mehr Detail, mehr Memory.
- **`cullWithChildrenBounds: true`** standardmäßig, lass das.
- **`preferLeaves: false`** für initial-snap-in, danach `true` für hohes Detail.
- **Mehrere BL parallel laden**: jede `tileset_url` als eigenes `Cesium3DTileset.fromUrl(...)` — keine Sammelladung nötig.

## Voller Demo-Code

Lodapi-Repo hat einen fertigen Cesium-Viewer unter [`code/demo/api-tilesets/index.html`](../../../code/demo/api-tilesets/index.html) — der gleiche Code, aber mit BL-Switcher und Inspector-Panel.

## Stolperdrähte

- **Ion-Key nicht zwingend**, aber ohne Imagery-Provider sieht der Globus leer aus. Setze `Cesium.Ion.defaultAccessToken = "..."` für hochauflösende Sat-Karten.
- **CesiumJS ≥ 1.118** für 3D-Tiles-1.1-Support (Implicit Tiling). Lodapi-Tilesets sind 1.1.
- **CORS**: `https://api.lodapi.de` erlaubt `*.lodapi.de` und `localhost:*`. Andere Origins brauchen einen Custom-Eintrag — Issue eröffnen.