# Protokoll Datenkarte 0.1 {#protokol-datovamapa-0-1}

Normative Beschreibung der Schnittstelle zwischen Datenanbieter und Portal. Bei Widersprüchen zu anderer Dokumentation gelten dieses Dokument und die maschinenlesbaren Schemata:

- [JSON Schema des Manifests](https://datenkarte.at/schema/0.1/manifest.json) und [JSON Schema der Daten](https://datenkarte.at/schema/0.1/data.json) – generiert aus den zod-Schemata in `src/lib/protocol/`,
- [OpenAPI-Vertrag des Anbieters](https://datenkarte.at/schema/0.1/provider-openapi.json).

Die Datenaufbereitung Schritt für Schritt (vor allem für KI-Agenten) beschreibt die [Anleitung für KI-Agenten](https://datenkarte.at/dokumentation/fuer-ki-agenten.md), eine verständliche Einführung bietet der [Leitfaden für Datenanbieter](https://datenkarte.at/dokumentation/fuer-datenanbieter.md). Gültige Vorlagen: [manifest-complete.json](https://datenkarte.at/beispiele/manifest-complete.json), [data-points.json](https://datenkarte.at/beispiele/data-points.json).

## Überblick {#prehled}

```
Anbieter                             Portal Datenkarte                 Browser
────────                             ─────────────────                 ───────
manifest.json  ◄── GET (Cache 10 min) ── Register → Katalog ─────────► /api/catalog
Daten-Endpoint ◄── GET ?bbox&zoom&… ──── Proxy + Validierung + Cache ─► /api/data/{provider}/{dataset}
Rasterkacheln  ◄─────────────────────────────────────────────────────── direkt aus dem Browser
```

## Allgemeine Regeln {#obecna-pravidla}

- Format JSON, Kodierung UTF-8, Koordinaten in WGS84 (EPSG:4326) in der Reihenfolge `[lon, lat]`. Daten in MGI / Austria Lambert (EPSG:31287) oder Gauß-Krüger M28/M31/M34 (EPSG:31257/31258/31259) müssen vorher nach WGS84 umgerechnet werden.
- Kommunikation über HTTPS (http nur für `localhost` während der Entwicklung).
- **Unbekannte Felder werden ignoriert.** Ein unbekannter `presentation`-Typ wird als `auto` dargestellt.
- Version `protocol` im Format `major.minor`. Das Portal akzeptiert Manifeste mit derselben Hauptversion.
- Bezeichner (`provider.id`, `dataset.id`): Kleinbuchstaben ohne Umlaute und Sonderzeichen, Ziffern, Bindestriche, max. 64 Zeichen. Der globale Schlüssel eines Datensatzes ist `provider/dataset`.
- Farben nur in Hex-Schreibweise (`#rgb`, `#rrggbb`, `#rrggbbaa`).

## Manifest {#manifest}

| Feld | Pflicht | Beschreibung |
|---|---|---|
| `protocol` | ja | Protokollversion, z. B. `"0.1"` |
| `provider.id` | ja | Bezeichner; muss der id im Register des Portals entsprechen |
| `provider.name` | ja | Name, der als Quelle angezeigt wird |
| `provider.description`, `homepage`, `logo`, `contact` | nein | |
| `provider.managedBy` | nein | `provider` (Standard) / `portal` – das Manifest für einen öffentlichen Dienst pflegt die Datenkarte |
| `license` | nein | `{ name, url?, attribution }` – Standardlizenz aller Datensätze |
| `datasets[]` | ja | 1–200 Datensätze mit eindeutiger `id` |

### Datensatz {#datova-sada}

| Feld | Pflicht | Beschreibung |
|---|---|---|
| `id`, `title` | ja | |
| `description` | nein | |
| `category` | nein | `territory`, `nature`, `water`, `risks`, `energy`, `transport`, `society`, `economy`, `infrastructure`, `sample`, `other`; anderer Wert → Sonstiges |
| `tags`, `keywords` | nein | Für die Suche und den künftigen Assistenten |
| `useCases` | nein | Zwecke, für die sich der Datensatz eignet: `construction`, `housing`, `land-purchase`, `agriculture`, `investment`… |
| `coverage` | nein | `{ bbox?, area?, minZoom?, maxZoom? }` – unterhalb von `minZoom` lädt das Portal keine Daten |
| `temporal` | nein | `{ updated?, frequency?, param? }` – `param` = Schlüssel des Parameters, mit dem der Zeitraum gewählt wird (siehe [Zeitfilter](https://datenkarte.at/dokumentation/protokoll.md#casovy-filtr)) |
| `license` | nein | Überschreibt die Lizenz des Anbieters |
| `source` | ja | Woher die Daten kommen (siehe unten) |
| `presentation` | ja | Wie die Daten dargestellt werden (siehe unten) |
| `fields[]` | nein | Beschreibung der Objekteigenschaften: `key`, `label`, `type`, `unit`, `decimals`, `description`, `primary` |
| `params[]` | nein | Filter für die Nutzerinnen und Nutzer (siehe unten) |
| `cache` | nein | `{ ttl?: Sekunden, store?: boolean }` |

### `source` {#source}

**`geojson`** – das native Format.

```json
{ "type": "geojson", "url": "/data/container", "mode": "bbox", "maxFeatures": 5000 }
```

- `url` kann relativ zur URL des Manifests sein. Quelle kann auch eine **statische Datei** sein (`parkbaenke.geojson` neben `manifest.json` auf beliebigem Webhosting) – im Modus `full` verlangt das Portal keine Query-Parameter, die Datei ist ein gültiger Endpoint.
- `mode: "full"` – der ganze Datensatz mit einer Anfrage (kleine Datensätze). `mode: "bbox"` – das Portal fragt den Kartenausschnitt ab.
- `maxFeatures` ≤ 5000.

**`raster`** – fertige Kacheln, der Browser lädt sie direkt von der Quelle.

```json
{ "type": "raster", "tiles": ["https://…/{z}/{x}/{y}.png"], "tileSize": 256, "minZoom": 0, "maxZoom": 19 }
```

Die Vorlagen unterstützen `{z}/{x}/{y}` und `{bbox-epsg-3857}` (WMS GetMap). Nur https.

### `presentation` {#presentation}

| `type` | Geometrie | Optionen |
|---|---|---|
| `circle` | Punkte | `color`, `radius`, `opacity`, `strokeColor`, `strokeWidth`, `label`, `cluster` |
| `heatmap` | Punkte | `weight`, `radius`, `intensity`, `colors[]`, `opacity` |
| `line` | Linien | `color`, `width`, `opacity`, `dash[]`, `label` |
| `fill` | Flächen | `color`, `opacity`, `outlineColor`, `outlineWidth`, `label` |
| `raster` | Kacheln | `opacity` |
| `auto` | beliebig | `color` |

Alle Typen haben eine optionale `legend: [{ label, color }]` (max. 20 Einträge). Das Portal zeigt sie in der Legende direkt in der Karte und in der Ebenenauswahl. Bei Vektortypen kann es sie aus den Farben ableiten, bei `raster` nicht – die Farben sind in die Kachelbilder eingebrannt, geben Sie die Legende eines Rasters daher selbst an (z. B. aus der Legende des WMS- bzw. ArcGIS-Dienstes übernommen).

**Farbe** (`color`) ist entweder ein Hex-String oder eine Regel nach einer Objekteigenschaft:

```json
{ "field": "art", "type": "categorical", "values": { "papier": "#2563eb" }, "default": "#64748b" }
{ "field": "wert", "type": "interpolate", "stops": [[0, "#f7fcb9"], [100, "#004529"]] }
{ "field": "wert", "type": "step", "default": "#eee", "stops": [[10, "#fc8"], [50, "#e34"]] }
{ "type": "trend" }
```

`trend` färbt Objekte danach, ob ihr Wert im Zeitverlauf steigt, stagniert oder sinkt. Das Portal berechnet ihn aus dem Verlaufsdiagramm `dm.chart` – siehe [Entwicklung im Zeitverlauf und Trend](https://datenkarte.at/dokumentation/protokoll.md#vyvoj-v-case-a-trend).

**Zahl** (`radius`, `width`, `weight`) ist eine Zahl oder `{ "field", "type": "interpolate", "stops": [[Wert, Zahl], …] }`.

**Beschriftung** (`label`): `{ field, minZoom?, color?, size? }`.

### `params` {#params}

Ein Filter, den die Nutzerin oder der Nutzer im Portal einstellt; das Portal sendet ihn als Query-Parameter `key=value`.

| `type` | Wert in der Anfrage |
|---|---|
| `enum` | `key=a` (aus `options`) |
| `multi-enum` | `key=a,b,c` |
| `number` | `key=42` (im Bereich `min`–`max`) |
| `range` | `key=von,bis` |
| `boolean` | `key=true` / `false` |
| `date` | `key=2026-10-06` |
| `date-range` | `key=2026-01-01,2026-12-31` |
| `text` | `key=…` (max. 200 Zeichen) |

Die Schlüssel `bbox`, `zoom`, `limit`, `cursor`, `lang`, `protocol` sind reserviert. Das Portal sendet nur deklarierte Parameter und prüft die Werte vorab; ein nicht ausgefüllter Parameter wird durch `default` ersetzt.

### Zeitfilter {#casovy-filtr}

Zeitbezogene Daten (Unfälle, Messungen, Ereignisse) haben einen Parameter für den Zeitraum und verweisen über `temporal.param` darauf. Das Portal zeigt ihn dann nicht bei den übrigen Filtern, sondern als Zeitachse im Fenster unter der Legende: einen Schieberegler für den Zeitraum und ein Säulendiagramm nach Jahren, in dem sich der Zeitraum per Klick oder Ziehen wählen lässt. Der gewählte Zeitraum ist auch bei der Ebene in der Legende zu sehen.

- Typ `range` mit Jahren – `min` und `max` sind das erste und letzte Jahr der Daten, der Wert `von,bis` (z. B. `2019,2023`, ein einzelnes Jahr `2023,2023`). Geben Sie die Objekte für den ganzen Zeitraum gemeinsam (zusammengefasst) zurück, nicht nach einzelnen Jahren.
- Typ `date-range` – Zeitraum tageweise, `2026-01-01,2026-06-30`.

```json manifest
{
  "protocol": "0.1",
  "provider": { "id": "stadt-beispiel", "name": "Stadt Beispiel" },
  "license": { "name": "CC BY 4.0", "attribution": "© Stadt Beispiel" },
  "datasets": [{
    "id": "unfaelle",
    "title": "Verkehrsunfälle",
    "description": "Von der Polizei erfasste Unfälle nach Unfallfolgen.",
    "category": "transport",
    "keywords": ["Unfall", "Verkehrsunfall", "Verkehrssicherheit", "Verletzung", "Kreuzung"],
    "useCases": ["transport", "housing"],
    "coverage": { "bbox": [15.35, 47.0, 15.55, 47.13], "minZoom": 12 },
    "temporal": { "frequency": "jährlich", "param": "obdobi" },
    "source": { "type": "geojson", "url": "https://data.stadt-beispiel.at/datenkarte/unfaelle", "mode": "bbox", "maxFeatures": 5000 },
    "presentation": {
      "type": "circle",
      "color": { "field": "folgen", "type": "categorical", "values": { "Personenschaden": "#dc2626", "Sachschaden": "#facc15" }, "default": "#facc15" }
    },
    "fields": [
      { "key": "folgen", "label": "Unfallfolgen", "type": "string", "primary": true },
      { "key": "datum", "label": "Datum", "type": "date" }
    ],
    "params": [{ "key": "obdobi", "label": "Zeitraum", "type": "range", "min": 2015, "max": 2025, "step": 1, "default": "2025,2025" }]
  }]
}
```

Das Diagramm zeichnet das Portal aus `dm.timeline` in der Antwort (siehe [Datenantwort](https://datenkarte.at/dokumentation/protokoll.md#datova-odpoved)). Bei Werten im Zeitverlauf, bei denen Objektanzahlen keinen Sinn ergeben (Einwohnerzahl, Preis), senden Sie stattdessen die zusammengefasste Entwicklung in `dm.chart` – das Portal zeigt sie beim Schieberegler als Liniendiagramm, siehe [Entwicklung im Zeitverlauf und Trend](https://datenkarte.at/dokumentation/protokoll.md#vyvoj-v-case-a-trend). Ohne beides bleibt nur der Schieberegler für den Zeitraum.

### Entwicklung im Zeitverlauf und Trend {#vyvoj-v-case-a-trend}

Die Standarddarstellung für Daten, deren Wert sich bei einem Objekt im Lauf der Zeit ändert – Einwohnerzahl einer Gemeinde, Preis, gemessene Konzentration, Besucherzahlen. Wann immer die Daten eine solche Zeitreihe haben, senden Sie sie mit; das Portal zeichnet daraus selbst ein Diagramm und kann danach einfärben.

- **Verlaufsdiagramm.** Hat ein Objekt Werte für mehrere Zeiträume, senden Sie sie in `feature.dm.chart` (siehe [Datenantwort](https://datenkarte.at/dokumentation/protokoll.md#datova-odpoved)). Das Portal zeigt sie im Objektdetail als Liniendiagramm mit dem Wert für den gewählten Zeitraum und der Veränderung gegenüber dessen Beginn. Das gilt auch für Kartogramme, bei denen das Jahr per Parameter gewählt wird: Senden Sie die Reihe für alle Jahre und das gewählte Jahr als `highlight` mit gleichem `from` und `to`. Färbt ein Datensatz nach einem Zahlenwert, wird der Zeitraum per Parameter gewählt und fehlt das Diagramm, meldet der Validator `missing_trend_chart`.
- **Zusammenfassendes Diagramm bei der Legende.** Die Entwicklung für das gesamte Gebiet des Datensatzes oder für den Ausschnitt (z. B. die Bevölkerung Österreichs) senden Sie in `dm.chart` der Antwort – in derselben Form wie das Diagramm eines Objekts. Das Portal zeigt es beim Zeitfilter, solange kein Objekt geöffnet ist, und markiert den gewählten Zeitraum nach `highlight`. Färbt der Datensatz nach Trend, erhält die Linie die Trendfarbe des Ganzen – so ist zu sehen, ob die grünen Punkte nicht bloß die bundesweite Entwicklung nachzeichnen.
- **Farbe nach Trend.** Geht es bei einem Datensatz um die Veränderung („wächst es oder schrumpft es?“), setzen Sie `color: { "type": "trend" }`. Das Portal berechnet aus dem Diagramm jedes Objekts die durchschnittliche Veränderung pro Zeitraum in % des Anfangswerts – im hervorgehobenen Zeitraum (`highlight`), sonst über die ganze Reihe. Ab `threshold` (standardmäßig 0,5 %) **steigt** der Wert (grün), ab −`threshold` abwärts **sinkt** er (rot), dazwischen **stagniert** er (grau). Die Farben lassen sich über `colors: { up, flat, down }` überschreiben, etwa wenn Wachstum unerwünscht ist. Die Legende leitet das Portal selbst ab und färbt das Diagramm im Detail genauso wie das Objekt in der Karte. Ein Objekt ohne Diagramm bleibt hellgrau (`trend_without_chart`).

Der Trend beruht auf der relativen Veränderung und eignet sich daher für positive Größen (Anzahlen, Preise, Konzentrationen). Werte um null, etwa den Wanderungssaldo, färben Sie über `interpolate` ein und zeigen die Entwicklung nur im Diagramm.

```json manifest
{
  "protocol": "0.1",
  "provider": { "id": "land-beispiel", "name": "Land Beispiel" },
  "license": { "name": "CC BY 4.0", "attribution": "© Land Beispiel" },
  "datasets": [{
    "id": "bevoelkerungsentwicklung",
    "title": "Bevölkerungsentwicklung der Gemeinden",
    "description": "Wo die Bevölkerung wächst und wo sie schrumpft. Farbe nach dem Trend im gewählten Zeitraum, im Detail der Gemeinde ein Diagramm nach Jahren.",
    "category": "society",
    "keywords": ["Bevölkerung", "Entwicklung", "Trend", "Wachstum", "Abwanderung"],
    "useCases": ["housing", "public-administration"],
    "temporal": { "frequency": "jährlich", "param": "obdobi" },
    "source": { "type": "geojson", "url": "https://data.land-beispiel.at/datenkarte/bevoelkerung" },
    "presentation": { "type": "circle", "color": { "type": "trend", "threshold": 0.5 }, "radius": 7 },
    "fields": [
      { "key": "nazev", "label": "Gemeinde", "type": "string", "primary": true },
      { "key": "obyvatel", "label": "Einwohner am Ende des Zeitraums", "type": "integer" }
    ],
    "params": [{ "key": "obdobi", "label": "Zeitraum", "type": "range", "min": 2015, "max": 2025, "step": 1, "default": "2015,2025" }]
  }]
}
```

Die Antwort sendet dann für jede Gemeinde die Reihe für alle Jahre und den gewählten Zeitraum in `highlight`, zum Beispiel `{ "from": "2015", "to": "2025" }`.

## Datenanfrage {#datovy-dotaz}

```
GET {source.url}?bbox=minLon,minLat,maxLon,maxLat&zoom=10&limit=5000&lang=de&protocol=0.1[&cursor=…][&{params}]
Accept: application/geo+json, application/json
User-Agent: DatovaMapa/0.1 (+https://datenkarte.at/dokumentation/fuer-datenanbieter)
```

- `bbox` und `zoom` nur im Modus `bbox`. Der Ausschnitt ist **an den Kacheln** der Stufe `zoom` (ganze Zahl) **ausgerichtet**, sodass nahe beieinanderliegende Ansichten zur selben Anfrage führen – Anbieter wie Portal können die Antworten cachen.
- `limit` = wie viele Objekte das Portal höchstens verarbeitet.
- Zeitlimit für die Antwort 10 s, Größe max. 15 MB.

## Datenantwort {#datova-odpoved}

GeoJSON `FeatureCollection` (RFC 7946). Unterstützte Geometrien: `Point`, `MultiPoint`, `LineString`, `MultiLineString`, `Polygon`, `MultiPolygon`. Objekte mit `geometry: null` werden übersprungen.

Optionale Erweiterungen:

```json
{
  "type": "FeatureCollection",
  "features": [{
    "type": "Feature", "id": 1, "geometry": {…}, "properties": {…},
    "dm": { "title": "…", "description": "…", "url": "https://…", "color": "#e11d48", "chart": {…} }
  }],
  "dm": { "generated": "2026-10-06T08:00:00Z", "ttl": 3600, "total": 1, "truncated": false, "next": "…", "notice": "…", "timeline": […] }
}
```

- `feature.dm` – Titel und Beschreibung im Detail, Link zum Detail bei der Quelle, Überschreiben der Farbe, Verlaufsdiagramm.
- `feature.dm.chart` – die Entwicklung eines Werts des Objekts über die Zeit, die das Portal im Objektdetail als Liniendiagramm mit dem Wert für den letzten Zeitraum zeichnet (z. B. die Einwohnerzahl einer Gemeinde nach Jahren) und aus der es die Farbe nach Trend berechnet. `label` sagt, was das Diagramm zeigt, optional sind `unit`, `decimals`, `note` (Anmerkung unter dem Diagramm, z. B. zu einer Methodenänderung) und `highlight: { from, to }` – der hervorgehobene Zeitraum, typischerweise der im Zeitfilter gewählte; das Portal hinterlegt ihn farbig, zeigt den Wert an seinem Ende und berechnet Veränderung wie Trend ab seinem Beginn. Gleiches `from` und `to` markiert einen einzelnen Zeitraum, z. B. das beim Kartogramm gewählte Jahr – das Diagramm endet dort. `points` sind Paare `{ period, value }`, sortiert vom ältesten Zeitraum an – `period` ist ein Jahr, Monat oder Tag wie bei `dm.timeline`. 2–100 Punkte. Senden Sie es immer, wenn ein Objekt Werte für mehrere Zeiträume hat (siehe [Entwicklung im Zeitverlauf und Trend](https://datenkarte.at/dokumentation/protokoll.md#vyvoj-v-case-a-trend)).
- `dm.ttl` – Gültigkeit der Antwort (das Portal verwendet den kleineren Wert aus `cache.ttl` und `dm.ttl`).
- `dm.total`, `dm.truncated` – wie viele Objekte es insgesamt gibt / ob die Antwort gekürzt ist.
- `dm.notice` – kurzer Hinweis für die Nutzerinnen und Nutzer (wird bei der Ebene angezeigt).
- `dm.next` – Cursor auf die nächste Seite (vom Portal noch nicht genutzt, reserviert).
- `dm.timeline` – Anzahl der Objekte **im Ausschnitt** nach Zeiträumen über die gesamte vom Datensatz abgedeckte Zeit, unabhängig vom gewählten Zeitraum und von `limit` (zählen Sie sie mit einer Aggregationsabfrage, nicht aus den zurückgegebenen Objekten). Das Portal zeichnet daraus das Diagramm bei der Legende. `period` ist ein Jahr (`2023`), Monat (`2023-05`) oder Tag; das optionale `values` teilt die Anzahl nach den Werten der Eigenschaft aus `color.field` auf, und das Diagramm färbt sie wie die Legende. Max. 400 Zeiträume.
- `dm.chart` – die zusammengefasste Entwicklung eines Werts für das gesamte Gebiet des Datensatzes oder den Ausschnitt (z. B. die Bevölkerung Österreichs), in derselben Form wie `feature.dm.chart`. Das Portal zeigt sie beim Zeitfilter als Liniendiagramm, wenn die Antwort kein `dm.timeline` enthält.

```json data
{
  "type": "FeatureCollection",
  "features": [],
  "dm": {
    "timeline": [
      { "period": "2024", "count": 2366, "values": { "Personenschaden": 701, "Sachschaden": 1665 } },
      { "period": "2025", "count": 1894, "values": { "Personenschaden": 652, "Sachschaden": 1242 } }
    ]
  }
}
```

Zusammengefasste Entwicklung für das gesamte Gebiet statt Objektanzahlen (gewählter Zeitraum 2022–2025):

```json data
{
  "type": "FeatureCollection",
  "features": [],
  "dm": {
    "chart": {
      "label": "Bevölkerung Österreichs zu Jahresbeginn",
      "highlight": { "from": "2022", "to": "2025" },
      "points": [
        { "period": "2021", "value": 8932664 },
        { "period": "2022", "value": 8978929 },
        { "period": "2023", "value": 9104772 },
        { "period": "2024", "value": 9158750 },
        { "period": "2025", "value": 9197213 }
      ]
    }
  }
}
```

Objekt mit Verlaufsdiagramm im Detail:

```json data
{
  "type": "FeatureCollection",
  "features": [{
    "type": "Feature",
    "id": "60101",
    "geometry": { "type": "Point", "coordinates": [15.4395, 47.0707] },
    "properties": { "nazev": "Graz", "obyvatel": 303300 },
    "dm": {
      "chart": {
        "label": "Einwohner zu Jahresbeginn",
        "points": [
          { "period": "2023", "value": 298500 },
          { "period": "2024", "value": 300800 },
          { "period": "2025", "value": 303300 }
        ]
      }
    }
  }]
}
```
- Eigenschaften mit dem Präfix `__dm_` sind für das Portal reserviert und werden aus der Antwort entfernt.

## Cache {#cache}

- Das Portal hält Antworten für `min(cache.ttl, dm.ttl)`, standardmäßig 300 s. Manifeste 10 min.
- Nach Ablauf bleibt der Eintrag noch 24 h als Reserve erhalten: Antwortet die Quelle nicht, zeigt das Portal die letzten Daten mit einem Hinweis.
- `cache.store: false` – der Anbieter ist mit einer dauerhaften Speicherung der Daten in der Datenschicht des Portals nicht einverstanden (das kurzfristige Cachen der Antworten nach `ttl` gilt weiterhin).

## Validierung {#validace}

Die Übereinstimmung mit dem Protokoll prüft der [Validator](https://datenkarte.at/dokumentation/api.md#validator) (`POST /api/validate`, Live-Test `GET /api/validate?manifestUrl=…` oder die MCP-Werkzeuge `validate_manifest` und `validate_data`). Er unterscheidet:

- **Fehler** (`errors`) – Verstöße gegen dieses Dokument; ein Manifest mit Fehler nimmt das Portal nicht an, Daten mit Fehler zeigt es nicht an,
- **Empfehlungen** (`warnings`) – die Daten funktionieren, lassen sich aber schlechter finden, darstellen oder kombinieren.

Jeder Befund hat einen stabilen `code` ([Übersicht der Codes](https://datenkarte.at/dokumentation/api.md#kody-nalezu)), einen Pfad `path` und bei Empfehlungen einen Rat `hint`. Die Codes ändern sich zwischen Minor-Versionen nicht, neue können hinzukommen.

## Weiterentwicklung des Protokolls {#vyvoj-protokolu}

- Neue optionale Felder und neue `presentation`- / `source`-Typen = neue Minor-Version (0.2…).
- Bedeutungsänderung bestehender Felder = neue Major-Version; das Portal unterstützt übergangsweise beide.
- Kandidaten für künftige Versionen: `symbol` (Icons), `extrusion` (3D), Zeitdimension (`time` bei Objekten + Parameter), `vector-tiles` / `pmtiles` / `ogc-features` als Quellen, Paginierung über `next`, Aggregation für kleine Zoomstufen.
