MapaDanych.pl

Wersja do odczytu maszynowego: /dokumentacja/api.md

API portalu MapaDanych

Maszynowy interfejs portalu dla aplikacji i agentów AI: katalog danych, dane ze wszystkich źródeł w ujednoliconej postaci, zapytania o miejsce (co jest w punkcie i w okolicy, podsumowanie dla gminy), walidator i rejestracja dla dostawców oraz serwer MCP. Wszystko jest publiczne, bez uwierzytelniania, z CORS *. Formalny opis znajduje się w OpenAPI.

Przegląd

Metoda i ścieżka Przeznaczenie
GET /api/catalog wszyscy dostawcy i zbiory danych (JSON)
GET /api/data/{provider}/{dataset} dane zbioru jako GeoJSON, przez cache portalu
GET /api/places?query=… wyszukiwanie adresu, ulicy lub gminy → współrzędne
GET /api/nearby?point=… co jest w punkcie i w okolicy, z wybranych zbiorów
GET /api/summary/{provider}/{dataset} podsumowanie zbioru dla całego obszaru lub dla gminy
GET /api/validate?manifestUrl=… test dostawcy na żywo
POST /api/validate kontrola manifestu lub danych bez publikacji
POST /api/registration rejestracja dostawcy (dane czekają na zatwierdzenie)
POST /mcp serwer MCP (Streamable HTTP)
GET /llms.txt, /llms-full.txt spis treści i cała dokumentacja dla modeli językowych
GET /index.md, /zrodla.md, /dokumentacja/{slug}.md strony portalu w markdownie
GET /schema/0.1/manifest.json, /schema/0.1/data.json JSON Schema protokołu
GET /schema/0.1/provider-openapi.json kontrakt OpenAPI, który implementuje dostawca
GET /przyklady/{plik}.json poprawne przykładowe manifesty i odpowiedzi

Katalog

GET /api/catalog

{
  "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": "Indeks radonowy",
      "category": "risks",
      "categoryLabel": "Zagrożenia i ograniczenia",
      "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" }
    }
  ]
}

Katalog zawiera wyłącznie zatwierdzone dane. Zbiorów dostawców, którzy zarejestrowali się sami i nie zostali jeszcze zatwierdzeni, w nim nie ma (zob. Rejestracja).

Zbiory danych zawierają wszystkie pola z manifestu dostawcy (description, fields, params, coverage…) z wyjątkiem URL źródła – dane GeoJSON odczytuje się przez portal (links.data), kafelki rastrowe bezpośrednio ze źródła (source.tiles). Ta sama treść w postaci czytelnej dla ludzi i modeli: zrodla.md.

Dane

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

Parametr Kiedy Opis
bbox zbiory z source.mode = "bbox" (wymagany) minLon,minLat,maxLon,maxLat w WGS84; portal wyrównuje go do kafelków
zoom zbiory z source.mode = "bbox" (wymagany) poziom przybliżenia 0–24
cursor opcjonalnie kursor z dm.next
{param} według params zbioru wartości w formacie protokołu (a,b, od,do); niewypełnione otrzymują default

Odpowiedź to GeoJSON FeatureCollection. Dane z feature.dm dostawcy są przeniesione do properties z przedrostkiem __dm_ (__dm_title, __dm_description, __dm_url, __dm_color, __dm_chart). W zbiorach z color.type = "trend" portal dodaje __dm_trend (roste, stagnuje, klesá) obliczony z dm.chart. Metadane odpowiedzi:

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

Nagłówek X-DM-Cache: hit (z cache), miss (świeżo ze źródła), stale (źródło niedostępne, ostatnie znane dane – zob. dm.notice).

Błędy mają postać { "error": "komunikat", "code": "kod" }: 400 nieprawidłowe zapytanie, 404 nieznany zbiór, 502 błąd źródła.

Zbiory tylko do wyświetlania. W przypadku kilku zbiorów zarządzanych przez portal źródło nie ma udokumentowanej licencji na dalsze rozpowszechnianie. Portal rysuje je na własnej mapie, ale danych dalej nie udostępnia: w katalogu mają puste links.data, a w links.source adres oryginalnej usługi dostawcy. Zapytanie spoza mapy portalu otrzyma 303 z nagłówkiem Location wskazującym tę usługę i treścią { "error": "…", "code": "display_only", "source": "…" }. Tak samo odpowiada narzędzie MCP fetch_data.

