# geo-spatial.org — Romanian open geodata > The whole geo-spatial.org open-geodata platform for Romania, landed rather than linked: its ISO-19139 GeoNetwork catalogue, its GeoServer WFS service materialised one table per feature type — administrative boundaries from ANCPI, the 2021 population and housing census by county and ethnicity from INS, national grids, settlements and the community's own layers — its published GeoParquet downloads, and the index of the site that documents them. Every generated table carries the layer's own attributes with their own types, plus its geometry as WGS 84 (EPSG:4326) WKT and a computed bounding box, so a spatial question is a WHERE clause rather than a download. service_layers.table_name is the index of the generated tables. - Dataset id: `geo-spatial-ro` - Update cadence: weekly - Upstream source: https://geo-spatial.org - Tags: romania, geospatial, open-data, geonetwork, geoserver, wfs, geoparquet, administrative-boundaries, census, boundaries, ancpi, ins - Current version: ingest `01M56FTS050N1FFFP9TBXVP9PE`, snapshot 2026-10-18, generated 2026-10-18T03:10:37.061Z ## Licence and attribution - Licence: Creative Commons Attribution 4.0 International (`CC-BY-4.0`) - Licence text: https://creativecommons.org/licenses/by/4.0/ - Required attribution: Date: geo-spatial.org, CC BY 4.0 - Notes: The catalogue records themselves declare this licence: every published record in the geo-spatial.org GeoNetwork carries licenseObject = "Creative Commons Attribution 4.0 International (CC BY 4.0)", and catalog_records.licence republishes that value verbatim per record so a reuser can check it dataset by dataset rather than trusting this line. The website's own prose is CC BY-SA 4.0, which is why no page text is republished here — site_pages carries a page's title, meta description and URL, not its body. Several layers are DERIVED FROM UPSTREAM PUBLIC BODIES, each of which carries its own terms and should be credited alongside geo-spatial.org: the administrative-boundaries layers are processed from public data of the Agenția Națională de Cadastru și Publicitate Imobiliară (ANCPI); the recensamant layers are the results of the 2021 Recensământul Populației și Locuințelor published by the Institutul Național de Statistică (INS), some of it harmonised with Eurostat census definitions; the cfro layers derive from the land-parcel identification programme operated by APIA. This connector republishes vector ATTRIBUTES AND GEOMETRY only — it does not copy the publisher's raster tiles, GeoTIFFs, images, PDFs, KML/KMZ presentation files or the contents of its archives, all of which stay as catalogued references in download_files with the reason recorded in each row. robots.txt at services.geo-spatial.org carries comments only: no Disallow, and no content signal. Reproduce the attribution line verbatim anywhere you republish this data. ## Manifest - Start here for how this directory works: https://data.bunnytech.app/llms.txt - This dataset: https://data-directory.fsn1.your-objectstorage.com/public/geo-spatial-ro/manifest.json - All datasets: https://data-directory.fsn1.your-objectstorage.com/public/index.json - Human page: https://data.bunnytech.app/datasets/geo-spatial-ro The manifest is the contract: file URLs, row counts, column types, min/max statistics and example queries all live there. Re-read it to discover a new version. ## Fastest path — Parquet exports This dataset publishes 153 tables — too many to inline one export URL per table here. The exports exist, and they are as immutable and as sorted as any other dataset's; their URLs are listed under `tables[].files[].url` in `manifest.json`: https://data-directory.fsn1.your-objectstorage.com/public/geo-spatial-ro/manifest.json That file is large, so do not fetch it just to run a query. The DuckLake catalog below reads exactly the same data with one ATTACH, no manifest download and no file list. Example queries: -- What layers exist, and where did each one land: service_layers is the index of the generated data tables. Read it first — the table names are only known after an ingest. ```sql ATTACH IF NOT EXISTS 'ducklake:https://data-directory.fsn1.your-objectstorage.com/catalog/catalog.ducklake' AS "datadirectory" (READ_ONLY); SELECT type_name, table_name, backing, feature_count, skip_reason FROM datadirectory.geo_spatial_ro.service_layers WHERE snapshot_date = (SELECT max(snapshot_date) FROM datadirectory.geo_spatial_ro.service_layers) ORDER BY feature_count DESC NULLS LAST ``` -- Every county boundary as WKT, with its bounding box ```sql ATTACH IF NOT EXISTS 'ducklake:https://data-directory.fsn1.your-objectstorage.com/catalog/catalog.ducklake' AS "datadirectory" (READ_ONLY); SELECT name, geometry_type, bbox_west, bbox_south, bbox_east, bbox_north FROM datadirectory.geo_spatial_ro.ro_admin_county_simplified_polygon ORDER BY name ``` ## Live lake — DuckLake catalog with time travel Attach the published catalog read-only over plain https. This works in native DuckDB AND in duckdb-wasm in the browser — the reader catalog resolves its data files through public https URLs, so no credentials and no backend are involved. ```sql INSTALL ducklake; LOAD ducklake; ATTACH 'ducklake:https://data-directory.fsn1.your-objectstorage.com/catalog/geo-spatial-ro/catalog.ducklake' AS geo_spatial_ro (READ_ONLY); SELECT * FROM geo_spatial_ro.main.analfabestism_etnie_peste14_ani LIMIT 5; USE geo_spatial_ro; ``` - Latest catalog: https://data-directory.fsn1.your-objectstorage.com/catalog/geo-spatial-ro/catalog.ducklake - This exact version: https://data-directory.fsn1.your-objectstorage.com/catalog/geo-spatial-ro/v/01M56FTS050N1FFFP9TBXVP9PE/catalog.ducklake (sha256 696f9e65addb76a996c1de506d34bba92a26a43c479ef05fbcab091f1cfb1975) - Written by DuckDB v1.5.5 - Time travel: this ingest is snapshot 55 — e.g. `SELECT * FROM geo_spatial_ro.analfabestism_etnie_peste14_ani AT (VERSION => 55)` ## Wholesale — S3 access For bulk downloads, read the bucket prefix directly over S3 with httpfs: ```sql INSTALL httpfs; LOAD httpfs; CREATE SECRET hetzner ( TYPE s3, ENDPOINT 'fsn1.your-objectstorage.com', URL_STYLE 'path', KEY_ID '', SECRET '' ); SELECT * FROM read_parquet('s3://data-directory/public/geo-spatial-ro/v/01M56FTS050N1FFFP9TBXVP9PE/**/*.parquet'); ``` ## Schema This dataset publishes 153 tables. The full column-level schema is too large to inline here; it lives in full in `manifest.json` at https://data-directory.fsn1.your-objectstorage.com/public/geo-spatial-ro/manifest.json. A table's columns can be discovered live with DuckDB instead. Which name a table answers to depends on which catalog you attached — both routes, in full: ```sql -- Route 1: the unified catalog (see `/llms.txt`). Every dataset is a schema inside it. DESCRIBE datadirectory.geo_spatial_ro.; SELECT table_name, column_name, data_type FROM information_schema.columns WHERE table_schema = 'geo_spatial_ro'; ``` ```sql -- Route 2: this dataset's own catalog. Its tables live in schema `main` of the alias -- you attach it under — there is no `datadirectory` schema on this route. ATTACH 'ducklake:https://data-directory.fsn1.your-objectstorage.com/catalog/geo-spatial-ro/catalog.ducklake' AS geo_spatial_ro (READ_ONLY); DESCRIBE geo_spatial_ro.main.
; SELECT table_name, column_name, data_type FROM information_schema.columns WHERE table_catalog = 'geo_spatial_ro' AND table_schema = 'main'; ``` Tables (name — row count): - `analfabestism_etnie_peste14_ani` — 1,008 rows - `arie_naturala_de_interes_national` — 1 rows - `catalog_contacts` — 374 rows - `catalog_keywords` — 328 rows - `catalog_links` — 667 rows - `catalog_records` — 57 rows - `date_demografie` — 227.2K rows - `date_demografie_opt` — 227.2K rows - `detect_see_land_cover_use` — 4,073 rows - `dim_date_demografie` — 513 rows - `download_files` — 7,883 rows - `etnie_educatie` — 1,008 rows - `etnie_limba_materna` — 966 rows - `etnie_religie` — 1,008 rows - `etnie_uat` — 3,180 rows - `etnie1930_2021` — 336 rows - `etnie1930_2021_v2` — 5,301 rows - `geostat_grid_1k_pop_2014_sparse` — 70.2K rows - `grid_inspire_1km` — 246.9K rows - `grid_inspire_25km` — 452 rows - `grid_inspire_50km` — 128 rows - `grid_inspire_5km` — 10.1K rows - `index_austrian_200k` — 41 rows - `index_eharta_soviet_50k_existent` — 656 rows - `index_geologie_200k` — 50 rows - `index_pt_20k` — 1,618 rows - `index_ro_topo_gk_1000k` — 6 rows - `index_ro_topo_gk_100k` — 300 rows - `index_ro_topo_gk_10k` — 19.2K rows - `index_ro_topo_gk_200k` — 80 rows - `index_ro_topo_gk_25k` — 4,800 rows - `index_ro_topo_gk_2k` — 307.2K rows - `index_ro_topo_gk_500k` — 16 rows - `index_ro_topo_gk_50k` — 1,200 rows - `index_ro_topo_gk_5k` — 76.8K rows - `intern_index_soviet_100k` — 202 rows - `judete_centroid` — 43 rows - `locatii_picturi` — 63 rows - `m_metadata` — 26 rows - `microcentrale_autorizate` — 262 rows - `microhidrocentrale_avizate` — 10 rows - `mobilitate_populatie` — 16.1K rows - `natura_2000` — 1 rows - `nivel_educatie_limba_materna` — 966 rows - `persoane_peste15_ani_afectate_demasurile_pandemiei_de_coronavirus` — 812 rows - `persoane_resedinta_strainatate_dupa_etnie_si_perioada` — 8,999 rows - `persoane_resedinta_strainatate_dupa_tara_si_durata` — 9,375 rows - `persoane_resedinta_strainatate_dupa_tara_si_perioada` — 9,375 rows - `persoane_resedinta_strainatate_dupa_tara_si_varsta` — 9,400 rows - `persoane_schimbare_resedinta_judet` — 125 rows - `persoane_temporar_absente_dupa_judetul_de_destinatie` — 381 rows - `persoane_temporar_absente_dupa_perioada_si_motiv` — 1,875 rows - `persoane_temporar_absente_plecate_in_strainatate_dupa_nivel_educatie` — 3,750 rows - `persoane_temporar_absente_plecate_in_strainatate_dupa_tara_si_durata` — 8,250 rows - `persoane_temporar_absente_plecate_in_strainatate_dupa_tara_si_motiv` — 8,250 rows - `persoane_temporar_absente_plecate_in_tara_dupa_durata_si_motiv` — 1,875 rows - `persoane_temporar_absente_plecate_in_tara_sau_strainatate_dupa_varsta` — 1,125 rows - `persoane_temporar_absenteplecate_in_strainatate_dupa_tara_si_varsta` — 8,250 rows - `persoane_ultima_resedinta_anterioara_in_strainatate_dupa_tara` — 9,375 rows - `persoane_ultima_resedinta_anterioara_strainatate_dupa_etnie` — 3,750 rows - `persoane_ultima_resedinta_anterioara_strainatate_dupa_grupe_varsta` — 3,750 rows - `persoane_ultima_resedinta_anterioara_strainatate_dupa_tara` — 8,928 rows - `populatia_rezidenta_activa_inactiva` — 5,625 rows - `populatia_rezidenta_dupa_domiciliu_uat` — 3,180 rows - `populatia_rezidenta_dupa_locul_nasterii_judet_domiciliu` — 5,292 rows - `populatia_rezidenta_dupa_locul_nasterii_judete` — 375 rows - `populatia_rezidenta_dupa_locul_nasterii_uat` — 3,180 rows - `populatia_rezidenta_dupa_religie_judet` — 42 rows - `populatia_rezidenta_dupa_religie_si_nivel_educatie` — 1,008 rows - `populatia_rezidenta_dupa_religie_uat` — 3,180 rows - `populatia_rezidenta_dupa_starea_civila_domiciliu` — 630 rows - `populatia_rezidenta_grupe_varsta_judet` — 210 rows - `populatie_dupa_nivel_educatie_institutie_absolvita` — 2,016 rows - `populatie_dupa_nivel_educatie_institutie_absolvita_etnie` — 10.2K rows - `populatie_feminina_peste11_ani_ce_traieste_in_uniune_consensuala` — 630 rows - `populatie_feminina_peste16_ani_casatorita` — 1,176 rows - `populatie_judete_romania` — 336 rows - `populatie_ocupata_activitati_economice_nationale` — 126 rows - `populatie_ocupata_dupa_grupa_de_ocupatii` — 378 rows - `populatie_ocupata_dupa_localizare_geografica_loc_munca` — 378 rows - `populatie_ocupata_dupa_statut_profesional` — 378 rows - `populatie_peste2_ani_ce_urmeaza_institutie_invatamant` — 42 rows - `populatie_rezidenta_dupa_cetatenie` — 126 rows - `populatie_rezidenta_dupa_limba_materna` — 378 rows - `populatie_rezidenta_dupa_sex_judet` — 42 rows - `populatie_rezidenta_dupa_sex_uat` — 3,186 rows - `populatie_rezidenta_dupa_varsta_sex_medii_rezidenta_judet` — 209 rows - `populatie_rezidenta_dupa_varsta_uat` — 3,180 rows - `populatie_rezidenta_feminina_peste11_ani_nr_copii` — 2,226 rows - `populatie_rezidenta_stare_civila_grupe_varsta_judete` — 633 rows - `recensamant2021_grid_data` — 240.3K rows - `recensamant2021_grid_data_10` — 240.3K rows - `recensamant2021_grid_data_11` — 240.3K rows - `recensamant2021_grid_data_12` — 240.3K rows - `recensamant2021_grid_data_13` — 240.3K rows - `recensamant2021_grid_data_14` — 240.3K rows - `recensamant2021_grid_data_15` — 240.3K rows - `recensamant2021_grid_data_16` — 240.3K rows - `recensamant2021_grid_data_2` — 240.3K rows - `recensamant2021_grid_data_3` — 240.3K rows - `recensamant2021_grid_data_4` — 240.3K rows - `recensamant2021_grid_data_5` — 240.3K rows - `recensamant2021_grid_data_6` — 240.3K rows - `recensamant2021_grid_data_7` — 240.3K rows - `recensamant2021_grid_data_8` — 240.3K rows - `recensamant2021_grid_data_9` — 240.3K rows - `ro_admin_country_line` — 7 rows - `ro_admin_country_polygon` — 1 rows - `ro_admin_country_simplified_line` — 1 rows - `ro_admin_country_simplified_polygon` — 1 rows - `ro_admin_county_line` — 121 rows - `ro_admin_county_polygon` — 42 rows - `ro_admin_county_simplified_line` — 121 rows - `ro_admin_county_simplified_polygon` — 42 rows - `ro_admin_lau_bucharest_merged_line` — 9,635 rows - `ro_admin_lau_bucharest_merged_polygon` — 3,181 rows - `ro_admin_lau_line` — 9,644 rows - `ro_admin_lau_polygon` — 3,186 rows - `ro_admin_lau_simplified_bucharest_merged_line` — 9,635 rows - `ro_admin_lau_simplified_bucharest_merged_polygon` — 3,181 rows - `ro_admin_lau_simplified_line` — 9,644 rows - `ro_admin_lau_simplified_polygon` — 3,186 rows - `ro_admin_macroregion_line` — 9 rows - `ro_admin_macroregion_polygon` — 4 rows - `ro_admin_macroregion_simplified_line` — 9 rows - `ro_admin_macroregion_simplified_polygon` — 4 rows - `ro_admin_region_line` — 19 rows - `ro_admin_region_polygon` — 8 rows - `ro_admin_region_simplified_line` — 19 rows - `ro_admin_region_simplified_polygon` — 8 rows - `ro_blocuri_fizice_2021` — 1.3M rows - `ro_frontiera_poligon` — 1 rows - `ro_frontiera_polilinie` — 7 rows - `ro_geomorphometry_landforms_all` — 757 rows - `ro_grid_data_ancpi_40km` — 189 rows - `ro_judete_poligon` — 42 rows - `ro_judete_polilinie` — 121 rows - `ro_limite_unitati_relief` — 819 rows - `ro_localitati_punct` — 13.8K rows - `ro_settlements_point` — 13.8K rows - `ro_uat_poligon` — 3,186 rows - `ro_uat_polilinie` — 9,639 rows - `sectii_politie_bucuresti_poligon` — 28 rows - `service_layer_attributes` — 3,694 rows - `service_layers` — 292 rows - `sit_directiva_pasari` — 1 rows - `sit_ramsar` — 1 rows - `sit_rezervatia_biosferei_delta_dunarii` — 1 rows - `sit_unesco` — 1 rows - `site_pages` — 254 rows - `soluri200k` — 51.7K rows - `someri_dupa_etnie` — 375 rows - `varsta_medie_judet` — 42 rows ## Performance notes - There are no indexes in a lakehouse. The physical sort order plus Parquet row-group min/max statistics ARE the index. Predicates on the leading sort columns prune whole row groups; everything else is a full column scan. - `ILIKE '%needle%'` cannot prune: it decompresses that whole column. Prefer prefix predicates on the lowercased search companion columns where they exist. - Every file URL under `/v//` is immutable. Cache it as aggressively as you like. - Files are never rewritten in place — a new ingest writes a new version path. Re-read the manifest to pick up updates rather than polling the file URLs. - Pull only the columns you need. Parquet is columnar and the reader range-GETs what it reads. ## Do not - Do not scrape https://data.bunnytech.app HTML. Every number on those pages comes from the manifest above. - Do not hit the upstream source (https://geo-spatial.org) in bulk. This mirror exists so you do not have to. - Do not read DuckLake internal data files with a plain Parquet reader. They come with positional delete files, and ignoring those silently returns deleted rows. Use the ducklake extension, or use the published exports above. - Do not republish without the attribution line, and do not imply endorsement.