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:
- JSON Schema des Manifests und JSON Schema der Daten – generiert aus den zod-Schemata in
src/lib/protocol/, - OpenAPI-Vertrag des Anbieters.
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
- 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
localhostwährend der Entwicklung). - Unbekannte Felder werden ignoriert. Ein unbekannter
presentation-Typ wird alsautodargestellt. - Version
protocolim Formatmajor.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 istprovider/dataset. - Farben nur in Hex-Schreibweise (
#rgb,#rrggbb,#rrggbbaa).
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 }
urlkann relativ zur URL des Manifests sein. Quelle kann auch eine statische Datei sein (parkbaenke.geojsonnebenmanifest.jsonauf beliebigem Webhosting) – im Modusfullverlangt 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.
{ "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.
- Typ
rangemit Jahren –minundmaxsind das erste und letzte Jahr der Daten, der Wertvon,bis(z. B.2019,2023, ein einzelnes Jahr2023,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.
{
"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.
- Verlaufsdiagramm. Hat ein Objekt Werte für mehrere Zeiträume, senden Sie sie in
feature.dm.chart(siehe Datenantwort). 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 alshighlightmit gleichemfromundto. Färbt ein Datensatz nach einem Zahlenwert, wird der Zeitraum per Parameter gewählt und fehlt das Diagramm, meldet der Validatormissing_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.chartder 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 nachhighlight. 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. Abthreshold(standardmäßig 0,5 %) steigt der Wert (grün), ab −thresholdabwärts sinkt er (rot), dazwischen stagniert er (grau). Die Farben lassen sich übercolors: { 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.
{
"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)
bboxundzoomnur im Modusbbox. Der Ausschnitt ist an den Kacheln der Stufezoom(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
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": […] }
}
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.labelsagt, was das Diagramm zeigt, optional sindunit,decimals,note(Anmerkung unter dem Diagramm, z. B. zu einer Methodenänderung) undhighlight: { 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. Gleichesfromundtomarkiert einen einzelnen Zeitraum, z. B. das beim Kartogramm gewählte Jahr – das Diagramm endet dort.pointssind Paare{ period, value }, sortiert vom ältesten Zeitraum an –periodist ein Jahr, Monat oder Tag wie beidm.timeline. 2–100 Punkte. Senden Sie es immer, wenn ein Objekt Werte für mehrere Zeiträume hat (siehe Entwicklung im Zeitverlauf und Trend).dm.ttl– Gültigkeit der Antwort (das Portal verwendet den kleineren Wert auscache.ttlunddm.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 vonlimit(zählen Sie sie mit einer Aggregationsabfrage, nicht aus den zurückgegebenen Objekten). Das Portal zeichnet daraus das Diagramm bei der Legende.periodist ein Jahr (2023), Monat (2023-05) oder Tag; das optionalevaluesteilt die Anzahl nach den Werten der Eigenschaft auscolor.fieldauf, 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 wiefeature.dm.chart. Das Portal zeigt sie beim Zeitfilter als Liniendiagramm, wenn die Antwort keindm.timelineenthält.
{
"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 }
]
}
}
}]
}
- Eigenschaften mit dem Präfix
__dm_sind für das Portal reserviert und werden aus der Antwort entfernt.
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 nachttlgilt weiterhin).
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:
- 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), einen Pfad path und bei Empfehlungen einen Rat hint. Die Codes ändern sich zwischen Minor-Versionen nicht, neue können hinzukommen.
Weiterentwicklung des Protokolls
- 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 (timebei Objekten + Parameter),vector-tiles/pmtiles/ogc-featuresals Quellen, Paginierung übernext, Aggregation für kleine Zoomstufen.