Szczegóły obiektu. GET /api/data/{dostawca}/{zbiór}/detail?id={id} zwraca FeatureDetail (protokół) dla zbiorów, które mają w manifeście detail. Id obiektu jest w zapytaniu (nie w ścieżce), bo może zawierać % i |. Zasady jak przy danych: zbiór tylko do wyświetlania daje szczegóły tylko mapie portalu (inaczej 303, Cache-Control: private), pozostałe są buforowane według ttl odpowiedzi. Nieznane id zwraca 404 (unknown_detail), zbiór bez szczegółów 404 (no_detail).

Miejsce i okolica

Zapytania dla asystentów AI i aplikacji, które odpowiadają na pytania o konkretne miejsce. Zwracają wartości opisane w sposób czytelny dla ludzi (etykiety i jednostki według fields zbioru) bez geometrii, z atrybucją i linkiem do mapy. Poradnik dla użytkowników asystentów: Dane dla asystentów AI.

Wyszukiwanie miejsca

GET /api/places?query=Floriańska 1, Kraków (opcjonalnie max, domyślnie 5, maksymalnie 10)

Wyszukuje w rejestrze adresów adresy, ulice, gminy, części gmin i inne elementy terytorialne. Podaj tylko adres lub nazwę; doprecyzowań takich jak powiat czy „koło Zakopanego” usługa nie rozumie. municipality to gmina, w której miejsce leży (name, district, region i kod TERYT gminy code) – dla niej podsumowanie zwraca dane za całą gminę. Dla miejsc poza miastami powyżej 10 000 mieszkańców jest dodatkowo near – najbliższe takie miasto i odległość w km; według obu pól rozróżnia się miejsca o tej samej nazwie.

{
  "query": "Floriańska 1, Kraków",
  "count": 1,
  "places": [{ "name": "Floriańska 1, 31-019 Kraków", "type": "adres", "point": [19.9393, 50.0626], "municipality": { "slug": "krakow", "code": "1261011", "name": "Kraków", "district": "Kraków", "region": "Województwo małopolskie" } }],
  "attribution": "© źródło rejestru adresów"
}

Co jest w punkcie i w okolicy

GET /api/nearby

Parametr Opis
point lon,lat w WGS84
place zamiast point: adres lub nazwa, używany jest pierwszy wynik wyszukiwania miejsca
radius promień okolicy w metrach, domyślnie 500, maksymalnie 20 000
datasets klucze provider/dataset rozdzielone przecinkami, maksymalnie 12
purpose zamiast datasets: zbiory o tym przeznaczeniu (useCases), które obejmują punkt
search zamiast datasets: zbiory według zgodności z tekstem, np. zagrożenia dla budowy
max maksymalnie obiektów na zbiór, domyślnie 5, maksymalnie 50
{provider}/{dataset}.{param} parametr zbioru, tak samo jak w linku do mapy

Jeden z parametrów datasets, purpose, search jest wymagany. Automatyczny wybór bierze tylko zbiory, które potrafią odpowiedzieć dla punktu: najpierw zagrożenia i ograniczenia, mapy podkładowe na końcu. Zbiory ponad limit zwraca w skipped.

status Znaczenie
ok zapytanie się powiodło; puste hits = w okolicy / w punkcie nic nie ma (np. poza obszarem zagrożenia powodziowego)
unavailable zbiór nie udostępnia wartości w punkcie (kafelki są tylko obrazem) lub punkt leży poza zasięgiem
error źródło zawiodło (error, code)
{
  "place": { "name": "Floriańska 1, 31-019 Kraków", "type": "adres", "point": [19.9393, 50.0626] },
  "point": [19.9393, 50.0626],
  "radius": 500,
  "generated": "2026-10-06T16:00:00.000Z",
  "results": [
    {
      "dataset": "cgs/radon",
      "title": "Indeks radonowy",
      "provider": "Česká geologická služba",
      "attribution": "© Česká geologická služba",
      "status": "ok",
      "hits": [{ "title": "Indeks radonowy", "distance": 0, "values": [{ "label": "radonovériziko", "value": "přechodný" }, { "label": "stupeňradonovéhoindexu", "value": "2" }] }]
    },
    {
      "dataset": "npu/kulturni-pamatky",
      "title": "Zabytki kultury",
      "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": "fabryka Breitfeld-Daněk",
          "distance": 91,
          "values": [{ "label": "Numer rejestru ÚSKP", "value": "105958" }, { "label": "Stan ochrony", "value": "pod ochroną konserwatorską" }],
          "url": "https://pamatkovykatalog.cz/x-14624751"
        }
      ]
    }
  ],
  "map": "https://mapadanych.pl/?d=cgs/radon&d=npu/kulturni-pamatky#15/50.0626/19.9393"
}

