Skip to content

Repository files navigation

PyPI version GitHub Ask DeepWiki License: MIT Newsletter

openrndt

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-explorer inclusa in questo repo. I principi di design sono nella sezione Per agenti AI.

Stato: v1.0 — read-only.

Cos'è il RNDT

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.

Installazione

Da PyPI

uv tool install openrndt
# oppure, senza installazione persistente:
uvx openrndt --help

Da locale (per sviluppo o versioni non ancora pubblicate)

git 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 openrndt

Per sviluppo (modifiche con ricarica immediata)

git clone https://github.com/ondata/openrndt.git
cd openrndt
uv sync
uv run openrndt --help

Uso

# 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 discover

Il 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 5

Tutti 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).

Esempi di conversazione con un'AI

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ò eseguire openrndt da terminale.

«Mi serve l'uso del suolo dell'Emilia-Romagna da caricare in QGIS»

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 20

AI: 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=WMS

Scegli poi l'annata che ti interessa fra i layer offerti dal servizio.

«Voglio il catasto di un comune piemontese»

Tu: Mi serve il catasto urbano per un'analisi in Piemonte.

openrndt search --q "catasto" --num 10

AI: 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

«Cerco ortofoto da usare come base»

Tu: Mi servono delle ortofoto come sfondo per la mia mappa. Cosa c'è disponibile?

openrndt search --q "ortofoto" --num 50

AI: Diverse amministrazioni espongono ortofoto via WMS, pronte da usare come base in QGIS. Per esempio:

  • Regione Sardegnahttps://webgis.regione.sardegna.it/geoserverraster/ows?service=wms&version=1.3.0&request=GetCapabilities
  • Provincia di Lodihttp://sdi.provincia.lodi.it/arcgis/services/DBTL/dbtl_ortofoto_digitali/MapServer/WMSServer?request=GetCapabilities&service=WMS
  • Regione Piemontehttps://geomap.reteunitaria.piemonte.it/mapproxy/service?service=WMS&version=1.3.0&request=getCapabilities

«Il reticolo idrografico, ma vettoriale (per editing)»

Tu: Non voglio un'immagine: mi serve il reticolo idrografico come vettoriale, così posso interrogarlo e modificarlo.

openrndt search --q "reticolo idrografico" --num 50

AI: Per i vettoriali ti serve un WFS (in QGIS: Aggiungi layer WFS). Alcuni servizi disponibili:

  • ISPRAhttp://sdi.isprambiente.it/geoserver/hy/wfs?service=wfs&version=2.0.0&request=GetCapabilities
  • ARPA Venetohttp://gaia.arpa.veneto.it/geoserver/ows?service=WFS&version=1.0.0&request=GetCapabilities
  • Regione Basilicatahttp://rsdi.regione.basilicata.it/rbgeoserver2016/dbgt_0404/nd_idr/wfs?request=GetCapabilities&service=WFS&version=2.0.0

«Tutto quello che pubblica un certo ente»

Tu: Quanti e quali dataset ha pubblicato la Regione Lombardia?

openrndt search --q 'apiso_OrganizationName_txt:"Regione Lombardia"' \
  --sort "apiso_Modified_dt:desc" --num 10

AI: 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.

«Cosa copre la mia area di studio»

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 10

AI: 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.

«Solo dati con licenza aperta»

Tu: Mi servono dati sulle frane, ma solo open data che posso riusare liberamente.

openrndt search --q "frane AND isOpendata:*" --num 10

AI: 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?

«Devo scaricare i dati e citare la fonte in un articolo»

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.

Uso come libreria Python

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")

Per agenti AI

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 table per la lettura umana, --format csv per i risultati tabellari, --format compact (NDJSON, una riga per record) per scremare molti risultati a basso costo.
  • In modalità JSON, stdout contiene solo JSON. Errori e avvisi vanno su stderr: si può fare pipe diretta in jq.
  • Errori leggibili e self-contained: mai stack trace. Un errore di rete o HTTP produce un messaggio comprensibile su stderr ed exit code 1, non un traceback.
  • Exit code chiari. 0 successo, 1 errore (rete, HTTP, ID inesistente), 2 parametri non validi.
  • Niente formati ambigui. get <id> --format csv (dettaglio non tabellare) fallisce con un messaggio esplicito invece di restituire output vuoto.

La skill rndt-explorer — esplorazione guidata

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.

Riferimenti

Licenza

MIT.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages