Nota: strumento giovane — aiutaci a migliorarlo aprendo issue o condividendo feedback.
CLI Python e libreria per accedere al Repertorio Nazionale dei Dati Territoriali (RNDT) — pensata per essere orchestrata da un'AI.
Il modo giusto di trovare dati territoriali con l'AI. I modelli linguistici capiscono bene le domande, ma inventano nomi di dataset e URL di servizi WMS/WFS che non esistono. Il pattern corretto è usare l'AI per comporre interrogazioni al catalogo ufficiale, non per generare i riferimenti. openrndt è il layer di esecuzione di quel pattern: l'AI decide cosa cercare, openrndt interroga il RNDT e restituisce metadati e URL reali, verificabili.
Al meglio con un'AI. openrndt funziona benissimo da solo, ma dà il massimo se guidato da un agente AI: la CLI è progettata per essere composta, interrogata e orchestrata passo passo. Per un'esperienza guidata — scoperta delle codelist, ricerca con filtri progressivi, dettaglio del metadato, risorse scaricabili — abbinala alla Agent Skill
rndt-explorerinclusa in questo repo. I principi di design sono nella sezione Per agenti AI.
Stato: v1.0 — read-only.
Il Repertorio Nazionale dei Dati Territoriali è il catalogo ufficiale italiano dei metadati geografici (ISO 19115/19139). Espone REST API per cercare e scaricare i metadati.
uv tool install openrndt
# oppure, senza installazione persistente:
uvx openrndt --helpgit clone https://github.com/ondata/openrndt.git
cd openrndt
# CLI globale: venv isolato, eseguibile in PATH
uv tool install .
# Aggiornamento dopo modifiche al codice
uv tool install --reinstall .
# Disinstallazione
uv tool uninstall openrndtgit clone https://github.com/ondata/openrndt.git
cd openrndt
uv sync
uv run openrndt --help# Ricerca testuale
openrndt search --q "catasto" --num 5
# Filtro per bounding box (Piemonte sud)
openrndt search --q "cartografia" --bbox 7,44,8,45 --num 10
# Per categoria tematica ISO 19115
openrndt search --data-category planningCadastre --num 5
# Singolo metadato
openrndt get age:D_E973_MARSAGLIA
# XML ISO 19139 grezzo
openrndt get age:D_E973_MARSAGLIA --xml > meta.xml
# Codelist disponibili (no rete)
openrndt discoverIl timeout HTTP per singolo tentativo è configurabile con --timeout (default 30s);
con i retry su timeout/5xx (3 tentativi) il caso peggiore è ~3x questo valore:
openrndt --timeout 5 search --q "catasto" --num 5Tutti i comandi accettano --format json (default), --format table, --format csv.
Per search c'è anche --format compact: una riga NDJSON per record con i soli
campi ad alto segnale (id, title, org, type, category, updated,
resources), pensata per agenti AI e pipe a basso consumo di token.
openrndt --format compact search --q "catasto" --num 3
# {"id":"…","title":"…","org":"Comune di Torino","type":"service","category":null,"updated":"…","resources":["WMS"]}Se resources è [] il record non linka servizi fruibili: recupera il
dettaglio con get <id> e guarda _source.links_s (spesso il download è
dietro un portale dell'ente, non un link diretto).
openrndt è pensato per essere pilotato da un assistente AI. Non devi imparare la sintassi: descrivi a parole quello che ti serve e l'AI compone i comandi, legge i risultati e ti restituisce ciò che conta — di solito un URL WMS/WFS da incollare in QGIS o un dato da scaricare. Tutti gli esempi qui sotto usano risposte reali del catalogo RNDT.
Per provarli serve un assistente (es. Claude) a cui è stata installata la skill
skills/rndt-explorer/o che può eseguireopenrndtda terminale.
Tu: Sto lavorando su un progetto QGIS in Emilia-Romagna. Mi trovi un servizio con l'uso del suolo regionale, così lo aggiungo come layer?
L'AI cerca i servizi pubblicati sul tema:
openrndt search --q "uso del suolo WMS" --num 20AI: Trovato. La Regione Emilia-Romagna pubblica un WMS Uso del Suolo che copre più annate (2020, 2017, 2014, 2008, 2003, 1994, 1976) più l'uso storico dal 1853. In QGIS aggiungi un nuovo layer WMS/WMTS con questo URL:
http://servizigis.regione.emilia-romagna.it/wms/uso_del_suolo?request=GetCapabilities&service=WMSScegli poi l'annata che ti interessa fra i layer offerti dal servizio.
Tu: Mi serve il catasto urbano per un'analisi in Piemonte.
openrndt search --q "catasto" --num 10AI: C'è il Catasto Urbano 1:1500 come geo-servizio WMS della Regione Piemonte. URL per QGIS:
https://geomap.reteunitaria.piemonte.it/ws/siccms/coto-01/wmsg01/wms_sicc17bis_catasto_urbano?service=WMS&version=1.1.1&request=getCapabilities
Tu: Mi servono delle ortofoto come sfondo per la mia mappa. Cosa c'è disponibile?
openrndt search --q "ortofoto" --num 50AI: Diverse amministrazioni espongono ortofoto via WMS, pronte da usare come base in QGIS. Per esempio:
- Regione Sardegna —
https://webgis.regione.sardegna.it/geoserverraster/ows?service=wms&version=1.3.0&request=GetCapabilities- Provincia di Lodi —
http://sdi.provincia.lodi.it/arcgis/services/DBTL/dbtl_ortofoto_digitali/MapServer/WMSServer?request=GetCapabilities&service=WMS- Regione Piemonte —
https://geomap.reteunitaria.piemonte.it/mapproxy/service?service=WMS&version=1.3.0&request=getCapabilities
Tu: Non voglio un'immagine: mi serve il reticolo idrografico come vettoriale, così posso interrogarlo e modificarlo.
openrndt search --q "reticolo idrografico" --num 50AI: Per i vettoriali ti serve un WFS (in QGIS: Aggiungi layer WFS). Alcuni servizi disponibili:
- ISPRA —
http://sdi.isprambiente.it/geoserver/hy/wfs?service=wfs&version=2.0.0&request=GetCapabilities- ARPA Veneto —
http://gaia.arpa.veneto.it/geoserver/ows?service=WFS&version=1.0.0&request=GetCapabilities- Regione Basilicata —
http://rsdi.regione.basilicata.it/rbgeoserver2016/dbgt_0404/nd_idr/wfs?request=GetCapabilities&service=WFS&version=2.0.0
Tu: Quanti e quali dataset ha pubblicato la Regione Lombardia?
openrndt search --q 'apiso_OrganizationName_txt:"Regione Lombardia"' \
--sort "apiso_Modified_dt:desc" --num 10AI: La Regione Lombardia ha 430 dataset nel RNDT. Ecco i 10 aggiornati più di recente… (l'AI elenca titoli e date). Posso filtrarli per tema — uso del suolo, idrografia, trasporti — o mostrarti solo quelli con un servizio WMS/WFS.
Tu: Sto studiando l'area attorno a Bologna. Quali dataset la coprono?
openrndt search --q "edificato" --bbox "11.2,44.4,11.5,44.6" --num 10AI: Nel riquadro che copre l'area bolognese ci sono 40 dataset che la intersecano: il Database Topografico Regionale (edifici, unità volumetriche, falde) e anche cartografie storiche (Ducato di Modena 1821, territorio ferrarese 1814) disponibili come WMS. Nota: il filtro è per sovrapposizione al riquadro, quindi include dataset a copertura regionale che toccano l'area.
Tu: Mi servono dati sulle frane, ma solo open data che posso riusare liberamente.
openrndt search --q "frane AND isOpendata:*" --num 10AI: Ci sono 259 dataset open data sulle frane — dall'inventario IFFI della Regione Toscana ai rilievi con drone dell'emergenza alluvione 2023 in Emilia-Romagna. Te li elenco con la licenza di ciascuno?
Tu: Sto scrivendo un articolo sul rischio alluvioni. Mi servono i dati, la licenza d'uso e come citare la fonte.
L'AI cerca fra gli open data e recupera licenza ed ente dal dettaglio:
openrndt --format compact search --q "alluvioni AND isOpendata:*" --num 30
openrndt search --id "ispra_rm:01IdroHazard_DT" \
| jq -r '.results[0].links[] | select(.dctype != null) | "\(.dctype)\t\(.href)"'
openrndt get "ispra_rm:01IdroHazard_DT" \
| jq '{licenza: ._source.isOpendata, ente: ._source.EnteResponsabile_s}'AI: ISPRA pubblica Popolazione a rischio alluvioni con licenza CC-BY-4.0: puoi riusarlo citando la fonte (es. "Fonte: ISPRA — Popolazione a rischio alluvioni, CC-BY 4.0"). I dati sono esposti come WFS: te li scarico in GeoPackage con
ogr2ogr, pronti per QGIS o per un'analisi tabellare.
from openrndt import search, get_item, get_item_xml, ItemNotFoundError
# Ricerca
results = search(q="catasto", num=5)
for r in results["results"]:
print(r["id"], r["title"])
# Filtro per categoria e bbox
results = search(data_category="planningCadastre", bbox="7,44,8,45", num=10)
# Dettaglio singolo metadato
item = get_item("age:D_E973_MARSAGLIA")
print(item["_source"]["title"])
# XML ISO 19139
xml = get_item_xml("age:D_E973_MARSAGLIA")
# Gestione ID inesistente
try:
item = get_item("id_inesistente")
except ItemNotFoundError:
print("metadato non trovato")Le funzioni propagano le eccezioni httpx: httpx.HTTPStatusError per le
risposte 4xx/5xx e httpx.ConnectError / httpx.TimeoutException per i
problemi di rete. I retry interni coprono i timeout e i 5xx (3 tentativi),
mentre gli errori di connessione/DNS (ConnectError) vengono propagati subito.
Tutte derivano da httpx.HTTPError, comodo per catturarle insieme:
import httpx
from openrndt import search
try:
results = search(q="catasto")
except httpx.HTTPError as exc:
print(f"richiesta fallita: {exc}")Il base URL è configurabile via variabile d'ambiente o parametro:
from openrndt.config import set_base_url
set_base_url("https://mio-mirror.example.com/RNDT")L'utente primario di questa CLI è un agente che legge stdout e compone i comandi
passo passo. Da qui i principi di design (sul modello di
opensdmx):
- Output strutturato, mai oggetti Python. Default JSON su
stdout;--format tableper la lettura umana,--format csvper i risultati tabellari,--format compact(NDJSON, una riga per record) per scremare molti risultati a basso costo. - In modalità JSON,
stdoutcontiene solo JSON. Errori e avvisi vanno sustderr: si può fare pipe diretta injq. - Errori leggibili e self-contained: mai stack trace. Un errore di rete o HTTP
produce un messaggio comprensibile su
stderred exit code1, non un traceback. - Exit code chiari.
0successo,1errore (rete, HTTP, ID inesistente),2parametri non validi. - Niente formati ambigui.
get <id> --format csv(dettaglio non tabellare) fallisce con un messaggio esplicito invece di restituire output vuoto.
Il repo include una Agent Skill per Claude Code:
skills/rndt-explorer/. Guida l'agente
attraverso 4 fasi: scoperta delle codelist (offline), ricerca con filtri
progressivi, lettura del dettaglio, individuazione delle risorse scaricabili
(WMS, WFS, download diretto). Include workflow pronti e verificati per casi
d'uso reali — dall'operatore GIS che vuole un layer per QGIS al data journalist
che deve scaricare i dati, verificarne la licenza e citare la fonte.
Installazione (dopo aver installato la CLI):
git clone https://github.com/ondata/openrndt.git
mkdir -p ~/.claude/skills
cp -r openrndt/skills/rndt-explorer ~/.claude/skills/Da quel momento Claude Code attiva la skill da solo quando chiedi dati territoriali italiani — «mi serve il catasto della mia zona», «trova un WMS con le ortofoto della Sardegna» — senza che tu debba nominarla.
- Pagina ufficiale REST API: https://geodati.gov.it/geoportale/eng/strumenti-en/rest-api
- Spec completa (sito di test Esri Geoportal Server, non produzione): https://gpt.geocloud.com/geoportal3/api/gpt_api.json
- Documentazione raccolta nella cartella
ref/.
MIT.