# Návod pre AI agentov: pripojenie dát do DátovejMapy {#navod-pro-ai-agenty-pripojeni-dat-do-datovemapy}

Tento dokument je určený AI agentom, ktorí pripravujú dáta pre portál DátováMapa. Poskytovateľom môže byť ktokoľvek, kto má dáta s polohou. Popisuje cieľ, postup, pravidlá a kritériá hotovej práce. Človek, ktorý agenta riadi, nájde zrozumiteľnejšiu verziu v [sprievodcovi pre poskytovateľov](https://datovamapa.sk/dokumentacia/pre-poskytovatelov.md).

## Cieľ {#cil}

Zverejniť na HTTPS:

1. **manifest** – JSON podľa [schémy manifestu](https://datovamapa.sk/schema/0.1/manifest.json),
2. pre každú dátovú sadu **zdroj dát** – GeoJSON súbor alebo endpoint podľa [schémy dát](https://datovamapa.sk/schema/0.1/data.json) a [OpenAPI kontraktu poskytovateľa](https://datovamapa.sk/schema/0.1/provider-openapi.json), prípadne existujúce rastrové dlaždice / WMS,

tak, aby [validátor](https://datovamapa.sk/dokumentacia/api.md#validator) vrátil `"valid": true` a čo najmenej varovaní.

## Čo si načítať {#co-si-nacist}

| Zdroj | Prečo |
|---|---|
| [llms.txt](https://datovamapa.sk/llms.txt) | rozcestník celej dokumentácie |
| [Protokol 0.1](https://datovamapa.sk/dokumentacia/protokol.md) | normatívna špecifikácia – pri nejasnosti platí tá |
| [JSON Schema manifestu](https://datovamapa.sk/schema/0.1/manifest.json), [dát](https://datovamapa.sk/schema/0.1/data.json) | presné typy, limity a popisy polí |
| [OpenAPI poskytovateľa](https://datovamapa.sk/schema/0.1/provider-openapi.json) | kontrakt endpointu, dá sa z neho generovať server |
| [manifest-complete.json](https://datovamapa.sk/priklady/manifest-complete.json), [manifest-minimal.json](https://datovamapa.sk/priklady/manifest-minimal.json) | platné vzory |
| [data-points.json](https://datovamapa.sk/priklady/data-points.json), [data-polygons.json](https://datovamapa.sk/priklady/data-polygons.json) | platné vzory odpovedí |
| [Katalóg](https://datovamapa.sk/zdroje.md) | čo už v portáli je – nevytvárajte duplicity, inšpirujte sa kľúčovými slovami |

Ak viete používať MCP, pripojte sa k serveru `https://datovamapa.sk/mcp` (Streamable HTTP, bez autentifikácie). Nástroje `documentation`, `schema`, `example`, `validate_manifest`, `validate_data` a `catalog` pokrývajú všetko v tomto návode. Pozri [MCP server](https://datovamapa.sk/dokumentacia/api.md#mcp-server).

## Postup {#postup}

### 1. Inventúra dát {#1-inventura-dat}

Zistite, aké priestorové dáta poskytovateľ má: databázy (PostGIS, MS SQL), GIS súbory (SHP, GPKG, KML, CSV so súradnicami), existujúce API, služby WMS/WMTS. Pri každom zdroji zistite:

- typ geometrie (body / línie / plochy),
- súradnicový systém (na Slovensku často **S-JTSK, EPSG:5514** – treba previesť),
- počet objektov a ako často sa menia,
- licenciu a kto ju môže schváliť,
- či obsahuje **osobné údaje** (mená, rodné čísla, adresy fyzických osôb, EČV…).

### 2. Návrh dátových sád {#2-navrh-datovych-sad}

- Jedna sada = jeden druh objektov s jedným spôsobom zobrazenia. Kontajnery a hlukovú mapu dajte do dvoch sád.
- `id` sady aj poskytovateľa: malé písmená bez diakritiky, číslice, spojovníky (`kontejnery-na-odpad`). Po zverejnení ho nemeňte – je súčasťou odkazov.
- Voľba zdroja:

| Situácia | `source` |
|---|---|
| do ~2 000 objektov, menia sa najviac denne | statický súbor, `"type": "geojson", "mode": "full"` |
| viac objektov alebo živé dáta | endpoint, `"mode": "bbox"`, nastavte `coverage.bbox` a pri veľkých sadách `coverage.minZoom` |
| už existuje WMS / XYZ dlaždice | `"type": "raster"` so šablónou `{bbox-epsg-3857}` alebo `{z}/{x}/{y}`; doplňte `presentation.legend` (farby a popisky z legendy služby, napr. ArcGIS `…/MapServer/legend?f=json` alebo WMS `GetLegendGraphic`) |

### 3. Prevod dát {#3-prevod-dat}

- Súradnice **WGS84 (EPSG:4326), poradie `[lon, lat]`**. Pre Slovensko je to zhruba `[19, 48]`, nie `[48, 19]`.
- Zaokrúhlite na 6 desatinných miest (≈ 10 cm), zvyšok len zväčšuje odpoveď.
- Polygóny musia mať uzavreté prstence (prvý bod = posledný).
- Každý objekt by mal mať stabilné `id`.
- Vlastnosti (`properties`) ako jednoduché hodnoty – reťazce, čísla, booleany, dátumy v ISO 8601. Žiadne HTML.
- Čísla ako čísla (`1100`), nie reťazce (`"1100 l"`); jednotku dajte do `fields[].unit`.

Prevod GIS súboru do GeoJSON:

```bash
ogr2ogr -f GeoJSON -t_srs EPSG:4326 -lco RFC7946=YES -lco COORDINATE_PRECISION=6 lavicky.geojson vstup.shp
```

Prevod súradníc v Pythone:

```python
from pyproj import Transformer

to_wgs84 = Transformer.from_crs("EPSG:5514", "EPSG:4326", always_xy=True)
lon, lat = to_wgs84.transform(x_sjtsk, y_sjtsk)  # always_xy=True vracia [lon, lat]
```

### 4. Manifest {#4-manifest}

Vyplňte nielen povinné polia, ale aj tie, ktoré rozhodujú o tom, či dáta niekto nájde:

- `description` – 1–2 vety: čo dáta obsahujú, odkiaľ sú, ako sú aktuálne.
- `keywords` – 5–15 slov a synoným v slovenčine, vrátane hovorových tvarov (`smetnica` popri `kontajner`).
- `useCases` – na čo dáta pomáhajú: `construction`, `housing`, `land-purchase`, `agriculture`, `investment`, `transport`, `tourism`, `business`, `public-administration`. Podľa nich asistent portálu vyberá dáta k zadaniu typu „chcem stavať v obci X“.
- `category` – jedna z: `territory`, `nature`, `water`, `risks`, `energy`, `transport`, `society`, `economy`, `infrastructure`.
- `fields` – každá vlastnosť, ktorú má používateľ vidieť: `label`, `type`, `unit`. Jednu označte `primary` (nadpis v detaile).
- `license` – názov a text atribúcie. **Licenciu si nevymýšľajte**; ak ju neviete, opýtajte sa človeka.
- `temporal.updated`, `temporal.frequency` – aktuálnosť dát.
- `temporal.param` – pri dátach v čase (nehody, merania, udalosti): kľúč parametra typu `range` s rokmi (`min`/`max` = prvý a posledný rok), ktorým používateľ volí obdobie. Odpoveď k tomu má posielať `dm.timeline` s počtami po rokoch (pri hodnotách v čase, ako je počet obyvateľov, namiesto toho súhrnný `dm.chart`), pozri [časový filter](https://datovamapa.sk/dokumentacia/protokol.md#casovy-filtr).
- **Vývoj v čase** – zistite, či majú objekty hodnotu za viac období (stavy po rokoch, merania, ceny). Ak áno, posielajte ju vždy pri každom objekte v `dm.chart`; ak je zmyslom sady zmena, farbite podľa trendu. Pozri [vývoj v čase a trend](https://datovamapa.sk/dokumentacia/protokol.md#vyvoj-v-case-a-trend).

### 5. Vizualizácia {#5-vizualizace}

| Geometria | Vhodný typ | Poznámka |
|---|---|---|
| body, desiatky až stovky | `circle` | farba podľa kategórie (`categorical`), popisok cez `label` |
| body, tisíce | `circle` s `cluster` alebo `heatmap` | heatmapa len pre hustotu, neukazuje jednotlivé objekty |
| línie | `line` | šírka môže závisieť od hodnoty |
| plochy s hodnotou | `fill` + `interpolate` alebo `step` | kartogram; `opacity` 0.4–0.6, aby bol vidieť podklad |
| body alebo plochy, ktorých hodnota sa mení v čase | `circle` / `fill` + `color: { "type": "trend" }` | ak ide o zmenu (rastie / klesá); rad hodnôt v `dm.chart` pri každom objekte, trend dopočíta portál |
| plochy bez hodnoty | `fill` s jednou farbou | |

Pravidlá: farby hex; kategórie max. ~8 farieb; pre hodnoty použite postupnú škálu od svetlej po tmavú; `field` v prezentácii musí zodpovedať vlastnosti v dátach (a vo `fields`, s číselným typom pri `interpolate`/`step`). Ak má hodnota objektu históriu, pošlite ju v `dm.chart` pri akejkoľvek prezentácii – aj pri kartograme s výberom roka (zvolený rok v `highlight`).

### 6. Endpoint (len pri `mode: "bbox"` alebo živých dátach) {#6-endpoint-jen-u-mode-bbox-nebo-zivych-dat}

Implementujte `GET` podľa [OpenAPI kontraktu](https://datovamapa.sk/schema/0.1/provider-openapi.json):

- query `bbox=minLon,minLat,maxLon,maxLat` – vráťte objekty, ktoré výrez pretínajú,
- `zoom` – celé číslo; pri malom priblížení môžete vracať agregácie,
- `limit` – nevracajte viac objektov; ak ich orežete, nastavte `dm.truncated: true` a `dm.total`,
- vlastné parametre z `params` (rozsah `od,do`, viac hodnôt `a,b,c`),
- `Content-Type: application/geo+json` alebo `application/json`, HTTPS, odpoveď do 1 s,
- neznáme query parametre ignorujte (`lang`, `protocol`, `cursor` môžete obísť).

CORS nie je potrebný – portál sa pýta zo servera.

Python (FastAPI + PostGIS):

```python
from fastapi import FastAPI

app = FastAPI()

@app.get("/datovamapa/kontejnery")
def kontejnery(bbox: str | None = None, zoom: int | None = None, limit: int = 5000, druh: str | None = None):
    west, south, east, north = map(float, bbox.split(",")) if bbox else (-180, -90, 180, 90)
    druhy = druh.split(",") if druh else None
    rows = db.fetch_all(
        """
        SELECT id, druh, objem, vyvoz::text, ST_AsGeoJSON(geom, 6)::json AS geometry
        FROM kontejnery
        WHERE geom && ST_MakeEnvelope(%s, %s, %s, %s, 4326)
          AND (%s::text[] IS NULL OR druh = ANY(%s))
        LIMIT %s
        """,
        (west, south, east, north, druhy, druhy, limit + 1),
    )
    features = [
        {"type": "Feature", "id": r["id"], "geometry": r["geometry"],
         "properties": {"druh": r["druh"], "objem": r["objem"], "vyvoz": r["vyvoz"]}}
        for r in rows[:limit]
    ]
    return {"type": "FeatureCollection", "features": features, "dm": {"truncated": len(rows) > limit, "ttl": 3600}}
```

TypeScript (Cloudflare Worker / Node, dáta v pamäti):

```ts
// KONTEJNERY: pole GeoJSON Feature s bodmi, načítané pri štarte (z databázy alebo súboru).
declare const KONTEJNERY: { type: "Feature"; id: number; geometry: { type: "Point"; coordinates: [number, number] }; properties: Record<string, unknown> }[];

export default {
  async fetch(request: Request): Promise<Response> {
    const url = new URL(request.url);
    const [west, south, east, north] = (url.searchParams.get("bbox") ?? "-180,-90,180,90").split(",").map(Number);
    const limit = Math.min(Number(url.searchParams.get("limit")) || 5000, 5000);
    const inside = KONTEJNERY.filter(({ geometry: { coordinates: [lon, lat] } }) =>
      lon >= west && lon <= east && lat >= south && lat <= north);
    return Response.json(
      { type: "FeatureCollection", features: inside.slice(0, limit), dm: { total: inside.length, truncated: inside.length > limit } },
      { headers: { "Content-Type": "application/geo+json", "Cache-Control": "public, max-age=300" } },
    );
  },
};
```

### 7. Validácia {#7-validace}

Opakujte, kým nie sú chyby, a prejdite každé varovanie (opravte, alebo vedome ponechajte a zdôvodnite):

```bash
# manifest (bez zverejnenia)
curl -sX POST https://datovamapa.sk/api/validate -H 'Content-Type: application/json' --data @manifest.json
# dáta proti konkrétnej sade
curl -sX POST https://datovamapa.sk/api/validate -H 'Content-Type: application/json' \
  --data "{\"data\": $(cat lavicky.geojson), \"dataset\": $(jq '.datasets[0]' manifest.json)}"
# živý test zverejneného manifestu a všetkých zdrojov
curl -s 'https://datovamapa.sk/api/validate?manifestUrl=https://www.obec-priklad.sk/datovamapa/manifest.json'
```

Odpoveď: `{ valid, summary, errors: [{ path, code, message, hint? }], warnings: [...] }`, pri živom teste navyše `datasets[]` s dopytom, dobou odozvy a počtom objektov. Význam kódov je v [API portálu](https://datovamapa.sk/dokumentacia/api.md#kody-nalezu).

### 8. Odovzdanie človeku {#8-predani-cloveku}

Na záver zhrňte:

- URL manifestu a zoznam sád (id, názov, typ zdroja, počet objektov),
- výsledok živého testu (`summary`, zvyšné varovania a prečo zostali),
- čo musí človek potvrdiť: **licenciu a atribúciu**, že dáta neobsahujú osobné údaje, kontakt pre portál,
- ako dáta aktualizovať (skript, cron, zdroj pravdy).

Keď človek potvrdí licenciu a obsah, zaregistrujte manifest: `POST https://datovamapa.sk/api/registration` s `{ "manifestUrl": "…" }` alebo MCP nástroj `register_provider`. Dáta budú dostupné ako neschválené (s varovaním, mimo katalógu), kým ich prevádzkovateľ neschváli. Po každej zmene manifestu čakajú na nové schválenie. Podrobnosti: [registrácia](https://datovamapa.sk/dokumentacia/pre-poskytovatelov.md#5-registrace).

## Pravidlá {#pravidla}

- **Nezverejňujte osobné údaje** (GDPR). Pri pochybnosti dáta agregujte alebo vynechajte a opýtajte sa.
- Nevymýšľajte licenciu, zdroj ani aktuálnosť dát.
- Do `properties` ani `dm` nevkladajte HTML; portál všetko zobrazuje ako text.
- Do URL nedávajte tajné kľúče – manifest je verejný.
- Nemeňte `provider.id` ani `dataset.id` po zverejnení.
- Kľúče `bbox`, `zoom`, `limit`, `cursor`, `lang`, `protocol` nepoužívajte pre vlastné parametre.
- Max. 5 000 objektov a 15 MB na odpoveď, odpoveď do 10 s (cieľom je do 1 s).

## Kritériá hotovej práce {#kriteria-hotove-prace}

- [ ] Manifest je dostupný na HTTPS a živý test validátora vracia `"valid": true`.
- [ ] Každá sada má `description`, `keywords`, `useCases`, `category` a (pri GeoJSON) `fields`.
- [ ] Licencia a atribúcia sú potvrdené človekom.
- [ ] Súradnice sú WGS84 `[lon, lat]`, žiadne varovanie `swapped_coordinates` ani `outside_coverage`.
- [ ] Žiadna sada nevracia v teste 0 objektov (`empty_response`), ak to nie je zámer.
- [ ] Objekty, ktoré majú hodnotu za viac období, posielajú `dm.chart` (žiadne `missing_trend_chart` ani `trend_without_chart`).
- [ ] Odozva endpointov je pod 3 s (`slow_response`).
- [ ] Dáta neobsahujú osobné údaje.
- [ ] Je opísané, ako sa dáta aktualizujú.

## Zadanie pre agenta (na skopírovanie) {#zadani-pro-agenta-ke-zkopirovani}

Človek môže svojmu agentovi dať tento text:

```text
Priprav naše priestorové dáta pre portál DátováMapa (https://datovamapa.sk).
Postupuj podľa návodu https://datovamapa.sk/dokumentacia/pre-ai-agentov.md
(rozcestník dokumentácie: https://datovamapa.sk/llms.txt, MCP server: https://datovamapa.sk/mcp).
Zdroje dát: <popíš databázy, súbory, služby>.
Kam zverejniť: <web / server / repozitár>.
Licencia: <napr. CC BY 4.0, atribúcia „© Obec Príklad“> – inú si nevymýšľaj.
Hotovo je, keď živý test validátora vracia valid: true a prejdeš kritériá hotovej práce.
Na konci mi odovzdaj zhrnutie podľa kroku 8.
```
