# API portálu DátováMapa {#api-portalu-datovamapa}

Strojové rozhranie portálu pre aplikácie a AI agentov: katalóg dát, dáta zo všetkých zdrojov v zjednotenom tvare, dotazy na miesto (čo je v bode a okolí, súhrn za obec), validátor a registrácia pre poskytovateľov a MCP server. Všetko je verejné, bez autentifikácie, s CORS `*`. Formálny popis je v [OpenAPI](https://datovamapa.sk/openapi.json).

## Prehľad {#prehled}

| Metóda a cesta | Účel |
|---|---|
| `GET /api/catalog` | všetci poskytovatelia a dátové sady (JSON) |
| `GET /api/data/{provider}/{dataset}` | dáta sady ako GeoJSON, cez cache portálu |
| `GET /api/places?query=…` | hľadanie adresy, ulice alebo obce → súradnice |
| `GET /api/nearby?point=…` | čo je v bode a okolí, z vybraných sád |
| `GET /api/summary/{provider}/{dataset}` | súhrn sady za celé územie alebo za obec |
| `GET /api/validate?manifestUrl=…` | živý test poskytovateľa |
| `POST /api/validate` | kontrola manifestu alebo dát bez zverejnenia |
| `POST /api/registration` | registrácia poskytovateľa (dáta čakajú na schválenie) |
| `POST /mcp` | MCP server (Streamable HTTP) |
| `GET /llms.txt`, `/llms-full.txt` | rozcestník a celá dokumentácia pre jazykové modely |
| `GET /index.md`, `/zdroje.md`, `/dokumentacia/{slug}.md` | stránky portálu v markdowne |
| `GET /schema/0.1/manifest.json`, `/schema/0.1/data.json` | JSON Schema protokolu |
| `GET /schema/0.1/provider-openapi.json` | OpenAPI kontrakt, ktorý implementuje poskytovateľ |
| `GET /priklady/{soubor}.json` | platné ukážkové manifesty a odpovede |

## Katalóg {#katalog}

`GET /api/catalog`

```json
{
  "protocol": "0.1",
  "generated": "2026-10-06T08:00:00.000Z",
  "providers": [{ "id": "cgs", "name": "Česká geologická služba", "status": "ok", "datasetCount": 2, "managedBy": "portal" }],
  "datasets": [
    {
      "key": "cgs/radon",
      "providerId": "cgs",
      "providerName": "Česká geologická služba",
      "title": "Radonový index",
      "category": "risks",
      "categoryLabel": "Rizika a omezení",
      "keywords": ["radon"],
      "useCases": ["construction", "housing"],
      "source": { "type": "raster", "tiles": ["https://…"] },
      "presentation": { "type": "raster", "opacity": 0.45 },
      "attribution": "© Česká geologická služba",
      "links": { "data": null, "map": "/?d=cgs/radon" }
    }
  ]
}
```

Katalóg obsahuje iba schválené dáta. Sady poskytovateľov, ktorí sa zaregistrovali sami a zatiaľ nie sú schválení, v ňom nie sú (pozri [Registrácia](#registrace)).

Dátové sady nesú všetky polia z manifestu poskytovateľa (`description`, `fields`, `params`, `coverage`…) okrem URL zdroja – GeoJSON dáta sa čítajú cez portál (`links.data`), rastrové dlaždice priamo zo zdroja (`source.tiles`). Rovnaký obsah čitateľný pre ľudí aj modely: [zdroje.md](https://datovamapa.sk/zdroje.md).

## Dáta {#data}

`GET /api/data/{provider}/{dataset}`

| Parameter | Kedy | Popis |
|---|---|---|
| `bbox` | sady so `source.mode = "bbox"` (povinný) | `minLon,minLat,maxLon,maxLat` vo WGS84; portál ho zarovná na dlaždice |
| `zoom` | sady so `source.mode = "bbox"` (povinný) | úroveň priblíženia 0–24 |
| `cursor` | voliteľne | kurzor z `dm.next` |
| `{param}` | podľa `params` sady | hodnoty vo formáte protokolu (`a,b`, `od,do`); nevyplnené dostanú `default` |

Odpoveď je GeoJSON `FeatureCollection`. Údaje z `feature.dm` poskytovateľa sú presunuté do `properties` s prefixom `__dm_` (`__dm_title`, `__dm_description`, `__dm_url`, `__dm_color`, `__dm_chart`). Pri sadách s `color.type = "trend"` pridá portál `__dm_trend` (`roste`, `stagnuje`, `klesá`) vypočítaný z `dm.chart`. Metadáta odpovede:

```json
{ "dm": { "protocol": "0.1", "dataset": "aopk/pamatne-stromy", "generated": "…", "ttl": 86400, "total": 13, "truncated": false, "notice": null } }
```

Hlavička `X-DM-Cache`: `hit` (z cache), `miss` (čerstvo zo zdroja), `stale` (zdroj nedostupný, posledné známe dáta – pozri `dm.notice`).

Chyby majú tvar `{ "error": "správa", "code": "kod" }`: `400` neplatný dotaz, `404` neznáma sada, `502` chyba zdroja.

**Sady len na zobrazenie.** Pri niekoľkých sadách spravovaných portálom nemá zdroj doloženú licenciu na ďalšie šírenie. Portál ich kreslí vo vlastnej mape, ale dáta ďalej nevydáva: v katalógu majú `links.data` prázdne a v `links.source` adresu pôvodnej služby poskytovateľa. Dotaz mimo mapu portálu dostane `303` s hlavičkou `Location` na túto službu a telom `{ "error": "…", "code": "display_only", "source": "…" }`. Rovnako odpovie nástroj MCP `fetch_data`.

## Miesto a okolie {#misto-a-okoli}

Dotazy pre AI asistentov a aplikácie, ktoré odpovedajú na otázky o konkrétnom mieste. Vracajú ľudsky popísané hodnoty (popisky a jednotky podľa `fields` sady) bez geometrií, s atribúciou a odkazom na mapu. Návod pre používateľov asistentov: [Dáta pre AI asistentov](https://datovamapa.sk/dokumentacia/ai-asistenti.md).

### Hľadanie miesta {#hledani-mista}

`GET /api/places?query=Hlavná 1, Košice` (voliteľne `max`, predvolene 5, najviac 10)

Hľadá v registri adries adresy, ulice, obce, časti obcí a ďalšie územné prvky. Zadajte len adresu alebo názov; upresnenia ako okres alebo „pri Zlatých Moravciach“ služba nepozná. `municipality` je obec, v ktorej miesto leží (`name`, `district`, `region` a kód obce `code`) – pre ňu vie [súhrn](#souhrn) dáta za celú obec. Pri miestach mimo miest nad 10 000 obyvateľov je navyše `near` najbližšie takéto mesto a vzdialenosť v km; podľa oboch sa rozlíšia rovnomenné miesta.

```json
{
  "query": "Hlavná 1, Košice",
  "count": 1,
  "places": [{ "name": "Hlavná 1, 04001 Košice", "type": "adresa", "point": [21.258, 48.7209], "municipality": { "slug": "kosice", "code": "598186", "name": "Košice", "district": "Košice I", "region": "Košický kraj" } }],
  "attribution": "© zdroj registra adries"
}
```

### Čo je v bode a okolí {#co-je-v-bode-a-okoli}

`GET /api/nearby`

| Parameter | Popis |
|---|---|
| `point` | `lon,lat` vo WGS84 |
| `place` | miesto `point`: adresa alebo názov, použije sa prvý nález hľadania miesta |
| `radius` | polomer okolia v metroch, predvolene 500, najviac 20 000 |
| `datasets` | kľúče `provider/dataset` oddelené čiarkou, najviac 12 |
| `purpose` | namiesto `datasets`: sady s týmto účelom (`useCases`), ktoré bod pokrývajú |
| `search` | namiesto `datasets`: sady podľa zhody s textom, napr. `rizika pre stavbu` |
| `max` | najviac objektov na sadu, predvolene 5, najviac 50 |
| `{provider}/{dataset}.{param}` | parameter sady, rovnako ako v [odkaze na mapu](#odkaz-na-mapu) |

Jedno z `datasets`, `purpose`, `search` je povinné. Automatický výber berie len sady, ktoré vedia na bod odpovedať: najprv riziká a obmedzenia, podkladové mapy nakoniec. Sady nad limit vráti v `skipped`.

- **GeoJSON sady:** objekty do vzdialenosti `radius` zoradené od najbližšieho. `distance` je v metroch, 0 = bod leží vo vnútri plochy (napr. obec pri kartograme). `count` je počet objektov v okolí. Sady, ktoré sa načítavajú len pri veľkom priblížení, okolie zmenšia (`radius`, `notice`). Pri celých sadách (`mode: full`), ktoré v okolí nič nemajú, vráti aspoň najbližší objekt (napr. meraciu stanicu).
- **Rastrové sady:** portál sa opýta zdroja priamo na bod. Dotaz odvodí zo šablóny dlaždíc: WMS `GetMap` → `GetFeatureInfo`, ArcGIS `MapServer/export` → `identify`, `ImageServer/exportImage` → `identify` s tabuľkou tried rastra. Hodnoty sú atribúty zdroja (názvy polí, ako ich zdroj vracia). Pri výklade kódov pomôže `description` a `legend`.

| `status` | Význam |
|---|---|
| `ok` | dotaz prebehol; prázdne `hits` = v okolí / v bode nič nie je (napr. mimo záplavového územia) |
| `unavailable` | sada hodnotu v bode neposkytuje (dlaždice sú len obraz) alebo bod leží mimo pokrytia |
| `error` | zdroj zlyhal (`error`, `code`) |

```json
{
  "place": { "name": "Hlavná 1, 04001 Košice", "type": "adresa", "point": [21.258, 48.7209] },
  "point": [21.258, 48.7209],
  "radius": 500,
  "generated": "2026-10-06T16:00:00.000Z",
  "results": [
    {
      "dataset": "cgs/radon",
      "title": "Radonový index",
      "provider": "Česká geologická služba",
      "attribution": "© Česká geologická služba",
      "status": "ok",
      "hits": [{ "title": "Radonový index", "distance": 0, "values": [{ "label": "radonovériziko", "value": "přechodný" }, { "label": "stupeňradonovéhoindexu", "value": "2" }] }]
    },
    {
      "dataset": "npu/kulturni-pamatky",
      "title": "Kulturní památky",
      "provider": "Národní památkový ústav",
      "attribution": "Národní památkový ústav",
      "license": "CC BY-SA 4.0",
      "status": "ok",
      "count": 27,
      "radius": 500,
      "hits": [
        {
          "title": "továrna Breitfeld-Daněk",
          "distance": 91,
          "values": [{ "label": "Rejstříkové číslo ÚSKP", "value": "105958" }, { "label": "Stav ochrany", "value": "památkově chráněno" }],
          "url": "https://pamatkovykatalog.cz/x-14624751"
        }
      ]
    }
  ],
  "map": "https://datovamapa.sk/?d=cgs/radon&d=npu/kulturni-pamatky#15/48.7209/21.258"
}
```

### Súhrn {#souhrn}

`GET /api/summary/{provider}/{dataset}?municipality=Žilina` (ostatné query parametre sú parametre sady)

Súhrn GeoJSON sady za celé územie, alebo s `municipality` len za obec – ktorúkoľvek obec Slovenska: `count`, `categories` (počty podľa kategórie farby), `rankings` (najvyššie a najnižšie hodnoty) a pri kartograme `own` – hodnoty plochy, v ktorej obec leží. Sú to rovnaké čísla, aké ukazuje stránka sady. Sady načítavané len pri veľkom priblížení majú súhrn len za obec. Rastrové sady súhrn nemajú.

`municipality` je názov („Žilina“), názov s okresom alebo krajom („Nová Ves (okres Trenčín)“), kód obce („598186“, vracia ho [hľadanie miesta](#hledani-mista) v `municipality.code`) alebo adresa jej prehľadu („trenciansky-kraj/nova-ves-trencin“). Samotný názov, ktorý nesie viac obcí, skončí chybou `ambiguous_place` so zoznamom týchto obcí, ich okresov a kódov.

## Validátor {#validator}

Nástroj pre poskytovateľov a ich AI agentov. Vracia vždy HTTP 200 a report:

```json
{
  "valid": false,
  "summary": "Manifest není platný: 1 chyb, 2 doporučení.",
  "errors": [{ "path": "datasets[0].source.tiles[0]", "code": "raster_without_template", "message": "Šablona dlaždic neobsahuje {z}/{x}/{y} ani {bbox-epsg-3857}." }],
  "warnings": [{ "path": "datasets[0].keywords", "code": "missing_keywords", "message": "Sada nemá klíčová slova.", "hint": "Doplňte 5–15 slov…" }]
}
```

- `POST /api/validate` s telom:
  - manifest (objekt s `datasets`) alebo `{ "manifest": … }` – statická kontrola,
  - GeoJSON `FeatureCollection` alebo `{ "data": …, "dataset": … }` – kontrola dát; s `dataset` (objekt sady z manifestu) aj súlad s manifestom,
  - `{ "manifestUrl": "https://…" }` – živý test.
- `GET /api/validate?manifestUrl=https://…` – živý test: stiahne manifest, skontroluje ho a na každú sadu pošle testovací dotaz ako portál (pri `bbox` na stred `coverage.bbox`, zoom 12 alebo `coverage.minZoom`; pri rastri jednu dlaždicu). Report má navyše `provider` a `datasets[]` s `request`, `durationMs`, `featureCount`, `errors`, `warnings`.

## Registrácia {#registrace}

`POST /api/registration` s telom `{ "manifestUrl": "https://…" }`. Portál manifest skontroluje živým testom (ako validátor). Keď prejde, zaregistruje poskytovateľa medzi neschválené dáta:

- Dáta sú dostupné cez `/api/data/…` aj na stránkach sád `/mapa/{provider}/{dataset}`. Stránka najprv ukáže varovanie, že dáta nahrala tretia strana a prevádzkovateľ ich neschválil. Dáta do mapy načíta až po potvrdení. Stránka má `noindex`.
- Do katalógu, vyhľadávania, `llms.txt`, MCP nástroja `catalog` a na stránky za obce sa dáta dostanú až po schválení prevádzkovateľom.
- Schválenie platí pre odtlačok (SHA-256) obsahu manifestu. Po zmene manifestu je poskytovateľ opäť neschválený, kým ho prevádzkovateľ neschváli znova.
- Prehľad neschválených poskytovateľov: [/neschvalene-data](https://datovamapa.sk/neschvalene-data).

```json
{
  "registered": true,
  "status": "pending_review",
  "message": "Registrováno. …",
  "provider": { "id": "obec-priklad", "name": "Obec Příklad" },
  "links": { "review": "/neschvalene-data#obec-priklad", "datasets": ["/mapa/obec-priklad/lavicky"] },
  "check": { "summary": "Poskytovatel je platný bez výhrad.", "warnings": [] }
}
```

| HTTP | `code` | Význam |
|---|---|---|
| 201 | – | zaregistrované, čaká na schválenie |
| 200 | – | už zaregistrované; `status` je `pending_review` alebo `approved` |
| 400 | `invalid_input`, `invalid_url` | chýba alebo je neplatná `manifestUrl` |
| 403 | `rejected` | registráciu prevádzkovateľ zamietol |
| 409 | `id_taken`, `url_registered` | `provider.id` už v portáli je / URL je registrovaná pod iným id |
| 422 | `manifest_rejected` | živý test neprešiel; report je v `check` |
| 429 | `too_many_requests`, `queue_full` | viac než 5 pokusov za minútu z jednej adresy / na schválenie čaká vyše 100 poskytovateľov |
| 503 | `registration_unavailable` | registrácia teraz nefunguje |

## MCP server {#mcp-server}

Endpoint `https://datovamapa.sk/mcp`, transport Streamable HTTP (bezstavový, odpovede JSON), bez autentifikácie.

| Nástroj | Vstup | Výstup |
|---|---|---|
| `documentation` | `topic`: `ai-agents`, `ai-assistants`, `protocol`, `providers`, `api`, `about` | markdown dokumentu |
| `schema` | `type`: `manifest`, `data`, `provider-openapi` | JSON Schema / OpenAPI |
| `example` | `name`: `manifest-minimal`, `manifest-complete`, `data-points`, `data-polygons` | platný ukážkový JSON |
| `validate_manifest` | `manifest` (objekt) alebo `manifestUrl` (živý test) | report validátora |
| `validate_data` | `data`, voliteľne `dataset` | report validátora |
| `register_provider` | `manifestUrl` | výsledok [registrácie](#registrace) |
| `catalog` | voliteľne `search` (voľný text), `point` (`[lon, lat]`) | dátové sady v portáli, zoradené podľa zhody; `pointQuery` = sada odpovie na `nearby` |
| `find_place` | `query`, `maxResults` | ako [hľadanie miesta](#hledani-mista) |
| `nearby` | `point` alebo `place`; `datasets`, `purpose` alebo `search`; `radius`, `maxFeatures`, `params` (`{ "provider/dataset": { "param": "hodnota" } }`) | ako [čo je v bode a okolí](#co-je-v-bode-a-okoli) |
| `summary` | `dataset`, voliteľne `municipality`, `params` | ako [súhrn](#souhrn) |
| `fetch_data` | `dataset` (`provider/dataset`), `bbox` alebo `municipality`, `zoom`, `params`, `maxFeatures` | GeoJSON (skrátený na `maxFeatures`) |

Pripojenie:

```bash
claude mcp add --transport http datovamapa https://datovamapa.sk/mcp
```

```json
{ "mcpServers": { "datovamapa": { "type": "http", "url": "https://datovamapa.sk/mcp" } } }
```

## Odkaz na mapu {#odkaz-na-mapu}

`https://datovamapa.sk/?d={provider}/{dataset}&d=…&{provider}/{dataset}.{param}={hodnota}#{zoom}/{lat}/{lon}`

Každá sada má aj vlastnú stránku s mapou a popisom: `https://datovamapa.sk/mapa/{provider}/{dataset}`, celoštátne GeoJSON sady aj za obce nad 10 000 obyvateľov: `https://datovamapa.sk/mapa/{provider}/{dataset}/{obec}` (napr. [/mapa/chmu/kvalita-ovzdusi/ostrava](https://datovamapa.sk/mapa/chmu/kvalita-ovzdusi/ostrava)). Odkaz na stránku sady je v katalógu v `links.map`. Na stránke sady (aj zostavenej mapy `/mapy/{slug}`) sa do `?d=…` zapisuje len rozdiel oproti predvolenému výberu: bez `d` platia sady stránky, `d` vymenuje celý výber (`?d=` = nič nie je zapnuté) a parameter sa uvádza, len keď sa líši od predvoleného.

Príklad – dopravné nehody v Brne súhrnne za roky 2019–2023: [/?d=brno/dopravni-nehody&brno/dopravni-nehody.obdobi=2019,2023#13/49.195/16.608](https://datovamapa.sk/?d=brno/dopravni-nehody&brno/dopravni-nehody.obdobi=2019,2023#13/49.195/16.608)

## Kódy nálezov {#kody-nalezu}

Stabilné kódy chýb (`errors`) a odporúčaní (`warnings`) validátora a proxy.

### Manifest {#manifest}

| Kód | Úroveň | Význam |
|---|---|---|
| `schema_*` | chyba | porušenie JSON Schema (`schema_invalid_type`, `schema_too_small`, `schema_invalid_format`, `schema_invalid_value`, `schema_custom`…), `path` ukazuje miesto |
| `unsupported_version` | chyba | iná hlavná verzia protokolu |
| `raster_without_template` | chyba | URL dlaždíc bez `{z}/{x}/{y}` aj `{bbox-epsg-3857}` |
| `geojson_with_raster_presentation` | chyba | GeoJSON zdroj s `presentation.type: "raster"` |
| `param_without_options` | chyba | `enum` / `multi-enum` bez `options` |
| `invalid_default` | chyba | `default` parametra nezodpovedá typu alebo možnostiam |
| `time_param_missing` | chyba | `temporal.param` odkazuje na parameter, ktorý nie je v `params` |
| `time_param_type` | chyba | časový parameter nie je typu `range` ani `date-range` |
| `time_param_no_range` | odporúčanie | časový parameter typu `range` nemá `min` a `max` |
| `unknown_presentation_type` | odporúčanie | portál typ nepozná, kreslí `auto` |
| `raster_without_raster_presentation` | odporúčanie | raster sa vždy kreslí ako `raster` |
| `missing_description`, `missing_keywords`, `missing_use_cases` | odporúčanie | sadu horšie nájdu ľudia aj asistent |
| `missing_category`, `unknown_category` | odporúčanie | sada skončí v „Ostatné“ |
| `missing_field` | odporúčanie | detail objektu ukáže surové názvy vlastností |
| `field_not_described`, `field_not_number` | odporúčanie | prezentácia odkazuje na vlastnosť mimo `fields` / s nečíselným typom |
| `bbox_unbounded` | odporúčanie | sada `bbox` bez `coverage.minZoom` a `maxFeatures` |
| `missing_coverage` | odporúčanie | sada `bbox` bez `coverage.bbox` |
| `missing_license`, `missing_website` | odporúčanie | chýba licencia / web poskytovateľa |

### Dáta {#data}

| Kód | Úroveň | Význam |
|---|---|---|
| `coordinates_out_of_range` | chyba | súradnice mimo WGS84 (typicky neprevedený S-JTSK) |
| `unclosed_polygon` | chyba | prstenec polygónu nie je uzavretý |
| `too_many_features` | odporúčanie | viac objektov než `limit` / 5 000 |
| `missing_time_series` | odporúčanie | sada má `temporal.param`, odpoveď neposiela `dm.timeline` ani `dm.chart` |
| `missing_trend_chart` | odporúčanie | sada farbí podľa číselnej hodnoty a obdobie volí parametrom, objekty však neposielajú `dm.chart` |
| `trend_without_chart` | odporúčanie | sada sa farbí podľa trendu, niektoré objekty nemajú `dm.chart` (zostanú sivé) |
| `swapped_coordinates` | odporúčanie | súradnice zrejme v poradí `[lat, lon]` |
| `outside_coverage` | odporúčanie | väčšina objektov mimo `coverage.bbox` |
| `geometry_presentation_mismatch` | odporúčanie | napr. plochy pri `circle` |
| `field_missing_in_data`, `missing_presentation_property` | odporúčanie | vlastnosť z manifestu v dátach chýba |
| `missing_id` | odporúčanie | objekty bez `id` |
| `empty_geometry` | odporúčanie | objekty s `geometry: null` sa preskočia |

### Živý test a proxy {#zivy-test-a-proxy}

| Kód | Význam |
|---|---|
| `invalid_url`, `https_required` | neplatná URL / zdroj nie je na HTTPS |
| `source_unreachable`, `timeout`, `http_error` | zdroj neodpovedá, nestihol 10 s, vrátil HTTP chybu |
| `invalid_json`, `empty_body`, `response_too_large` | odpoveď nie je JSON / je prázdna / má viac než 15 MB |
| `invalid_manifest`, `id_mismatch` | manifest registrovaného poskytovateľa neprešiel / má iné `provider.id` |
| `registration_unavailable`, `too_many_requests`, `queue_full`, `manifest_rejected`, `id_taken`, `url_registered`, `rejected` | chyby [registrácie](#registrace) |
| `data_schema_mismatch` | dáta od zdroja nezodpovedajú schéme |
| `empty_response`, `slow_response` | testovací dotaz vrátil 0 objektov / trval vyše 3 s |
| `tile_http_error`, `tile_not_image`, `tile_unreachable` | testovacia rastrová dlaždica zlyhala |
| `source_error` | iná chyba pri komunikácii so zdrojom (podrobnosti v `message`) |
| `invalid_query`, `unknown_dataset`, `raster_dataset`, `invalid_input`, `internal_error` | chyby dotazu na portál |
| `display_only` | sadu portál iba zobrazuje, dáta poskytuje pôvodná služba (`source`) |
| `missing_place`, `unknown_place` | dotaz na miesto bez bodu aj miesta / miesto (adresu, obec) sa nepodarilo nájsť |
| `geocoding_unavailable` | hľadanie adries a miest v danej krajine portál zatiaľ nemá (HTTP 501) |
| `ambiguous_place` | názov obce nesie viac obcí – správa ich vymenuje s okresom a kódom |
| `missing_dataset_selection` | dotaz na okolie bez `datasets`, `purpose` aj `search` |
| `summary_requires_place` | sada sa dá načítať len po priblížení, súhrn za celé územie nemá – zadajte obec |
| `unknown_schema`, `unknown_example` | neexistujúca schéma / príklad (odpoveď obsahuje zoznam `available`) |
