---
operation_id: get_vegetation_canopy
method: GET
path: /v1/vegetation/canopy
summary: Vegetationshöhe (Kronenhöhe) an einem WGS84-Punkt aus dem CDSM
tags: [vegetation]
stability: beta
since_version: 0.1.0
auth: none
data_product: vegetation
snapshot_aware: true
attribution_block: false
rate_limit_tier: public
related:
  - /v1/vegetation/datasets
  - /v1/terrain/elevation
---
# `GET /v1/vegetation/canopy` — Punktabfrage Vegetationshöhe

Liefert die **Vegetationshöhe über Grund** an einem WGS84-Punkt aus dem CDSM (Canopy-DSM = nDOM = DOM − DGM1, gebäudemaskiert, Schwelle ≥ 2 m), optional die **Kronenunterkante** (TDSM) und die **Belaubungs-Transmissivität** (leaf-on/leaf-off, Konarska et al. 2014).

PostGIS routet den Punkt über die Dataset-Bounds ins zuständige Bundesland; die verantwortliche COG-Kachel wird deterministisch aus dem Punkt berechnet (`{zone}_{easting_km}_{northing_km}.tif`, UTM-Origin-aligned) und via GDAL/rasterio `/vsicurl/` mit HTTP-Range-Requests gesampelt — dieselbe Mechanik wie `GET /v1/terrain/elevation`.

> **Das ist der Verschattungs-Input, den kein deutsches Solarkataster liefert** (ADR-0020): Energieatlas NRW/RLP, Wien, tetraeder.solar behandeln Vegetation als opake DOM-Zellen. Im Winterhalbjahr — das PV-Ertrag und Heizlast bestimmt — ist das um eine Größenordnung falsch. Der Endpoint gibt Kronenhöhe, Kronenunterkante und leaf-on/leaf-off-Transmissivität aus.

## Parameter

| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| `lat` | float | — | Breite in WGS84-Grad (−90…90), Pflicht |
| `lon` | float | — | Länge in WGS84-Grad (−180…180), Pflicht |
| `trunk` | bool | `true` | Auch die Kronenunterkante (TDSM) sampeln |
| `srs` | string | `EPSG:4326` | Referenzsystem von lat/lon (nur EPSG:4326) |

## Antwort

```json
{
  "canopy_height_m": 16.02,
  "crown_base_m": 4.0,
  "height_reference": "above_ground_nDOM",
  "transmissivity": { "leaf_on": [1.3, 5.3], "leaf_off": [40.0, 52.0] },
  "source_bl": "be",
  "snapshot": "2021-01-01",
  "crs": "EPSG:25833",
  "tile_id": "33_378_5816",
  "license": "dl-de-zero-2.0",
  "attribution": null
}
```

`canopy_height_m` ist die Höhe über Grund (kein vertikales Datum). `crown_base_m` ist `null`, wenn `trunk=false` oder kein TDSM vorliegt. `transmissivity` ist der Anteil durchgelassenen Lichts in Prozent.

## Brückenmaske ab Snapshot `2026-07-20` (ADR-0023)

Ab Snapshot `2026-07-20` (be/he/ni) sind **Brückendecks aus der Vegetation entfernt** (amtliche ATKIS-Bauwerksmaske `AX_BauwerkImVerkehrsbereich`, Puffer 1,0 m). `nDOM = DOM − DGM` sah ein Deck vorher exakt wie einen Baum ⇒ Falsch-Grün auf 37,5 % der he-Kacheln. **Konsequenz für dieses Sampling**: ein Punkt auf einem Brückendeck liefert jetzt `404` (NoData) statt einer Baumhöhe.

⚠️ **Bewusster Trade-off**: Vegetation *unter* einer Brücke geht mit verloren — das DOM sieht das Deck, nicht was darunter steht.

⚠️ **be-Ausnahme**: Berlin hat **keine** amtliche Brückenquelle ⇒ be-Snapshots tragen **keine** Brückenmaske; Falsch-Vegetation auf Berliner Brücken bleibt (bekannt/akzeptiert). Ältere Snapshots (`2026-07-16`, `2021-*`) tragen die Maske ebenfalls nicht — der `snapshot`-Wert im Response zeigt an, welche Rezeptur greift.

## Fehler

- `404` — kein Vegetations-Dataset deckt den Punkt ab, **oder** NoData (Punkt vegetationsfrei: < 2 m, versiegelt, gebäudemaskiert, oder außerhalb der Kachel-Abdeckung).
- `400` — nicht unterstütztes `srs`.
- `422` — lat/lon außerhalb des gültigen Bereichs.
- `502` — CDSM-COG nicht lesbar (Coverage-Loch oder Box/Netz-Fehler).

## Examples

### curl — Grunewald (Berlin)

```bash
curl -s "https://api.lodapi.de/v1/vegetation/canopy?lat=52.484&lon=13.230" | jq
```

### Python-SDK

```python
from lodapi import Client
c = Client()
r = c.vegetation.canopy(lat=52.484, lon=13.230)
print(r.canopy_height_m, r.crown_base_m, r.transmissivity["leaf_off"])
```

## Attribution

Lizenz je Dataset (`license`). Berlin-DOM = **DL-DE Zero** (keine Attributionspflicht).