DatovaMapa.cz

Strojovo čitateľná verzia: /sk/dokumentace/pro-ai-agenty.md

Návod pro AI agenty: připojení dat do DatovéMapy

Tento dokument je určený AI agentům, kteří připravují data pro portál DatováMapa. Poskytovatelem může být kdokoli, kdo má data s polohou. Popisuje cíl, postup, pravidla a kritéria hotové práce. Člověk, který agenta řídí, najde srozumitelnější verzi v průvodci pro poskytovatele.

Cíl

Zveřejnit na HTTPS:

  1. manifest – JSON podle schématu manifestu,
  2. pro každou datovou sadu zdroj dat – GeoJSON soubor nebo endpoint podle schématu dat a OpenAPI kontraktu poskytovatele, případně existující rastrové dlaždice / WMS,

tak, aby validátor vrátil "valid": true a co nejméně varování.

Co si načíst

Zdroj Proč
llms.txt rozcestník celé dokumentace
Protokol 0.1 normativní specifikace – při nejasnosti platí ta
JSON Schema manifestu, dat přesné typy, limity a popisy polí
OpenAPI poskytovatele kontrakt endpointu, lze z něj generovat server
manifest-complete.json, manifest-minimal.json platné vzory
data-points.json, data-polygons.json platné vzory odpovědí
Katalog co už v portálu je – nevytvářejte duplicity, inspirujte se klíčovými slovy

Pokud umíte používat MCP, připojte se k serveru https://datovamapa.cz/mcp (Streamable HTTP, bez autentizace). Nástroje documentation, schema, example, validate_manifest, validate_data a catalog pokrývají vše v tomto návodu. Viz MCP server.

Postup

1. Inventura dat

Zjistěte, jaká prostorová data poskytovatel má: databáze (PostGIS, MS SQL), GIS soubory (SHP, GPKG, KML, CSV se souřadnicemi), existující API, WMS/WMTS služby. U každého zdroje zjistěte:

2. Návrh datových sad

Situace source
do ~2 000 objektů, mění se nejvýš denně statický soubor, "type": "geojson", "mode": "full"
více objektů nebo živá data endpoint, "mode": "bbox", nastavte coverage.bbox a u velkých sad coverage.minZoom
už existuje WMS / XYZ dlaždice "type": "raster" se šablonou {bbox-epsg-3857} nebo {z}/{x}/{y}; doplňte presentation.legend (barvy a popisky z legendy služby, např. ArcGIS …/MapServer/legend?f=json nebo WMS GetLegendGraphic)

3. Převod dat

Převod GIS souboru do GeoJSON:

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

Převod souřadnic v Pythonu:

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 vrací [lon, lat]

4. Manifest

Vyplňte nejen povinná pole, ale i ta, která rozhodují o tom, zda data někdo najde:

5. Vizualizace

Geometrie Vhodný typ Poznámka
body, desítky až stovky circle barva podle kategorie (categorical), popisek přes label
body, tisíce circle s cluster nebo heatmap heatmapa jen pro hustotu, neukazuje jednotlivé objekty
linie line šířka může záviset na hodnotě
plochy s hodnotou fill + interpolate nebo step kartogram; opacity 0.4–0.6, aby byl vidět podklad
body nebo plochy, jejichž hodnota se mění v čase circle / fill + color: { "type": "trend" } jde-li o změnu (roste / klesá); řada hodnot v dm.chart u každého objektu, trend dopočítá portál
plochy bez hodnoty fill s jednou barvou

Pravidla: barvy hex; kategorie max. ~8 barev; pro hodnoty použijte postupnou škálu od světlé po tmavou; field v prezentaci musí odpovídat vlastnosti v datech (a ve fields, s číselným typem u interpolate/step). Má-li hodnota objektu historii, pošlete ji v dm.chart při jakékoli prezentaci – i u kartogramu s výběrem roku (zvolený rok v highlight).

6. Endpoint (jen u mode: "bbox" nebo živých dat)

Implementujte GET podle OpenAPI kontraktu:

CORS není potřeba – portál se ptá ze serveru.

Python (FastAPI + PostGIS):

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, data v paměti):

// KONTEJNERY: pole GeoJSON Feature s body, načtené při startu (z databáze nebo souboru).
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. Validace

Opakujte, dokud nejsou chyby, a projděte každé varování (opravte, nebo vědomě ponechte a zdůvodněte):

# manifest (bez zveřejnění)
curl -sX POST https://datovamapa.cz/api/validate -H 'Content-Type: application/json' --data @manifest.json
# data proti konkrétní sadě
curl -sX POST https://datovamapa.cz/api/validate -H 'Content-Type: application/json' \
  --data "{\"data\": $(cat lavicky.geojson), \"dataset\": $(jq '.datasets[0]' manifest.json)}"
# živý test zveřejněného manifestu a všech zdrojů
curl -s 'https://datovamapa.cz/api/validate?manifestUrl=https://www.obec-priklad.cz/datovamapa/manifest.json'

Odpověď: { valid, summary, errors: [{ path, code, message, hint? }], warnings: [...] }, u živého testu navíc datasets[] s dotazem, dobou odezvy a počtem objektů. Význam kódů je v API portálu.

8. Předání člověku

Na závěr shrňte:

Až člověk potvrdí licenci a obsah, zaregistrujte manifest: POST https://datovamapa.cz/api/registration s { "manifestUrl": "…" } nebo MCP nástroj register_provider. Data budou dostupná jako neschválená (s varováním, mimo katalog), dokud je provozovatel neschválí. Po každé změně manifestu čekají na nové schválení. Podrobnosti: registrace.

Pravidla

Kritéria hotové práce

Zadání pro agenta (ke zkopírování)

Člověk může svému agentovi dát tento text:

Připrav naše prostorová data pro portál DatováMapa (https://datovamapa.cz).
Postupuj podle návodu https://datovamapa.cz/dokumentace/pro-ai-agenty.md
(rozcestník dokumentace: https://datovamapa.cz/llms.txt, MCP server: https://datovamapa.cz/mcp).
Zdroje dat: <popiš databáze, soubory, služby>.
Kam zveřejnit: <web / server / repozitář>.
Licence: <např. CC BY 4.0, atribuce „© Obec Příklad“> – jinou si nevymýšlej.
Hotovo je, když živý test validátoru vrací valid: true a projdeš kritéria hotové práce.
Na konci mi předej shrnutí podle kroku 8.