# Protokol DátovejMapy 0.1 {#protokol-datovamapa-0-1}

Normatívny popis rozhrania medzi poskytovateľom dát a portálom. Pri rozpore s inou dokumentáciou platí tento dokument a strojové schémy:

- [JSON Schema manifestu](https://datovamapa.sk/schema/0.1/manifest.json) a [JSON Schema dát](https://datovamapa.sk/schema/0.1/data.json) – generované zo zod schém v `src/lib/protocol/`,
- [OpenAPI kontrakt poskytovateľa](https://datovamapa.sk/schema/0.1/provider-openapi.json).

Postup prípravy dát krok za krokom (najmä pre AI agentov) je v [návode pre AI agentov](https://datovamapa.sk/dokumentacia/pre-ai-agentov.md), zrozumiteľný úvod v [sprievodcovi pre poskytovateľov](https://datovamapa.sk/dokumentacia/pre-poskytovatelov.md). Platné vzory: [manifest-complete.json](https://datovamapa.sk/priklady/manifest-complete.json), [data-points.json](https://datovamapa.sk/priklady/data-points.json).

## Prehľad {#prehled}

```
Poskytovateľ                         Portál DátovaMapa                 Prehliadač
─────────────                        ─────────────────                 ─────────
manifest.json  ◄── GET (cache 10 min) ── register → katalóg ─────────► /api/catalog
data endpoint  ◄── GET ?bbox&zoom&… ──── proxy + validácia + cache ───► /api/data/{provider}/{dataset}
rastrové dlaždice ◄───────────────────────────────────────────────────── priamo z prehliadača
```

## Všeobecné pravidlá {#obecna-pravidla}

- Formát JSON, kódovanie UTF-8, súradnice WGS84 (EPSG:4326) v poradí `[lon, lat]`.
- Komunikácia cez HTTPS (http len pre `localhost` pri vývoji).
- **Neznáme polia sa ignorujú.** Neznámy typ `presentation` sa vykreslí ako `auto`.
- Verzia `protocol` v tvare `major.minor`. Portál prijme manifest s rovnakou hlavnou verziou.
- Identifikátory (`provider.id`, `dataset.id`): malé písmená bez diakritiky, číslice, pomlčky, max. 64 znakov. Globálny kľúč sady je `provider/dataset`.
- Farby len v hex zápise (`#rgb`, `#rrggbb`, `#rrggbbaa`).

## Manifest {#manifest}

| Pole | Povinné | Popis |
|---|---|---|
| `protocol` | áno | Verzia protokolu, napr. `"0.1"` |
| `provider.id` | áno | Identifikátor; musí zodpovedať id v registri portálu |
| `provider.name` | áno | Názov zobrazovaný ako zdroj |
| `provider.description`, `homepage`, `logo`, `contact` | nie | |
| `provider.managedBy` | nie | `provider` (predvolené) / `portal` – manifest pre verejnú službu udržiava DátovaMapa |
| `license` | nie | `{ name, url?, attribution }` – predvolená licencia všetkých sád |
| `datasets[]` | áno | 1–200 dátových sád s unikátnym `id` |

### Dátová sada {#datova-sada}

| Pole | Povinné | Popis |
|---|---|---|
| `id`, `title` | áno | |
| `description` | nie | |
| `category` | nie | `territory`, `nature`, `water`, `risks`, `energy`, `transport`, `society`, `economy`, `infrastructure`, `sample`, `other`; iná hodnota → Ostatné |
| `tags`, `keywords` | nie | Na vyhľadávanie a budúceho asistenta |
| `useCases` | nie | Účely, pre ktoré sa sada hodí: `construction`, `housing`, `land-purchase`, `agriculture`, `investment`… |
| `coverage` | nie | `{ bbox?, area?, minZoom?, maxZoom? }` – pod `minZoom` portál dáta nenačítava |
| `temporal` | nie | `{ updated?, frequency?, param? }` – `param` = kľúč parametra, ktorým sa volí obdobie (pozri [časový filter](https://datovamapa.sk/dokumentacia/protokol.md#casovy-filtr)) |
| `license` | nie | Prepisuje licenciu poskytovateľa |
| `source` | áno | Odkiaľ brať dáta (pozri nižšie) |
| `presentation` | áno | Ako dáta vykresliť (pozri nižšie) |
| `fields[]` | nie | Popis vlastností objektov: `key`, `label`, `type`, `unit`, `decimals`, `description`, `primary` |
| `params[]` | nie | Filtre pre používateľa (pozri nižšie) |
| `cache` | nie | `{ ttl?: sekundy, store?: boolean }` |

### `source` {#source}

**`geojson`** – natívny formát.

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

- `url` môže byť relatívna voči URL manifestu. Zdrojom môže byť aj **statický súbor** (`lavicky.geojson` vedľa `manifest.json` na ľubovoľnom webhostingu) – v režime `full` portál žiadne query parametre nevyžaduje a súbor je platný endpoint.
- `mode: "full"` – celá sada jedným dopytom (malé sady). `mode: "bbox"` – portál sa pýta na výrez mapy.
- `maxFeatures` ≤ 5000.

**`raster`** – hotové dlaždice, prehliadač ich načítava priamo zo zdroja.

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

Šablóny podporujú `{z}/{x}/{y}` aj `{bbox-epsg-3857}` (WMS GetMap). Len https.

### `presentation` {#presentation}

| `type` | Geometria | Voľby |
|---|---|---|
| `circle` | body | `color`, `radius`, `opacity`, `strokeColor`, `strokeWidth`, `label`, `cluster` |
| `heatmap` | body | `weight`, `radius`, `intensity`, `colors[]`, `opacity` |
| `line` | línie | `color`, `width`, `opacity`, `dash[]`, `label` |
| `fill` | plochy | `color`, `opacity`, `outlineColor`, `outlineWidth`, `label` |
| `raster` | dlaždice | `opacity` |
| `auto` | čokoľvek | `color` |

Všetky typy majú voliteľnú `legend: [{ label, color }]` (max. 20 položiek). Portál ju ukazuje v legende priamo v mape a vo výbere vrstiev. Pri vektorových typoch ju vie odvodiť z farieb, pri `raster` nie – farby sú zapečené v obrázkoch dlaždíc, takže legendu rastra uveďte ručne (napr. prevzatím z legendy WMS / ArcGIS služby).

**Farba** (`color`) je buď hex reťazec, alebo pravidlo podľa vlastnosti objektu:

```json
{ "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` farbí objekty podľa toho, či ich hodnota v čase rastie, stagnuje, alebo klesá. Počíta ho portál z grafu vývoja `dm.chart` – pozri [vývoj v čase a trend](https://datovamapa.sk/dokumentacia/protokol.md#vyvoj-v-case-a-trend).

**Číslo** (`radius`, `width`, `weight`) je číslo alebo `{ "field", "type": "interpolate", "stops": [[hodnota, číslo], …] }`.

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

### `params` {#params}

Filter, ktorý používateľ nastaví v portáli; portál ho pošle ako query parameter `key=value`.

| `type` | Hodnota v dopyte |
|---|---|
| `enum` | `key=a` (z `options`) |
| `multi-enum` | `key=a,b,c` |
| `number` | `key=42` (v rozsahu `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=…` (max. 200 znakov) |

Kľúče `bbox`, `zoom`, `limit`, `cursor`, `lang`, `protocol` sú rezervované. Portál posiela len deklarované parametre a hodnoty vopred overí; nevyplnený parameter nahradí `default`.

### Časový filter {#casovy-filtr}

Dáta v čase (nehody, merania, udalosti) majú jeden parameter pre obdobie a odkazujú naň z `temporal.param`. Portál ho potom neukazuje medzi ostatnými filtrami, ale ako časovú os v okne pod legendou: posuvník obdobia a stĺpcový graf po rokoch, v ktorom sa dá obdobie vybrať kliknutím alebo ťahaním. Zvolené obdobie je vidieť aj pri vrstve v legende.

- Typ `range` s rokmi – `min` a `max` sú prvý a posledný rok dát, hodnota `od,do` (napr. `2019,2023`, jeden rok `2023,2023`). Objekty za celé obdobie vracajte dohromady (súhrnne), nie po jednotlivých rokoch.
- Typ `date-range` – obdobie po dňoch, `2026-01-01,2026-06-30`.

```json manifest
{
  "protocol": "0.1",
  "provider": { "id": "mesto-priklad", "name": "Mesto Príklad" },
  "license": { "name": "CC BY 4.0", "attribution": "© Mesto Príklad" },
  "datasets": [{
    "id": "nehody",
    "title": "Dopravné nehody",
    "description": "Nehody evidované políciou podľa následkov.",
    "category": "transport",
    "keywords": ["nehoda", "dopravná nehoda", "bezpečnosť", "zranenie", "križovatka"],
    "useCases": ["transport", "housing"],
    "coverage": { "bbox": [21.15, 48.65, 21.35, 48.78], "minZoom": 12 },
    "temporal": { "frequency": "ročne", "param": "obdobi" },
    "source": { "type": "geojson", "url": "https://data.mesto-priklad.sk/datovamapa/nehody", "mode": "bbox", "maxFeatures": 5000 },
    "presentation": {
      "type": "circle",
      "color": { "field": "nasledky", "type": "categorical", "values": { "zranenie": "#dc2626", "hmotná škoda": "#facc15" }, "default": "#facc15" }
    },
    "fields": [
      { "key": "nasledky", "label": "Následky", "type": "string", "primary": true },
      { "key": "datum", "label": "Dátum", "type": "date" }
    ],
    "params": [{ "key": "obdobi", "label": "Obdobie", "type": "range", "min": 2015, "max": 2025, "step": 1, "default": "2025,2025" }]
  }]
}
```

Graf kreslí portál z `dm.timeline` v odpovedi (pozri [dátová odpoveď](https://datovamapa.sk/dokumentacia/protokol.md#datova-odpoved)). Pri hodnotách v čase, kde počty objektov nedávajú zmysel (počet obyvateľov, cena), pošlite namiesto neho súhrnný vývoj v `dm.chart` – portál ho pri posuvníku ukáže ako čiarový graf, pozri [vývoj v čase a trend](https://datovamapa.sk/dokumentacia/protokol.md#vyvoj-v-case-a-trend). Bez oboch ostane len posuvník obdobia.

### Vývoj v čase a trend {#vyvoj-v-case-a-trend}

Štandardné zobrazenie dát, ktorých hodnota sa pri objekte mení v čase – počet obyvateľov obce, cena, nameraná koncentrácia, návštevnosť. Kedykoľvek majú dáta takýto rad, posielajte ho; portál z neho sám kreslí graf a vie podľa neho farbiť.

- **Graf vývoja.** Ak má objekt hodnotu za viac období, pošlite ju v `feature.dm.chart` (pozri [dátová odpoveď](https://datovamapa.sk/dokumentacia/protokol.md#datova-odpoved)). Portál ju ukáže v detaile objektu ako čiarový graf s hodnotou za zvolené obdobie a zmenou oproti jeho začiatku. Platí to aj pre kartogramy, kde sa rok volí parametrom: pošlite rad za všetky roky a zvolený rok ako `highlight` s rovnakým `from` a `to`. Keď sada farbí podľa číselnej hodnoty, obdobie sa volí parametrom a graf chýba, validátor to hlási ako `missing_trend_chart`.
- **Súhrnný graf pri legende.** Vývoj za celé územie sady alebo za výrez (napr. počet obyvateľov Slovenska) pošlite v `dm.chart` odpovede – rovnaký tvar ako graf objektu. Portál ho ukáže pri časovom filtri, kým používateľ žiadny objekt nerozklikne, a zvolené obdobie vyznačí podľa `highlight`. Ak sada farbí podľa trendu, dostane čiara farbu trendu celku – je potom vidieť, či zelené bodky len nekopírujú celoštátny vývoj.
- **Farba podľa trendu.** Ak je zmyslom sady zmena („rastie, alebo ubúda?“), nastavte `color: { "type": "trend" }`. Portál z grafu každého objektu vypočíta priemernú zmenu za jedno obdobie v % počiatočnej hodnoty – vo zvýraznenom období (`highlight`), inak za celý rad. Od `threshold` (predvolene 0,5 %) vyššie hodnota **rastie** (zelená), od −`threshold` nižšie **klesá** (červená), medzi tým **stagnuje** (sivá). Farby možno prepísať cez `colors: { up, flat, down }`, napríklad keď je rast nežiaduci. Legendu portál odvodí sám a graf v detaile zafarbí rovnako ako objekt v mape. Objekt bez grafu ostane svetlosivý (`trend_without_chart`).

Trend vychádza z relatívnej zmeny, hodí sa preto pre kladné veličiny (počty, ceny, koncentrácie). Hodnoty okolo nuly, ako saldo sťahovania, farbite cez `interpolate` a vývoj ukážte len grafom.

```json manifest
{
  "protocol": "0.1",
  "provider": { "id": "kraj-priklad", "name": "Kraj Príklad" },
  "license": { "name": "CC BY 4.0", "attribution": "© Kraj Príklad" },
  "datasets": [{
    "id": "vyvoj-obyvatel",
    "title": "Vývoj počtu obyvateľov obcí",
    "description": "Kde obyvateľov pribúda a kde ubúda. Farba podľa trendu vo zvolenom období, v detaile obce graf po rokoch.",
    "category": "society",
    "keywords": ["obyvatelia", "vývoj", "trend", "rast", "vyľudňovanie"],
    "useCases": ["housing", "public-administration"],
    "temporal": { "frequency": "ročne", "param": "obdobi" },
    "source": { "type": "geojson", "url": "https://data.kraj-priklad.sk/datovamapa/obyvatele" },
    "presentation": { "type": "circle", "color": { "type": "trend", "threshold": 0.5 }, "radius": 7 },
    "fields": [
      { "key": "nazev", "label": "Obec", "type": "string", "primary": true },
      { "key": "obyvatel", "label": "Obyvateľov na konci obdobia", "type": "integer" }
    ],
    "params": [{ "key": "obdobi", "label": "Obdobie", "type": "range", "min": 2015, "max": 2025, "step": 1, "default": "2015,2025" }]
  }]
}
```

Odpoveď potom pri každej obci posiela rad za všetky roky a zvolené obdobie v `highlight`, napríklad `{ "from": "2015", "to": "2025" }`.

## Dátový dopyt {#datovy-dotaz}

```
GET {source.url}?bbox=minLon,minLat,maxLon,maxLat&zoom=10&limit=5000&lang=sk&protocol=0.1[&cursor=…][&{params}]
Accept: application/geo+json, application/json
User-Agent: DatovaMapa/0.1 (+https://datovamapa.sk/dokumentacia/pre-poskytovatelov)
```

- `bbox` a `zoom` len v režime `bbox`. Výrez je **zarovnaný na dlaždice** úrovne `zoom` (celé číslo), takže blízke pohľady vedú na rovnaký dopyt – poskytovateľ aj portál môžu odpovede cachovať.
- `limit` = koľko objektov portál najviac spracuje.
- Časový limit odpovede 10 s, veľkosť max. 15 MB.

## Dátová odpoveď {#datova-odpoved}

GeoJSON `FeatureCollection` (RFC 7946). Podporované geometrie: `Point`, `MultiPoint`, `LineString`, `MultiLineString`, `Polygon`, `MultiPolygon`. Objekty s `geometry: null` sa preskočia.

Voliteľné rozšírenia:

```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` – nadpis a popis v detaile, odkaz na detail pri zdroji, prepísanie farby, graf vývoja.
- `feature.dm.chart` – vývoj jednej hodnoty objektu v čase, ktorý portál nakreslí v detaile objektu ako čiarový graf s hodnotou za posledné obdobie (napr. počet obyvateľov obce po rokoch) a z ktorého počíta farbu podľa trendu. `label` hovorí, čo graf ukazuje, nepovinné `unit`, `decimals`, `note` (poznámka pod grafom, napr. o zmene metodiky) a `highlight: { from, to }` – zvýraznené obdobie, typicky zvolené v časovom filtri; portál ho podfarbí, ukáže hodnotu na jeho konci a zmenu aj trend počíta od jeho začiatku. Rovnaké `from` a `to` označí jedno obdobie, napr. rok zvolený pri kartograme – graf sa na ňom zastaví. `points` sú dvojice `{ period, value }` zoradené od najstaršieho obdobia – `period` je rok, mesiac alebo deň ako pri `dm.timeline`. 2–100 bodov. Posielajte ho vždy, keď má objekt hodnotu za viac období (pozri [vývoj v čase a trend](https://datovamapa.sk/dokumentacia/protokol.md#vyvoj-v-case-a-trend)).
- `dm.ttl` – platnosť odpovede (portál použije menšie z `cache.ttl` a `dm.ttl`).
- `dm.total`, `dm.truncated` – koľko objektov celkom / či je odpoveď skrátená.
- `dm.notice` – krátke oznámenie pre používateľa (zobrazí sa pri vrstve).
- `dm.next` – kurzor na ďalšiu stránku (portál ho zatiaľ nevyužíva, rezervované).
- `dm.timeline` – počty objektov **vo výreze** po obdobiach za celý čas, ktorý sada pokrýva, nezávisle od zvoleného obdobia a od `limit` (spočítajte ich agregačným dopytom, nie z vrátených objektov). Portál z nich kreslí graf pri legende. `period` je rok (`2023`), mesiac (`2023-05`) alebo deň; nepovinné `values` rozdelí počet podľa hodnôt vlastnosti z `color.field` a graf ich zafarbí ako legendu. Max. 400 období.
- `dm.chart` – súhrnný vývoj hodnoty za celé územie sady alebo výrez (napr. počet obyvateľov Slovenska), rovnaký tvar ako `feature.dm.chart`. Portál ho ukáže pri časovom filtri ako čiarový graf, keď odpoveď neposiela `dm.timeline`.

```json data
{
  "type": "FeatureCollection",
  "features": [],
  "dm": {
    "timeline": [
      { "period": "2024", "count": 2366, "values": { "zranenie": 701, "hmotná škoda": 1665 } },
      { "period": "2025", "count": 1894, "values": { "zranenie": 652, "hmotná škoda": 1242 } }
    ]
  }
}
```

Súhrnný vývoj za celé územie namiesto počtov objektov (zvolené obdobie 2023–2025):

```json data
{
  "type": "FeatureCollection",
  "features": [],
  "dm": {
    "chart": {
      "label": "Počet obyvateľov Slovenska k 31. 12.",
      "highlight": { "from": "2022", "to": "2025" },
      "points": [
        { "period": "2021", "value": 5459781 },
        { "period": "2022", "value": 5434712 },
        { "period": "2023", "value": 5424687 },
        { "period": "2024", "value": 5415949 },
        { "period": "2025", "value": 5410836 }
      ]
    }
  }
}
```

Objekt s grafom vývoja v detaile:

```json data
{
  "type": "FeatureCollection",
  "features": [{
    "type": "Feature",
    "id": "500496",
    "geometry": { "type": "Point", "coordinates": [18.7408, 49.2231] },
    "properties": { "nazev": "Žilina", "obyvatel": 80500 },
    "dm": {
      "chart": {
        "label": "Počet obyvateľov k 31. 12.",
        "points": [
          { "period": "2023", "value": 81200 },
          { "period": "2024", "value": 80900 },
          { "period": "2025", "value": 80500 }
        ]
      }
    }
  }]
}
```
- Vlastnosti s prefixom `__dm_` sú rezervované pre portál a z odpovede sa odstránia.

## Cache {#cache}

- Portál drží odpovede po dobu `min(cache.ttl, dm.ttl)`, predvolene 300 s. Manifesty 10 min.
- Po uplynutí drží záznam ešte 24 h ako zálohu: keď zdroj neodpovedá, ukáže posledné dáta s upozornením.
- `cache.store: false` – poskytovateľ nesúhlasí s trvalým uložením dát do dátovej vrstvy portálu (krátkodobé cachovanie odpovedí podľa `ttl` platí ďalej).

## Validácia {#validace}

Zhodu s protokolom overuje [validátor](https://datovamapa.sk/dokumentacia/api.md#validator) (`POST /api/validate`, živý test `GET /api/validate?manifestUrl=…`, alebo MCP nástroje `validate_manifest` a `validate_data`). Rozlišuje:

- **chyby** (`errors`) – porušenie tohto dokumentu; manifest s chybou portál neprijme, dáta s chybou nezobrazí,
- **odporúčania** (`warnings`) – dáta fungujú, ale horšie sa hľadajú, zobrazujú alebo kombinujú.

Každý nález má stabilný `code` ([prehľad kódov](https://datovamapa.sk/dokumentacia/api.md#kody-nalezu)), cestu `path` a pri odporúčaniach radu `hint`. Kódy sa medzi minor verziami nemenia, nové môžu pribúdať.

## Vývoj protokolu {#vyvoj-protokolu}

- Nové voliteľné polia a nové typy `presentation` / `source` = nová minor verzia (0.2…).
- Zmena významu existujúcich polí = nová major verzia; portál po prechodný čas podporuje obe.
- Kandidáti na ďalšie verzie: `symbol` (ikony), `extrusion` (3D), časová dimenzia (`time` pri objektoch + parameter), `vector-tiles` / `pmtiles` / `ogc-features` ako zdroje, stránkovanie cez `next`, agregácia pre malé priblíženia.
