# VIDA Open Buildings: Romania > The footprint of every building in Romania, from a global layer that merges three sources: Google's Open Buildings V3 (detected from satellite imagery), Microsoft's GlobalMLBuildingFootprints (also imagery-detected) and OpenStreetMap (drawn by contributors). VIDA deduplicates and merges the three into one 2.7-billion-footprint global layer published on Source Cooperative; this dataset is that layer's Romanian slice, verified directly: 12,655,928 footprints, of which 12,491,968 (98.71%) are Microsoft-sourced, 163,960 (1.30%) are OpenStreetMap-sourced, and 0 are Google-sourced — Romania was not covered by Google's Open Buildings detection run. Every row carries its exact source (bf_source), because the three upstream sources carry different licences: OpenStreetMap is ODbL with a share-alike obligation, Microsoft is CDLA Permissive 2.0, and Google is CC BY 4.0. VIDA republishes the merged layer under a single licence, ODbL v1.0 — the strictest of the three — and this dataset does the same. The source has no stable per-building id; geometry is published as WKT polygons in WGS 84. - Dataset id: `vida-buildings-ro` - Update cadence: monthly - Upstream source: https://source.coop/vida/google-microsoft-osm-open-buildings - Tags: buildings, geospatial, openstreetmap, footprints, infrastructure, gis - Current version: ingest `01M1NQT7YTFY5YJ067PWBKZP89`, snapshot 2026-09-04, generated 2026-09-04T08:16:02.162Z ## Licence and attribution - Licence: Open Data Commons Open Database License v1.0 (`ODbL-1.0`) - Licence text: https://source.coop/vida/google-microsoft-osm-open-buildings - Required attribution: Building footprints © VIDA (google-microsoft-osm-open-buildings dataset), merging Google Open Buildings V3 (CC BY 4.0), Microsoft GlobalMLBuildingFootprints (CDLA Permissive 2.0) and © OpenStreetMap contributors (ODbL) — Open Data Commons Open Database License (ODbL) v1.0. - Notes: VIDA's own "Dataset Licenses" statement, read directly on the dataset's Source Cooperative page (https://source.coop/vida/google-microsoft-osm-open-buildings) and in the bucket's own README.md, says plainly: "The data is shared under the Open Data Commons Open Database License (ODbL) v1.0 license." That is the licence this connector republishes under, in full. IMPORTANT CONTEXT for a reuser. (1) This is a MERGE of three differently-licensed sources, each still identifiable per row via bf_source: OpenStreetMap (https://www.openstreetmap.org/copyright) is ODbL-1.0, which requires attribution and "share-alike" — a database produced from it must itself be offered under ODbL or a compatible licence; Microsoft's GlobalMLBuildingFootprints (https://github.com/microsoft/GlobalMLBuildingFootprints) is CDLA Permissive 2.0, which permits redistribution and modification with attribution and no share-alike obligation; Google's Open Buildings V3 (https://sites.research.google/open-buildings/) is CC BY 4.0, attribution required, no share-alike. VIDA's choice to publish the WHOLE merged product under ODbL v1.0 — the strictest of the three — is the safe, conservative position for a combined database that includes ODbL-licensed OSM data, and this dataset follows VIDA's own published position rather than trying to relicense a subset. (2) Romania's current extract carries no Google-sourced rows (bf_source is never "google" here), so in practice every row in this table today is Microsoft- (CDLA Permissive 2.0) or OSM-sourced (ODbL). A reuser who specifically needs a licence more permissive than ODbL can filter to bf_source <> 'osm' and rely on CDLA Permissive 2.0 for what remains — CDLA Permissive itself does not carry a share-alike clause — but the WHOLE published table, mixed, is offered under ODbL v1.0 as VIDA licenses it. (3) A "building" here means a detected or mapped footprint polygon, not an inspected structure: confidence is only ever populated for Google-sourced rows (none in Romania today), and Microsoft- and OSM-sourced footprints carry no model confidence at all. (4) What is republished is the layer's own GeoParquet columns for Romania, reshaped: the footprint geometry as WKT, the source, the area, the confidence where one exists, and a bounding box; VIDA's boundary_id and s2_id partition keys are dropped because they are constant across the whole Romanian extract and carry no information here. 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/vida-buildings-ro/manifest.json - All datasets: https://data-directory.fsn1.your-objectstorage.com/public/index.json - Human page: https://data.bunnytech.app/datasets/vida-buildings-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 Immutable, physically sorted snapshot exports. No catalog fetch, best row-group pruning, safe to cache forever. Register one view per table: ```sql INSTALL httpfs; LOAD httpfs; -- buildings: queried live at the source, never copied here — no parquet export. ``` Example queries: -- Buildings inside a bounding box (e.g. central Bucharest): bbox_min_longitude/bbox_max_longitude/bbox_min_latitude/bbox_max_latitude are plain DOUBLE columns, so a bounding-box query needs no spatial extension at all — only once the geometry itself is wanted does ST_GeomFromText(geometry_wkt) come in. ```sql INSTALL spatial; LOAD spatial; ATTACH IF NOT EXISTS ':memory:' AS "vida_buildings_ro"; CREATE SCHEMA IF NOT EXISTS "vida_buildings_ro"."main"; CREATE OR REPLACE VIEW "vida_buildings_ro"."main"."buildings" AS SELECT row_number() OVER ( ORDER BY geohash, bbox.xmin, bbox.ymin, bbox.ymax, bbox.xmax ) AS building_id, bf_source AS bf_source, confidence AS confidence, area_in_meters AS area_in_meters, geohash AS geohash, bbox.xmin AS bbox_min_longitude, bbox.ymin AS bbox_min_latitude, bbox.xmax AS bbox_max_longitude, bbox.ymax AS bbox_max_latitude, ST_AsText(CAST(geometry AS GEOMETRY)) AS geometry_wkt, TIMESTAMPTZ '2026-09-04T08:15:57.402Z' AS ingested_at FROM read_parquet('https://data.source.coop/vida/google-microsoft-osm-open-buildings/geoparquet/by_country/country_iso=ROU/ROU.parquet'); SELECT building_id, bf_source, area_in_meters, geometry_wkt FROM vida_buildings_ro.main.buildings WHERE bbox_min_longitude >= 26.05 AND bbox_max_longitude <= 26.15 AND bbox_min_latitude >= 44.40 AND bbox_max_latitude <= 44.47; ``` -- Prefix-prune by geohash, then measure with the spatial extension: The table's sortBy is geohash, so a prefix predicate on it prunes row groups before any geometry is even parsed; ST_Area is only computed for the rows that survive. ```sql INSTALL spatial; LOAD spatial; ATTACH IF NOT EXISTS ':memory:' AS "vida_buildings_ro"; CREATE SCHEMA IF NOT EXISTS "vida_buildings_ro"."main"; CREATE OR REPLACE VIEW "vida_buildings_ro"."main"."buildings" AS SELECT row_number() OVER ( ORDER BY geohash, bbox.xmin, bbox.ymin, bbox.ymax, bbox.xmax ) AS building_id, bf_source AS bf_source, confidence AS confidence, area_in_meters AS area_in_meters, geohash AS geohash, bbox.xmin AS bbox_min_longitude, bbox.ymin AS bbox_min_latitude, bbox.xmax AS bbox_max_longitude, bbox.ymax AS bbox_max_latitude, ST_AsText(CAST(geometry AS GEOMETRY)) AS geometry_wkt, TIMESTAMPTZ '2026-09-04T08:15:57.402Z' AS ingested_at FROM read_parquet('https://data.source.coop/vida/google-microsoft-osm-open-buildings/geoparquet/by_country/country_iso=ROU/ROU.parquet'); INSTALL spatial; LOAD spatial; SELECT count(*) AS n, sum(ST_Area(ST_GeomFromText(geometry_wkt))) AS total_deg2 FROM vida_buildings_ro.main.buildings WHERE geohash >= 'sxk9' AND geohash < 'sxk9' || chr(255); ``` ## Live lake — DuckLake catalog with time travel Every table in this dataset is queried live at its source, so nothing was copied into a DuckLake and the catalog published beside it holds no tables. Use the setup printed with the example queries above, or the `view.sql` of the table you want from `manifest.json` — that is the query, in full, against the upstream source. ## 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/vida-buildings-ro/v/01M1NQT7YTFY5YJ067PWBKZP89/**/*.parquet'); ``` ## Schema ### buildings One row per building footprint in Romania from VIDA's Google-Microsoft-OSM Open Buildings layer: the footprint polygon as WKT (WGS 84), which of Google, Microsoft or OpenStreetMap produced it, its area, and — for Google-sourced footprints only — the detection model's confidence score. A full wholesale snapshot of the source's current Romanian extract: every ingest replaces the whole table, because the source has no change log to append or upsert against, only a complete republished file. - 0 rows · 0 B · write mode `replace` - Physically sorted by: `geohash`, `building_id` - Primary key: `building_id` - Files: 0 Columns: - `building_id` BIGINT NOT NULL — Synthetic id assigned by this connector in the table's own sort order (geohash, then a deterministic bounding-box tiebreak). The source has no building id at all, not even within one file, so this id is unique within one ingest but is NOT guaranteed to name the same building again if VIDA republishes the extract with different contents. - `bf_source` VARCHAR NOT NULL — Which upstream source produced this exact footprint: "google" (Google Open Buildings V3, CC BY 4.0 — 0 rows in the current Romanian extract), "microsoft" (GlobalMLBuildingFootprints, CDLA Permissive 2.0), or "osm" (OpenStreetMap, ODbL, share-alike). This is the column a reuser who needs a licence more permissive than ODbL filters on to keep only the rows whose own upstream licence allows it. - `confidence` DOUBLE — The detection model's confidence score (0-1), populated only when bf_source is "google" — Microsoft and OpenStreetMap do not supply one and it stays NULL. NULL on every row of the current Romanian extract, because it holds no Google-sourced footprints; the column is kept for the day VIDA's Google coverage reaches Romania. - `area_in_meters` DOUBLE NOT NULL [m²] — The footprint polygon's area, as computed by VIDA. - `geohash` VARCHAR NOT NULL — An 8-character base32 geohash of the footprint's centroid (~19 m precision). The table's physical sort key — see sortByRationale — so a prefix filter such as geohash LIKE 'sxk9%' prunes whole parquet row groups instead of scanning the table. - `bbox_min_longitude` DOUBLE NOT NULL [°] — West edge of the footprint's bounding box, WGS 84 degrees. - `bbox_min_latitude` DOUBLE NOT NULL [°] — South edge of the footprint's bounding box, WGS 84 degrees. - `bbox_max_longitude` DOUBLE NOT NULL [°] — East edge of the footprint's bounding box, WGS 84 degrees. - `bbox_max_latitude` DOUBLE NOT NULL [°] — North edge of the footprint's bounding box, WGS 84 degrees. - `geometry_wkt` TEXT NOT NULL — The building footprint polygon as WKT (Well-Known Text) in WGS 84 (EPSG:4326) — e.g. "POLYGON ((26.1 44.43, 26.1 44.431, …))". WKT rather than a coordinate array because DuckDB's spatial extension reads it directly: `INSTALL spatial; LOAD spatial;` then `ST_GeomFromText(geometry_wkt)` gives a real geometry to intersect, buffer and measure. Longitude first, as WKT requires. - `ingested_at` TIMESTAMP NOT NULL — When this row was produced by the ingest run (UTC). ## 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. - `buildings` prunes on `geohash` → `building_id`. - `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://source.coop/vida/google-microsoft-osm-open-buildings) 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.