Podsumowanie

GET /api/summary/{provider}/{dataset}?municipality=Kraków (pozostałe parametry zapytania są parametrami zbioru)

Podsumowanie zbioru GeoJSON dla całego obszaru albo, z municipality, tylko dla gminy – dowolnej gminy w Polsce: count, categories (liczby według kategorii koloru), rankings (najwyższe i najniższe wartości), a w przypadku kartogramu own – wartości powierzchni, w której gmina leży. Są to te same liczby, które pokazuje strona zbioru. Zbiory wczytywane tylko przy dużym przybliżeniu mają podsumowanie wyłącznie dla gminy. Zbiory rastrowe podsumowania nie mają.

municipality to nazwa („Kraków”), nazwa z powiatem lub województwem („Michałowice (powiat krakowski)”), kod TERYT gminy („1261011”, zwraca go wyszukiwanie miejsca w municipality.code) lub adres jej strony przeglądowej („malopolskie/michalowice-krakowski”). Sama nazwa, którą nosi kilka gmin, kończy się błędem ambiguous_place z listą tych gmin, ich powiatów i kodów.

Walidator

Narzędzie dla dostawców i ich agentów AI. Zawsze zwraca HTTP 200 i raport:

{
  "valid": false,
  "summary": "Manifest nie jest poprawny: 1 błąd, 2 zalecenia.",
  "errors": [{ "path": "datasets[0].source.tiles[0]", "code": "raster_without_template", "message": "Szablon kafelków nie zawiera {z}/{x}/{y} ani {bbox-epsg-3857}." }],
  "warnings": [{ "path": "datasets[0].keywords", "code": "missing_keywords", "message": "Zbiór nie ma słów kluczowych.", "hint": "Dodaj 5–15 słów…" }]
}

Rejestracja

POST /api/registration z treścią { "manifestUrl": "https://…" }. Portal sprawdza manifest testem na żywo (tak jak walidator). Jeśli test przejdzie, rejestruje dostawcę wśród niezatwierdzonych danych:

{
  "registered": true,
  "status": "pending_review",
  "message": "Zarejestrowano. …",
  "provider": { "id": "gmina-przyklad", "name": "Gmina Przykład" },
  "links": { "review": "/niezatwierdzone-dane#gmina-przyklad", "datasets": ["/mapa/gmina-przyklad/lawki"] },
  "check": { "summary": "Dostawca jest poprawny bez zastrzeżeń.", "warnings": [] }
}
HTTP code Znaczenie
201 – zarejestrowano, czeka na zatwierdzenie
200 – już zarejestrowano; status to pending_review lub approved
400 invalid_input, invalid_url brak manifestUrl lub jest nieprawidłowy
403 rejected operator odrzucił rejestrację
409 id_taken, url_registered provider.id już jest w portalu / URL jest zarejestrowany pod innym id
422 manifest_rejected test na żywo nie przeszedł; raport jest w check
429 too_many_requests, queue_full więcej niż 5 prób na minutę z jednego adresu / na zatwierdzenie czeka ponad 100 dostawców
503 registration_unavailable rejestracja obecnie nie działa

Serwer MCP

Endpoint https://mapadanych.pl/mcp, transport Streamable HTTP (bezstanowy, odpowiedzi JSON), bez uwierzytelniania.

Narzędzie Wejście Wyjście
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 poprawny przykładowy JSON
validate_manifest manifest (obiekt) lub manifestUrl (test na żywo) raport walidatora
validate_data data, opcjonalnie dataset raport walidatora
register_provider manifestUrl wynik rejestracji
catalog opcjonalnie search (dowolny tekst), point ([lon, lat]) zbiory danych w portalu, uporządkowane według zgodności; pointQuery = zbiór odpowie na nearby
find_place query, maxResults jak wyszukiwanie miejsca
nearby point lub place; datasets, purpose lub search; radius, maxFeatures, params ({ "provider/dataset": { "param": "wartość" } }) jak co jest w punkcie i w okolicy
summary dataset, opcjonalnie municipality, params jak podsumowanie
fetch_data dataset (provider/dataset), bbox lub municipality, zoom, params, maxFeatures GeoJSON (skrócony do maxFeatures)

Połączenie:

claude mcp add --transport http datovamapa https://mapadanych.pl/mcp
{ "mcpServers": { "datovamapa": { "type": "http", "url": "https://mapadanych.pl/mcp" } } }

Link do mapy

https://mapadanych.pl/?d={provider}/{dataset}&d=…&{provider}/{dataset}.{param}={wartość}#{zoom}/{lat}/{lon}

Każdy zbiór ma też własną stronę z mapą i opisem: https://mapadanych.pl/mapa/{provider}/{dataset}, ogólnokrajowe zbiory GeoJSON także dla gmin powyżej 10 000 mieszkańców: https://mapadanych.pl/mapa/{provider}/{dataset}/{gmina} (np. /mapa/chmu/kvalita-ovzdusi/ostrava). Link do strony zbioru jest w katalogu w links.map. Na stronie zbioru (i mapy zestawionej /mapy/{slug}) do ?d=… zapisuje się tylko różnicę względem domyślnego wyboru: bez d obowiązują zbiory strony, d wymienia cały wybór (?d= = nic nie jest włączone), a parametr podaje się tylko wtedy, gdy różni się od domyślnego.

Przykład – wypadki drogowe w Brnie łącznie za lata 2019–2023: /?d=brno/dopravni-nehody&brno/dopravni-nehody.obdobi=2019,2023#13/49.195/16.608

Kody ustaleń

Stabilne kody błędów (errors) i zaleceń (warnings) walidatora i proxy.

Manifest

Kod Poziom Znaczenie
schema_* błąd naruszenie JSON Schema (schema_invalid_type, schema_too_small, schema_invalid_format, schema_invalid_value, schema_custom…), path wskazuje miejsce
unsupported_version błąd inna wersja główna protokołu
raster_without_template błąd URL kafelków bez {z}/{x}/{y} i bez {bbox-epsg-3857}
geojson_with_raster_presentation błąd źródło GeoJSON z presentation.type: "raster"
param_without_options błąd enum / multi-enum bez options
invalid_default błąd default parametru nie odpowiada typowi lub opcjom
time_param_missing błąd temporal.param wskazuje parametr, którego nie ma w params
time_param_type błąd parametr czasowy nie jest typu range ani date-range
time_param_no_range zalecenie parametr czasowy typu range nie ma min i max
live_interval_below_ttl zalecenie live.interval jest krótszy niż cache.ttl, mapa pytałaby częściej, niż zmieniają się dane
unknown_presentation_type zalecenie portal nie zna typu, rysuje auto
raster_without_raster_presentation zalecenie raster jest zawsze rysowany jako raster
missing_description, missing_keywords, missing_use_cases zalecenie zbiór trudniej znajdą ludzie i asystent
missing_category, unknown_category zalecenie zbiór trafi do kategorii „Inne”
missing_field zalecenie szczegóły obiektu pokażą surowe nazwy właściwości
detail_url_without_id błąd szablon detail.url nie zawiera {id}
detail_url_not_https błąd szablon detail.url nie jest https ani adresem względnym
detail_without_primary_field zalecenie zbiór ze szczegółami nie ma właściwości z primary: true (tytuł okna, zanim wczytają się szczegóły)
detail_highlight_too_large zalecenie highlight w szczegółach ma ponad 200 kB
transit_missing_live błąd zbiór z profilem transit_vehicles nie ma live
transit_not_circle błąd zbiór z profilem transit_vehicles nie ma prezentacji circle
transit_missing_properties błąd pojazd zbioru z profilem transit_vehicles nie ma dm.transit
transit_not_point błąd pojazd zbioru z profilem transit_vehicles nie jest punktem
field_not_described, field_not_number zalecenie prezentacja odwołuje się do właściwości spoza fields / o nieliczbowym typie
bbox_unbounded zalecenie zbiór bbox bez coverage.minZoom i maxFeatures
missing_coverage zalecenie zbiór bbox bez coverage.bbox
missing_license, missing_website zalecenie brak licencji / strony internetowej dostawcy

