Datenkarte.at

Maschinenlesbare Version: /dokumentation/protokoll.md

Protokoll Datenkarte 0.1

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

Die Datenaufbereitung Schritt für Schritt (vor allem für KI-Agenten) beschreibt die Anleitung für KI-Agenten, eine verständliche Einführung bietet der Leitfaden für Datenanbieter. Gültige Vorlagen: manifest-complete.json, data-points.json.

Überblick

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

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

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)
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

geojson – das native Format.

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

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

{ "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

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:

{ "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.

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

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

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

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.

{
  "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). 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. Ohne beides bleibt nur der Schieberegler für den Zeitraum.

Entwicklung im Zeitverlauf und 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.

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.

{
  "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

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)

Datenantwort

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

Optionale Erweiterungen:

{
  "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": […] }
}
{
  "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):

{
  "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:

{
  "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 }
        ]
      }
    }
  }]
}

Cache

Validierung

Die Übereinstimmung mit dem Protokoll prüft der Validator (POST /api/validate, Live-Test GET /api/validate?manifestUrl=… oder die MCP-Werkzeuge validate_manifest und validate_data). Er unterscheidet:

Jeder Befund hat einen stabilen code (Übersicht der Codes), einen Pfad path und bei Empfehlungen einen Rat hint. Die Codes ändern sich zwischen Minor-Versionen nicht, neue können hinzukommen.

Weiterentwicklung des Protokolls