Protokół MapaDanych 0.1
Normatywny opis interfejsu między dostawcą danych a portalem. W razie sprzeczności z inną dokumentacją obowiązuje ten dokument oraz schematy maszynowe:
- JSON Schema manifestu i JSON Schema danych – generowane ze schematów zod w
src/lib/protocol/, - kontrakt OpenAPI dostawcy.
Przygotowanie danych krok po kroku (zwłaszcza dla agentów AI) opisuje poradnik dla agentów AI, przystępne wprowadzenie znajdziesz w przewodniku dla dostawców. Poprawne wzorce: manifest-complete.json, data-points.json.
Przegląd
Dostawca Portal MapaDanych Przeglądarka
──────── ───────────────── ────────────
manifest.json ◄── GET (cache 10 min) ── rejestr → katalog ──────────► /api/catalog
endpoint danych ◄── GET ?bbox&zoom&… ─── proxy + walidacja + cache ───► /api/data/{provider}/{dataset}
kafelki rastrowe ◄────────────────────────────────────────────────────── bezpośrednio z przeglądarki
Zasady ogólne
- Format JSON, kodowanie UTF-8, współrzędne WGS84 (EPSG:4326) w kolejności
[lon, lat]. - Komunikacja przez HTTPS (http tylko dla
localhostpodczas programowania). - Nieznane pola są ignorowane. Nieznany typ
presentationjest renderowany jakoauto. - Wersja
protocolw postacimajor.minor. Portal przyjmie manifest o tej samej wersji głównej. - Identyfikatory (
provider.id,dataset.id): małe litery bez znaków diakrytycznych, cyfry, łączniki, maks. 64 znaki. Globalny klucz zbioru toprovider/dataset. - Kolory tylko w zapisie szesnastkowym (
#rgb,#rrggbb,#rrggbbaa).
Manifest
| Pole | Wymagane | Opis |
|---|---|---|
protocol |
tak | Wersja protokołu, np. "0.1" |
provider.id |
tak | Identyfikator; musi odpowiadać id w rejestrze portalu |
provider.name |
tak | Nazwa wyświetlana jako źródło |
provider.description, homepage, logo, contact |
nie | |
provider.managedBy |
nie | provider (domyślnie) / portal – manifest usługi publicznej utrzymuje portal MapaDanych |
license |
nie | { name, url?, attribution } – domyślna licencja wszystkich zbiorów |
datasets[] |
tak | 1–200 zbiorów danych o unikalnym id |
Zbiór danych
| Pole | Wymagane | Opis |
|---|---|---|
id, title |
tak | |
description |
nie | |
category |
nie | territory, nature, water, risks, energy, transport, society, economy, infrastructure, sample, other; inna wartość → Inne |
tags, keywords |
nie | Do wyszukiwania i dla przyszłego asystenta |
useCases |
nie | Cele, do których zbiór się nadaje: construction, housing, land-purchase, agriculture, investment… |
coverage |
nie | { bbox?, area?, minZoom?, maxZoom? } – poniżej minZoom portal nie wczytuje danych |
temporal |
nie | { updated?, frequency?, param? } – param = klucz parametru, którym wybiera się okres (zob. filtr czasowy) |
license |
nie | Nadpisuje licencję dostawcy |
source |
tak | Skąd pobierać dane (zob. niżej) |
presentation |
tak | Jak dane renderować (zob. niżej) |
fields[] |
nie | Opis właściwości obiektów: key, label, type, unit, decimals, description, primary |
params[] |
nie | Filtry dla użytkownika (zob. niżej) |
cache |
nie | { ttl?: sekundy, store?: boolean } |
live |
nie | { interval: sekundy } – dane na żywo: otwarta mapa sama odświeża zbiór (10 do 3600 s), zob. cache |
detail |
nie | { url } – szczegóły obiektu na żądanie po kliknięciu (rozkład jazdy, bogatszy opis, wyróżnienie na mapie), zob. szczegóły obiektu |
profile |
nie | Rodzaj zbioru ze wspólnym zachowaniem w portalu: transit_vehicles = bieżące pozycje pojazdów transportu publicznego, zob. transport |
source
geojson – format natywny.
{ "type": "geojson", "url": "/data/kontenery", "mode": "bbox", "maxFeatures": 5000 }
urlmoże być względny wobec URL manifestu. Źródłem może być też plik statyczny (lawki.geojsonobokmanifest.jsonna dowolnym hostingu) – w trybiefullportal nie wymaga żadnych parametrów zapytania, a plik jest poprawnym endpointem.mode: "full"– cały zbiór jednym zapytaniem (małe zbiory).mode: "bbox"– portal pyta o wycinek mapy.maxFeatures≤ 5000.
raster – gotowe kafelki, przeglądarka wczytuje je bezpośrednio ze źródła.
{ "type": "raster", "tiles": ["https://…/{z}/{x}/{y}.png"], "tileSize": 256, "minZoom": 0, "maxZoom": 19 }
Szablony obsługują {z}/{x}/{y} oraz {bbox-epsg-3857} (WMS GetMap). Tylko https.
presentation
type |
Geometria | Opcje |
|---|---|---|
circle |
punkty | color, radius, opacity, strokeColor, strokeWidth, label, cluster |
heatmap |
punkty | weight, radius, intensity, colors[], opacity |
line |
linie | color, width, opacity, dash[], label |
fill |
powierzchnie | color, opacity, outlineColor, outlineWidth, label |
raster |
kafelki | opacity |
auto |
cokolwiek | color |
Wszystkie typy mają opcjonalną legend: [{ label, color }] (maks. 20 pozycji). Portal pokazuje ją w legendzie bezpośrednio na mapie i w wyborze warstw. Dla typów wektorowych potrafi wyprowadzić ją z kolorów, dla raster nie – kolory są zapieczone w obrazach kafelków, dlatego legendę rastra podaj ręcznie (np. przejmując ją z legendy usługi WMS / ArcGIS).
Kolor (color) to albo ciąg szesnastkowy, albo reguła według właściwości obiektu:
{ "field": "druh", "type": "categorical", "values": { "papier": "#2563eb" }, "default": "#64748b" }
{ "field": "hodnota", "type": "interpolate", "stops": [[0, "#f7fcb9"], [100, "#004529"]] }
{ "field": "hodnota", "type": "step", "default": "#eee", "stops": [[10, "#fc8"], [50, "#e34"]] }
{ "type": "trend" }
trend koloruje obiekty według tego, czy ich wartość w czasie rośnie, stoi w miejscu, czy maleje. Oblicza go portal z wykresu zmian dm.chart – zob. zmiany w czasie i trend.
Liczba (radius, width, weight) to liczba albo { "field", "type": "interpolate", "stops": [[wartość, liczba], …] }.
Etykieta (label): { field, minZoom?, color?, size? }.
params
Filtr, który użytkownik ustawia w portalu; portal przesyła go jako parametr zapytania key=value.
type |
Wartość w zapytaniu |
|---|---|
enum |
key=a (z options) |
multi-enum |
key=a,b,c |
number |
key=42 (w zakresie min–max) |
range |
key=od,do |
boolean |
key=true / false |
date |
key=2026-10-06 |
date-range |
key=2026-01-01,2026-12-31 |
text |
key=… (maks. 200 znaków) |
Klucze bbox, zoom, limit, cursor, lang, protocol są zarezerwowane. Portal wysyła tylko zadeklarowane parametry, a ich wartości wcześniej sprawdza; niewypełniony parametr zastępuje wartością default.
Filtr czasowy
Dane w czasie (wypadki, pomiary, zdarzenia) mają jeden parametr okresu i odwołują się do niego z temporal.param. Portal nie pokazuje go wtedy wśród pozostałych filtrów, lecz jako oś czasu w oknie pod legendą: suwak okresu i wykres słupkowy według lat, na którym okres można wybrać kliknięciem lub przeciągnięciem. Wybrany okres widać też przy warstwie w legendzie.
- Typ
rangez latami –minimaxto pierwszy i ostatni rok danych, wartośćod,do(np.2019,2023, jeden rok2023,2023). Obiekty za cały okres zwracaj łącznie (zbiorczo), nie z podziałem na poszczególne lata. - Typ
date-range– okres z dokładnością do dni,2026-01-01,2026-06-30.
{
"protocol": "0.1",
"provider": { "id": "miasto-przyklad", "name": "Miasto Przykład" },
"license": { "name": "CC BY 4.0", "attribution": "© Miasto Przykład" },
"datasets": [{
"id": "nehody",
"title": "Wypadki drogowe",
"description": "Wypadki zarejestrowane przez policję według skutków.",
"category": "transport",
"keywords": ["wypadek", "wypadek drogowy", "bezpieczeństwo", "obrażenia", "skrzyżowanie"],
"useCases": ["transport", "housing"],
"coverage": { "bbox": [19.79, 49.97, 20.22, 50.13], "minZoom": 12 },
"temporal": { "frequency": "co roku", "param": "obdobi" },
"source": { "type": "geojson", "url": "https://data.miasto-przyklad.pl/mapadanych/wypadki", "mode": "bbox", "maxFeatures": 5000 },
"presentation": {
"type": "circle",
"color": { "field": "nasledky", "type": "categorical", "values": { "obrażenia": "#dc2626", "szkoda materialna": "#facc15" }, "default": "#facc15" }
},
"fields": [
{ "key": "nasledky", "label": "Skutki", "type": "string", "primary": true },
{ "key": "datum", "label": "Data", "type": "date" }
],
"params": [{ "key": "obdobi", "label": "Okres", "type": "range", "min": 2015, "max": 2025, "step": 1, "default": "2025,2025" }]
}]
}
Wykres rysuje portal z dm.timeline w odpowiedzi (zob. odpowiedź z danymi). Przy wartościach w czasie, dla których liczba obiektów nie ma sensu (liczba ludności, cena), wyślij zamiast tego zbiorczy przebieg w dm.chart – portal pokaże go przy suwaku jako wykres liniowy, zob. zmiany w czasie i trend. Bez żadnego z nich zostanie tylko suwak okresu.
Zmiany w czasie i trend
Standardowy sposób prezentacji danych, których wartość przy obiekcie zmienia się w czasie – liczba mieszkańców gminy, cena, zmierzone stężenie, frekwencja odwiedzających. Zawsze, gdy dane mają taki szereg, wysyłaj go; portal sam narysuje z niego wykres i może według niego kolorować.
- Wykres zmian. Jeśli obiekt ma wartość za kilka okresów, wyślij ją w
feature.dm.chart(zob. odpowiedź z danymi). Portal pokaże ją w szczegółach obiektu jako wykres liniowy z wartością za wybrany okres i zmianą względem jego początku. Dotyczy to także kartogramów, w których rok wybiera się parametrem: wyślij szereg za wszystkie lata, a wybrany rok jakohighlightz jednakowymfromito. Gdy zbiór koloruje według wartości liczbowej, okres wybiera się parametrem, a wykresu brak, walidator zgłasza to jakomissing_trend_chart. - Wykres zbiorczy przy legendzie. Przebieg dla całego obszaru zbioru lub dla wycinka (np. liczbę ludności Polski) wyślij w
dm.chartodpowiedzi – w takiej samej postaci jak wykres obiektu. Portal pokaże go przy filtrze czasowym, dopóki użytkownik nie otworzy żadnego obiektu, a wybrany okres zaznaczy wedłughighlight. Jeśli zbiór koloruje według trendu, linia otrzyma kolor trendu całości – widać wtedy, czy zielone punkty nie powielają po prostu ogólnokrajowego przebiegu. - Kolor według trendu. Jeśli sensem zbioru jest zmiana („rośnie czy maleje?”), ustaw
color: { "type": "trend" }. Portal z wykresu każdego obiektu obliczy średnią zmianę na jeden okres w % wartości początkowej – w wyróżnionym okresie (highlight), w przeciwnym razie dla całego szeregu. Odthreshold(domyślnie 0,5 %) w górę wartość rośnie (zielony), od −thresholdw dół maleje (czerwony), pomiędzy nimi stoi w miejscu (szary). Kolory można nadpisać przezcolors: { up, flat, down }, na przykład gdy wzrost jest niepożądany. Legendę portal wyprowadzi sam, a wykres w szczegółach pokoloruje tak samo jak obiekt na mapie. Obiekt bez wykresu pozostanie jasnoszary (trend_without_chart).
Trend opiera się na zmianie względnej, dlatego nadaje się dla wielkości dodatnich (liczby, ceny, stężenia). Wartości w okolicy zera, takie jak saldo migracji, koloruj przez interpolate, a zmiany pokazuj tylko wykresem.
{
"protocol": "0.1",
"provider": { "id": "wojewodztwo-przyklad", "name": "Województwo Przykład" },
"license": { "name": "CC BY 4.0", "attribution": "© Województwo Przykład" },
"datasets": [{
"id": "vyvoj-obyvatel",
"title": "Zmiany liczby mieszkańców gmin",
"description": "Gdzie mieszkańców przybywa, a gdzie ubywa. Kolor według trendu w wybranym okresie, w szczegółach gminy wykres według lat.",
"category": "society",
"keywords": ["mieszkańcy", "ludność", "trend", "wzrost", "wyludnianie"],
"useCases": ["housing", "public-administration"],
"temporal": { "frequency": "co roku", "param": "obdobi" },
"source": { "type": "geojson", "url": "https://data.wojewodztwo-przyklad.pl/mapadanych/mieszkancy" },
"presentation": { "type": "circle", "color": { "type": "trend", "threshold": 0.5 }, "radius": 7 },
"fields": [
{ "key": "nazev", "label": "Gmina", "type": "string", "primary": true },
{ "key": "obyvatel", "label": "Mieszkańcy na koniec okresu", "type": "integer" }
],
"params": [{ "key": "obdobi", "label": "Okres", "type": "range", "min": 2015, "max": 2025, "step": 1, "default": "2015,2025" }]
}]
}
Odpowiedź wysyła wtedy przy każdej gminie szereg za wszystkie lata, a wybrany okres w highlight, na przykład { "from": "2015", "to": "2025" }.
Zapytanie o dane
GET {source.url}?bbox=minLon,minLat,maxLon,maxLat&zoom=10&limit=5000&lang=pl&protocol=0.1[&cursor=…][&{params}]
Accept: application/geo+json, application/json
User-Agent: DatovaMapa/0.1 (+https://mapadanych.pl/dokumentacja/dla-dostawcow)
bboxizoomtylko w trybiebbox. Wycinek jest wyrównany do kafelków poziomuzoom(liczba całkowita), więc zbliżone widoki prowadzą do tego samego zapytania – zarówno dostawca, jak i portal mogą buforować odpowiedzi.limit= ile obiektów portal przetworzy maksymalnie.- Limit czasu odpowiedzi 10 s, rozmiar maks. 15 MB.
Odpowiedź z danymi
GeoJSON FeatureCollection (RFC 7946). Obsługiwane geometrie: Point, MultiPoint, LineString, MultiLineString, Polygon, MultiPolygon. Obiekty z geometry: null są pomijane.
Opcjonalne rozszerzenia:
{
"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– nagłówek i opis w szczegółach, link do szczegółów u źródła, nadpisanie koloru, wykres zmian.feature.dm.transit– pojazd transportu publicznego w zbiorach z profilemtransit_vehicles, zob. transport.feature.dm.chart– przebieg jednej wartości obiektu w czasie, który portal narysuje w szczegółach obiektu jako wykres liniowy z wartością za ostatni okres (np. liczba mieszkańców gminy według lat) i z którego oblicza kolor według trendu.labelmówi, co wykres pokazuje, opcjonalne sąunit,decimals,note(uwaga pod wykresem, np. o zmianie metodyki) ihighlight: { from, to }– wyróżniony okres, zwykle wybrany w filtrze czasowym; portal go podświetli, pokaże wartość na jego końcu, a zmianę i trend liczy od jego początku. Jednakowefromitooznaczają jeden okres, np. rok wybrany przy kartogramie – wykres zatrzyma się na nim.pointsto pary{ period, value }uporządkowane od najstarszego okresu –periodto rok, miesiąc lub dzień, tak jak wdm.timeline. 2–100 punktów. Wysyłaj go zawsze, gdy obiekt ma wartość za kilka okresów (zob. zmiany w czasie i trend).dm.ttl– ważność odpowiedzi (portal użyje mniejszej z wartościcache.ttlidm.ttl).dm.total,dm.truncated– ile jest obiektów łącznie / czy odpowiedź jest skrócona.dm.notice– krótki komunikat dla użytkownika (wyświetla się przy warstwie).dm.next– kursor do następnej strony (portal na razie go nie wykorzystuje, zarezerwowane).dm.timeline– liczby obiektów w wycinku według okresów za cały czas, który zbiór obejmuje, niezależnie od wybranego okresu i odlimit(policz je zapytaniem agregującym, nie ze zwróconych obiektów). Portal rysuje z nich wykres przy legendzie.periodto rok (2023), miesiąc (2023-05) lub dzień; opcjonalnevaluesdzieli liczbę według wartości właściwości zcolor.field, a wykres koloruje je jak legendę. Maks. 400 okresów.dm.chart– zbiorczy przebieg wartości dla całego obszaru zbioru lub wycinka (np. liczba ludności Polski), w takiej samej postaci jakfeature.dm.chart. Portal pokaże go przy filtrze czasowym jako wykres liniowy, gdy odpowiedź nie zawieradm.timeline.
{
"type": "FeatureCollection",
"features": [],
"dm": {
"timeline": [
{ "period": "2024", "count": 2366, "values": { "obrażenia": 701, "szkoda materialna": 1665 } },
{ "period": "2025", "count": 1894, "values": { "obrażenia": 652, "szkoda materialna": 1242 } }
]
}
}
Zbiorczy przebieg dla całego obszaru zamiast liczby obiektów (wybrany okres 2023–2025):
{
"type": "FeatureCollection",
"features": [],
"dm": {
"chart": {
"label": "Liczba ludności Polski na 31 grudnia",
"highlight": { "from": "2022", "to": "2025" },
"points": [
{ "period": "2021", "value": 38036118 },
{ "period": "2022", "value": 37766327 },
{ "period": "2023", "value": 37636508 },
{ "period": "2024", "value": 37489087 },
{ "period": "2025", "value": 37350000 }
]
}
}
}
Obiekt z wykresem zmian w szczegółach:
{
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"id": "1261011",
"geometry": { "type": "Point", "coordinates": [19.9450, 50.0647] },
"properties": { "nazev": "Kraków", "obyvatel": 806000 },
"dm": {
"chart": {
"label": "Liczba mieszkańców na 31 grudnia",
"points": [
{ "period": "2023", "value": 803300 },
{ "period": "2024", "value": 804900 },
{ "period": "2025", "value": 806000 }
]
}
}
}]
}
- Właściwości z przedrostkiem
__dm_są zarezerwowane dla portalu i zostają usunięte z odpowiedzi.
Szczegóły obiektu
Zbiór może oferować szczegóły obiektu na żądanie: po kliknięciu obiektu portal pokazuje okno z właściwości, a pod nim uzupełnia szczegóły pobrane osobno. Przydają się przy bogatszej treści, która nie mieści się we właściwościach: rozkład jazdy pociągu, przebieg przejazdu, wyróżnienie trasy na mapie. Pole detail w zbiorze zawiera szablon adresu z symbolem {id}, za który portal podstawia id obiektu z danych (obiekty muszą więc mieć stabilne id). Adres jest https albo względny wobec manifestu; walidator zgłasza szablon bez {id} (detail_url_without_id) i schemat inny niż https (detail_url_not_https).
"detail": { "url": "https://data.example.cz/detail?id={id}" }
Odpowiedzią jest JSON FeatureDetail (title i generated są obowiązkowe, pozostałe pola opcjonalne):
title,subtitle,badge { text, color, textColor }– nagłówek,status { label, tone }– stan z tonemok,warning,dangerlubneutral,fields[] { label, value },tags[],notes[]– dodatkowe dane, krótkie etykiety i uwagi,journey.calls[]– kolejne przystanki (najwyżej 300):name,arrival,departure(obowiązujący czas),scheduledArrival,scheduledDeparture(rozkład),estimated(czas jest szacunkiem),platform,state(passed,current,upcoming); czasy są w ISO 8601 z przesunięciem strefy,highlight– GeoJSONFeatureCollectiondo wyróżnienia na mapie, do około 200 kB: linie z właściwościąrolepassed(przebyta część, przyciemniona) lubupcoming, punkty zrolestoplubcurrentinamejako etykietą,color,url,notice,generated,ttl(jak długo szczegóły są ważne, w sekundach).
Dopóki szczegóły są otwarte, mapa odświeża je z interwałem live.interval zbioru. Portal buforuje odpowiedzi według ttl i sprawdza ich schemat tak samo jak dane. Nieznane id dostawca zwraca jako 404.
{
"title": "RJ 1000",
"subtitle": "→ Praha-Zahradní Město · RegioJet a.s.",
"badge": {
"text": "RJ 1000",
"color": "#0f766e"
},
"status": {
"label": "+8 min",
"tone": "warning"
},
"journey": {
"calls": [
{
"name": "Ostrava hlavní nádraží",
"departure": "2026-11-04T05:05:00+01:00",
"scheduledDeparture": "2026-11-04T05:05:00+01:00",
"platform": "2",
"state": "passed"
},
{
"name": "Pardubice hlavní nádraží",
"arrival": "2026-11-04T07:30:00+01:00",
"departure": "2026-11-04T07:38:00+01:00",
"scheduledArrival": "2026-11-04T07:22:00+01:00",
"scheduledDeparture": "2026-11-04T07:30:00+01:00",
"platform": "3",
"state": "current"
}
]
},
"highlight": {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [
[
15.77,
50.03
],
[
14.43,
50.08
],
[
14.6,
50.07
]
]
},
"properties": {
"role": "upcoming"
}
},
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
15.77,
50.03
]
},
"properties": {
"role": "current",
"name": "Pardubice hlavní nádraží"
}
}
]
},
"color": "#0f766e",
"generated": "2026-11-04T07:35:00Z",
"ttl": 30
}
Pełny przykład: detail-jizda.json.
Transport
Zbiory z bieżącymi pozycjami pojazdów transportu publicznego (pociągi, autobusy, tramwaje, metro…) oznacz "profile": "transit_vehicles". Portal pokaże je wtedy we wspólnej warstwie „Transport na żywo”: wszystkie tym samym stylem (kształt według rodzaju, kolor według opóźnienia), z jedną legendą, filtrem według rodzaju transportu, opóźnienia i przewoźnika oraz z wyszukiwaniem kursu. Użytkownik wybiera więc rodzaj transportu, a nie źródło danych.
Zbiór z profilem musi mieć live, prezentację circle i obiekty jako punkty z feature.dm.transit. Walidator zgłasza brak live (transit_missing_live), inną prezentację (transit_not_circle), obiekt bez dm.transit (transit_missing_properties) i obiekt, który nie jest punktem (transit_not_point).
Pole dm.transit |
Wymagane | Opis |
|---|---|---|
mode |
tak | rail, bus, tram, metro, trolleybus, ferry, funicular, other |
label |
tak | Oznaczenie, którego szukają ludzie: pociąg (R 1234), linia (188) |
line |
nie | Linia, gdy różni się od oznaczenia (S2) |
headsign, operator |
nie | Cel kursu, przewoźnik |
delay_min |
nie | Opóźnienie w pełnych minutach, ujemne = przed czasem |
delay_band |
tak | on_time do 4 min, minor 5 do 14, medium 15 do 29, major 30 do 59, extreme 60 i więcej, unknown bez danych |
bearing |
nie | Kierunek jazdy w stopniach od północy |
trip_ref |
nie | Stały klucz kursu (ten sam przy kolejnych odświeżeniach); taki sam jak id obiektu, jeśli zbiór oferuje szczegóły kursu |
observed_at |
tak | Kiedy zmierzono pozycję (ISO 8601) |
Każdy pojazd ma być na mapie tylko raz. Gdy te same pojazdy zgłasza kilka źródeł, niech wydaje je tylko jeden zbiór. Właściwości w properties (opisy dla ludzi w języku kraju) pozostają, dm.transit to neutralna część dla portalu.
{
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"id": "1234|20261104",
"geometry": { "type": "Point", "coordinates": [14.4352, 50.0833] },
"properties": { "vlak": "R 1234", "cil": "Brno hl.n.", "zpozdeni_min": 6 },
"dm": {
"transit": {
"mode": "rail", "label": "R 1234", "headsign": "Brno hl.n.", "operator": "České dráhy",
"delay_min": 6, "delay_band": "minor", "bearing": 135, "trip_ref": "1234|20261104",
"observed_at": "2026-11-04T07:35:10Z"
}
}
}]
}
Pełny przykład: data-doprava.json.
Cache
- Portal przechowuje odpowiedzi przez czas
min(cache.ttl, dm.ttl), domyślnie 300 s. Manifesty 10 min. - Po upływie tego czasu przechowuje wpis jeszcze 24 h jako kopię zapasową: gdy źródło nie odpowiada, pokazuje ostatnie dane z ostrzeżeniem.
cache.store: false– dostawca nie zgadza się na trwałe zapisanie danych w warstwie danych portalu (krótkotrwałe buforowanie odpowiedzi wedługttlobowiązuje nadal).live: { interval }– dane na żywo. Włączony zbiór w otwartej mapie sam pobiera się ponownie cointervalsekund (10 do 3600), bez odświeżania strony; przy ukrytej karcie odświeżanie się zatrzymuje. Interwał krótszy niżcache.ttlwalidator zgłasza (live_interval_below_ttl), bo mapa pytałaby częściej, niż zmieniają się dane. Portal oznacza zbiór zlivejako działający na żywo także bez „(na żywo)” w nazwie.
Walidacja
Zgodność z protokołem sprawdza walidator (POST /api/validate, test na żywo GET /api/validate?manifestUrl=… lub narzędzia MCP validate_manifest i validate_data). Rozróżnia:
- błędy (
errors) – naruszenie tego dokumentu; manifestu z błędem portal nie przyjmie, danych z błędem nie wyświetli, - zalecenia (
warnings) – dane działają, ale gorzej się je wyszukuje, wyświetla lub łączy.
Każde ustalenie ma stabilny code (przegląd kodów), ścieżkę path, a przy zaleceniach wskazówkę hint. Kody nie zmieniają się między wersjami minor, nowe mogą dochodzić.
Rozwój protokołu
- Nowe opcjonalne pola i nowe typy
presentation/source= nowa wersja minor (0.2…). - Zmiana znaczenia istniejących pól = nowa wersja major; portal przez okres przejściowy obsługuje obie.
- Kandydaci do kolejnych wersji:
symbol(ikony),extrusion(3D), wymiar czasowy (timeprzy obiektach + parametr),vector-tiles/pmtiles/ogc-featuresjako źródła, stronicowanie przeznext, agregacja dla małych przybliżeń.