Dane

Kod Poziom Znaczenie
coordinates_out_of_range błąd współrzędne poza WGS84 (zwykle nieprzeliczony PUWG 1992, EPSG:2180)
unclosed_polygon błąd pierścień wielokąta nie jest zamknięty
too_many_features zalecenie więcej obiektów niż limit / 5 000
missing_time_series zalecenie zbiór ma temporal.param, odpowiedź nie zawiera dm.timeline ani dm.chart
missing_trend_chart zalecenie zbiór koloruje według wartości liczbowej i wybiera okres parametrem, ale obiekty nie zawierają dm.chart
trend_without_chart zalecenie zbiór jest kolorowany według trendu, niektóre obiekty nie mają dm.chart (pozostaną szare)
swapped_coordinates zalecenie współrzędne prawdopodobnie w kolejności [lat, lon]
outside_coverage zalecenie większość obiektów poza coverage.bbox
geometry_presentation_mismatch zalecenie np. powierzchnie przy circle
field_missing_in_data, missing_presentation_property zalecenie brak w danych właściwości z manifestu
missing_id zalecenie obiekty bez id
empty_geometry zalecenie obiekty z geometry: null są pomijane

Test na żywo i proxy

Kod Znaczenie
invalid_url, https_required nieprawidłowy URL / źródło nie działa na HTTPS
source_unreachable, timeout, http_error źródło nie odpowiada, nie zdążyło w 10 s, zwróciło błąd HTTP
invalid_json, empty_body, response_too_large odpowiedź nie jest JSON-em / jest pusta / ma ponad 15 MB
invalid_gtfs_rt źródło GTFS Realtime (protobuf) zwróciło uszkodzone dane
invalid_manifest, id_mismatch manifest zarejestrowanego dostawcy nie przeszedł kontroli / ma inne provider.id
registration_unavailable, too_many_requests, queue_full, manifest_rejected, id_taken, url_registered, rejected błędy rejestracji
data_schema_mismatch dane ze źródła nie odpowiadają schematowi
invalid_id, no_detail, unknown_detail szczegóły obiektu: brak id / zbiór nie ma szczegółów / obiekt o tym id nie istnieje (404)
detail_schema_mismatch szczegóły ze źródła nie odpowiadają schematowi FeatureDetail
empty_response, slow_response zapytanie testowe zwróciło 0 obiektów / trwało ponad 3 s
tile_http_error, tile_not_image, tile_unreachable testowy kafelek rastrowy zawiódł
data_not_ready portal nie ma jeszcze wstępnie przetworzonych danych zbioru (przygotowuje je węzeł danych), spróbuj później
source_error inny błąd w komunikacji ze źródłem (szczegóły w message)
invalid_query, unknown_dataset, raster_dataset, invalid_input, internal_error błędy zapytania do portalu
display_only portal tylko wyświetla zbiór, dane udostępnia oryginalna usługa (source)
missing_place, unknown_place zapytanie o miejsce bez punktu i bez miejsca / nie udało się znaleźć miejsca (adresu, gminy)
geocoding_unavailable wyszukiwania adresów i miejsc w danym kraju portal jeszcze nie ma (HTTP 501)
ambiguous_place nazwę gminy nosi kilka gmin – komunikat wymienia je z powiatem i kodem
missing_dataset_selection zapytanie o okolicę bez datasets, purpose i bez search
summary_requires_place zbiór można wczytać tylko po przybliżeniu, nie ma podsumowania dla całego obszaru – podaj gminę
unknown_schema, unknown_example nieistniejący schemat / przykład (odpowiedź zawiera listę available)