Data Catalog - R2 Storage (landbruget-data)
Data lake with 130+ datasets across bronze/silver/gold medallion layers in Cloudflare R2.
Discovering Data
Use rclone to browse R2 — never use gsutil or google.cloud.storage.
# List top-level directories
rclone lsd r2:landbruget-data/
# List datasets in a layer
rclone lsd r2:landbruget-data/bronze/
rclone lsd r2:landbruget-data/silver/
rclone lsd r2:landbruget-data/gold/
# List snapshots (timestamped subdirectories) for a dataset
rclone lsd r2:landbruget-data/silver/subsidies/
# List files in a snapshot
rclone ls r2:landbruget-data/silver/subsidies/
# Find latest snapshot for a dataset
rclone lsd r2:landbruget-data/gold/field_production_2024/ | tail -1
Important: Some folder names contain spaces (e.g., silver/animal welfare/, silver/work permits/). Always quote paths when scripting.
Reading Data with DuckDB
DuckDB with R2 auth is the primary way to query data. Use StorageAccess from backend/common/storage/core.py:
from common.storage.core import StorageAccess
storage = StorageAccess()
# Read a parquet file into DuckDB
storage.create_table_from_storage_parquet("my_table", "landbruget-data/silver/subsidies/20260401_020000/data.parquet")
# Query it
result = storage.execute_query("SELECT cvr_number, COUNT(*) FROM my_table GROUP BY cvr_number")
Or use DuckDB directly after auth setup:
import duckdb
from common.storage.filesystem import setup_duckdb_cloud_auth
conn = duckdb.connect()
setup_duckdb_cloud_auth(conn)
# Query directly from R2
result = conn.execute("""
SELECT cvr_number, SUM(area_ha) as total_area
FROM read_parquet('r2://landbruget-data/gold/field_production_2024/*/data.parquet')
GROUP BY cvr_number
""").fetchdf()
Environment Variables
# R2 credentials (required)
R2_ACCESS_KEY_ID=<access-key>
R2_SECRET_ACCESS_KEY=<secret-key>
R2_ACCOUNT_ID=<account-id>
# Bucket name (defaults to "landbruget-data")
R2_BUCKET=landbruget-data
# Or: STORAGE_BUCKET=landbruget-data
Medallion Architecture
bronze/ — Raw data exactly as received (133 datasets)
silver/ — Cleaned, validated, standardized (126 datasets)
gold/ — Analysis-ready, joined datasets (86 datasets)
Full Dataset Inventory
Bronze (133 datasets)
| Category |
Datasets |
| Fields |
agricultural_blocks_{2020-2024}, agricultural_fields_{2020-2025}, fields |
| FVM Marker |
fvm_marker_{2008-2025}, fvm_marker_smaabiotoper_{2023-2025} |
| FVM Markblokke |
fvm_markblokke_{2005-2026} |
| Organic |
fvm_organic_areas_{2012-2024}, fvm_organic_subsidies_{2019-2024} |
| Subsidies |
subsidies, fvm_environmental_subsidies_{2019-2023}, fvm_grassland_subsidies_{2019-2024} |
| Jordbrugsanalyser |
jordbrugsanalyser_markers_{2012-2024} |
| Cadastral/Geo |
cadastral, dagi_kommuner, dagi_landsdele, dagi_postnumre, dagi_regioner, bbr_buildings |
| Environment |
bnbo_status, wetlands, soil_types, water_projects, water_typology_* (3 datasets), grukos_* (2 datasets), fertiliser |
| Pesticides |
pesticides, bmd, geus_dataverse_pesticides, kemidata_surface_water_pesticides |
| Livestock |
chr, animal_welfare, animal_mortality, animal_international_movements, pig_tail_cutting, slurry_leaks, stable_fires, transportation_accidents |
| Companies |
cvr_raw_companies, dst, dmi |
| Workers |
arbejdstilsynet_inspections, work_permits, worker_safety |
Silver (126 datasets)
| Category |
Datasets |
| Fields |
fvm_marker_{2008-2025}, fvm_markblokke_{2005-2026}, fvm_smaabiotoper_{2023-2025}, fields |
| Organic |
fvm_organic_areas_{2012-2023}, fvm_organic_subsidies_{2019-2024} |
| Subsidies |
subsidies, fvm_environmental_subsidies_{2019-2023}, fvm_grassland_subsidies_{2019-2024} |
| Cadastral/Geo |
cadastral, dagi_kommuner, dagi_landsdele, dagi_postnumre, dagi_regioner, bbr_buildings, dst_zone_mapping, dst_zone_mapping_reference |
| Environment |
bnbo_status, bnbo_status_dissolved, wetlands (implied), grukos, grukos_*_dissolved (2), water_projects, water_projects_dissolved, fertiliser |
| Pesticides |
pesticides, bmd, geus_dataverse_pesticides, geus_dataverse_pesticides_pfas |
| Livestock |
chr, svineflytning, animal welfare, animal mortality, animal international movements, pig tail cutting, slurry leaks, stable fires, transportation accidents |
| Companies |
cvr_companies, cvr_employment, cvr_persons, property_owners |
| Workers |
arbejdstilsynet_inspections, work permits, worker safety |
| Legacy/Other |
2016_* (4 datasets), gr {2015-2023} (8 datasets), fro_processed, gartn1_processed, halm1_processed, hst77_processed |
Gold (86 datasets)
| Category |
Datasets |
| Field Production |
field_production_{2008-2025} (18 years) |
| Field Analysis |
field_analysis_field_bnbo_intersections_{2024,2025}, field_analysis_field_bnbo_water_intersections_{2024,2025}, field_analysis_field_grukos_intersections_{2024,2025}, field_analysis_field_wetland_intersections_{2024,2025}, field_analysis_field_wetland_water_intersections_{2024,2025}, field_analysis_soil_intersections_{2024,2025}, field_analysis_water_projects_bnbo_intersections_{2024,2025}, field_analysis_water_projects_wetlands_intersections_{2024,2025}, field_analysis_wetland_water_coverage |
| Environmental Analysis |
field_environmental_analysis_fields_{2024,2025}, field_environmental_analysis_properties_{2024,2025} |
| Pesticides |
pesticide_disaggregation_{2010_2011 through 2023_2024} (13 year-pairs), pesticide_proximity_{2010_2011 through 2023_2024} (13 year-pairs) |
| Pre-computed stages |
stage0_bnbo_filtered_{2024,2025}, stage0_grukos_filtered_{2024,2025}, stage0_properties_filtered_{2024,2025}, stage0_soil_types_filtered_{2024,2025}, stage0_water_projects_filtered_{2024,2025}, stage0_wetlands_filtered_{2024,2025} |
| Livestock |
chr_timeline_summary, chr_veterinary_timeline |
| Companies |
cvr_enrichment, cvr_enrichment_collection, cvr_enrichment_companies, cvr_enrichment_financial, cvr_enrichment_financial_statements, cvr_enrichment_pnumbers |
| Cadastral |
property_cadastral_merged |
Other Top-Level
api/ — API-related data
cvr_collections/ — CVR collection data
Key Identifiers
| Identifier |
Format |
Description |
Validation |
| CVR |
8 digits |
Company registration number |
^\d{8}$ |
| CHR |
6 digits |
Central Husbandry Register (herd ID) |
^\d{6}$ |
| BFE |
Variable |
Cadastral parcel number |
varies |
| field_id |
String |
Field identifier from FVM |
varies |
| field_uuid |
UUID |
Unique field identifier |
UUID format |
Dataset Quick Reference
Okonomi (Finance)
| Dataset |
Path |
Rows |
Key Columns |
| Subsidies |
silver/subsidies/ |
554K |
cvr_number, tilskudsberetigt |
| CVR Enrichment |
gold/cvr_enrichment/ |
varies |
cvr_number, company data |
| Property Owners |
silver/property_owners/ |
8.2M |
CVRNummer, owner info |
Landbrugsareal (Agricultural Land)
| Dataset |
Path |
Rows |
Key Columns |
| FVM Marker (fields) |
silver/fvm_marker_{year}/ |
617K/year |
field_id, cvr_number, crop_code, geometry |
| Field Production |
gold/field_production_{year}/ |
617K/year |
field_id, yield_estimate, crop_type |
| Cadastral |
silver/cadastral/ |
2.16M |
bfe_number, geometry |
Miljo (Environment)
| Dataset |
Path |
Rows |
Key Columns |
| Pesticide Disaggregation |
gold/pesticide_disaggregation_{year}/ |
1.52M |
cvr_number, PesticideName, DosageQuantity |
| BNBO Status |
silver/bnbo_status/ |
5.4K |
geometry, status_bnbo |
| Wetlands |
silver/wetlands/ (in bronze) |
1.7M |
geometry, toerv_pct |
Husdyr (Livestock)
| Dataset |
Path |
Rows |
Key Columns |
| Svineflytning |
silver/svineflytning/ |
1.27M |
sender_chr_number, receiver_chr_number, total_animals |
| CHR Movements |
bronze/chr/ |
124K |
reporting_herd_number, animal_count |
| Animal Welfare |
silver/animal welfare/ |
varies |
chr_number |
Medarbejdere (Employees)
| Dataset |
Path |
Rows |
Key Columns |
| Arbejdstilsynet |
gold/arbejdstilsynet_inspections/ |
536 |
cvr_number, decision, severity_score |
| Work Permits |
silver/work permits/ |
varies |
cvr_number |
| Worker Safety |
silver/worker safety/ |
varies |
cvr_number |
Cross-Dataset Joins
CVR-based joins (most common)
# Join subsidies with pesticides on CVR using DuckDB
conn.execute("""
SELECT s.cvr_number, s.tilskudsberetigt, p.PesticideName
FROM read_parquet('r2://landbruget-data/silver/subsidies/*/data.parquet') s
JOIN read_parquet('r2://landbruget-data/gold/pesticide_disaggregation_2023_2024/*/data.parquet') p
ON s.cvr_number = p.cvr_number
""")
Field-based joins
# Join field production with environmental analysis
conn.execute("""
SELECT fp.field_id, fp.yield_estimate, fe.bnbo_overlap_pct
FROM read_parquet('r2://landbruget-data/gold/field_production_2024/*/data.parquet') fp
JOIN read_parquet('r2://landbruget-data/gold/field_environmental_analysis_fields_2024/*/data.parquet') fe
ON fp.field_id = fe.field_id
""")
Data Update Schedule
| Layer |
Frequency |
Notes |
| Bronze |
Weekly (Mondays 2AM UTC) |
Immutable, timestamped |
| Silver |
After bronze update |
Cleaned, validated |
| Gold |
After silver update |
Analysis-ready |
Related Skills
- okonomi/ - Financial data: subsidies, property values
- landbrugsareal/ - Field and crop data: FVM marker, production
- miljo/ - Environmental data: pesticides, nitrogen, BNBO
- husdyr/ - Livestock data: CHR, movements, welfare
- medarbejdere/ - Employee data: inspections, safety
Troubleshooting
Check R2 access
rclone lsd r2:landbruget-data/
If rclone fails
Check ~/.config/rclone/rclone.conf has an [r2] section with:
type = s3
provider = Cloudflare
access_key_id and secret_access_key
endpoint pointing to your R2 account
Large Files
Use DuckDB — never load large parquet files into Pandas:
conn.execute("""
SELECT cvr_number, SUM(area_ha) as total_area
FROM read_parquet('r2://landbruget-data/gold/field_production_2024/*/data.parquet')
GROUP BY cvr_number
""").fetchdf()
CRS
All geometry stored in EPSG:4326 (WGS84) in Supabase. Bronze/Silver/Gold processing uses EPSG:25832 (UTM 32N).
Converted and distributed by TomeVault — claim your Tome and manage your conversions.
1---2name: klimabevaegelsen-landbruget-dk-gcs-data-catalog3description: Data Catalog - R2 Storage (landbruget-data)4---56# Data Catalog - R2 Storage (landbruget-data)78Data lake with 130+ datasets across bronze/silver/gold medallion layers in Cloudflare R2.910## Discovering Data1112**Use `rclone` to browse R2 — never use `gsutil` or `google.cloud.storage`.**1314```bash15# List top-level directories16rclone lsd r2:landbruget-data/1718# List datasets in a layer19rclone lsd r2:landbruget-data/bronze/20rclone lsd r2:landbruget-data/silver/21rclone lsd r2:landbruget-data/gold/2223# List snapshots (timestamped subdirectories) for a dataset24rclone lsd r2:landbruget-data/silver/subsidies/2526# List files in a snapshot27rclone ls r2:landbruget-data/silver/subsidies/2829# Find latest snapshot for a dataset30rclone lsd r2:landbruget-data/gold/field_production_2024/ | tail -131```3233**Important**: Some folder names contain spaces (e.g., `silver/animal welfare/`, `silver/work permits/`). Always quote paths when scripting.3435## Reading Data with DuckDB3637DuckDB with R2 auth is the primary way to query data. Use `StorageAccess` from `backend/common/storage/core.py`:3839```python40from common.storage.core import StorageAccess4142storage = StorageAccess()4344# Read a parquet file into DuckDB45storage.create_table_from_storage_parquet("my_table", "landbruget-data/silver/subsidies/20260401_020000/data.parquet")4647# Query it48result = storage.execute_query("SELECT cvr_number, COUNT(*) FROM my_table GROUP BY cvr_number")49```5051Or use DuckDB directly after auth setup:5253```python54import duckdb55from common.storage.filesystem import setup_duckdb_cloud_auth5657conn = duckdb.connect()58setup_duckdb_cloud_auth(conn)5960# Query directly from R261result = conn.execute("""62 SELECT cvr_number, SUM(area_ha) as total_area63 FROM read_parquet('r2://landbruget-data/gold/field_production_2024/*/data.parquet')64 GROUP BY cvr_number65""").fetchdf()66```6768## Environment Variables6970```bash71# R2 credentials (required)72R2_ACCESS_KEY_ID=<access-key>73R2_SECRET_ACCESS_KEY=<secret-key>74R2_ACCOUNT_ID=<account-id>7576# Bucket name (defaults to "landbruget-data")77R2_BUCKET=landbruget-data78# Or: STORAGE_BUCKET=landbruget-data79```8081## Medallion Architecture8283- `bronze/` — Raw data exactly as received (133 datasets)84- `silver/` — Cleaned, validated, standardized (126 datasets)85- `gold/` — Analysis-ready, joined datasets (86 datasets)8687## Full Dataset Inventory8889### Bronze (133 datasets)9091| Category | Datasets |92|----------|----------|93| **Fields** | `agricultural_blocks_{2020-2024}`, `agricultural_fields_{2020-2025}`, `fields` |94| **FVM Marker** | `fvm_marker_{2008-2025}`, `fvm_marker_smaabiotoper_{2023-2025}` |95| **FVM Markblokke** | `fvm_markblokke_{2005-2026}` |96| **Organic** | `fvm_organic_areas_{2012-2024}`, `fvm_organic_subsidies_{2019-2024}` |97| **Subsidies** | `subsidies`, `fvm_environmental_subsidies_{2019-2023}`, `fvm_grassland_subsidies_{2019-2024}` |98| **Jordbrugsanalyser** | `jordbrugsanalyser_markers_{2012-2024}` |99| **Cadastral/Geo** | `cadastral`, `dagi_kommuner`, `dagi_landsdele`, `dagi_postnumre`, `dagi_regioner`, `bbr_buildings` |100| **Environment** | `bnbo_status`, `wetlands`, `soil_types`, `water_projects`, `water_typology_*` (3 datasets), `grukos_*` (2 datasets), `fertiliser` |101| **Pesticides** | `pesticides`, `bmd`, `geus_dataverse_pesticides`, `kemidata_surface_water_pesticides` |102| **Livestock** | `chr`, `animal_welfare`, `animal_mortality`, `animal_international_movements`, `pig_tail_cutting`, `slurry_leaks`, `stable_fires`, `transportation_accidents` |103| **Companies** | `cvr_raw_companies`, `dst`, `dmi` |104| **Workers** | `arbejdstilsynet_inspections`, `work_permits`, `worker_safety` |105106### Silver (126 datasets)107108| Category | Datasets |109|----------|----------|110| **Fields** | `fvm_marker_{2008-2025}`, `fvm_markblokke_{2005-2026}`, `fvm_smaabiotoper_{2023-2025}`, `fields` |111| **Organic** | `fvm_organic_areas_{2012-2023}`, `fvm_organic_subsidies_{2019-2024}` |112| **Subsidies** | `subsidies`, `fvm_environmental_subsidies_{2019-2023}`, `fvm_grassland_subsidies_{2019-2024}` |113| **Cadastral/Geo** | `cadastral`, `dagi_kommuner`, `dagi_landsdele`, `dagi_postnumre`, `dagi_regioner`, `bbr_buildings`, `dst_zone_mapping`, `dst_zone_mapping_reference` |114| **Environment** | `bnbo_status`, `bnbo_status_dissolved`, `wetlands` (implied), `grukos`, `grukos_*_dissolved` (2), `water_projects`, `water_projects_dissolved`, `fertiliser` |115| **Pesticides** | `pesticides`, `bmd`, `geus_dataverse_pesticides`, `geus_dataverse_pesticides_pfas` |116| **Livestock** | `chr`, `svineflytning`, `animal welfare`, `animal mortality`, `animal international movements`, `pig tail cutting`, `slurry leaks`, `stable fires`, `transportation accidents` |117| **Companies** | `cvr_companies`, `cvr_employment`, `cvr_persons`, `property_owners` |118| **Workers** | `arbejdstilsynet_inspections`, `work permits`, `worker safety` |119| **Legacy/Other** | `2016_*` (4 datasets), `gr {2015-2023}` (8 datasets), `fro_processed`, `gartn1_processed`, `halm1_processed`, `hst77_processed` |120121### Gold (86 datasets)122123| Category | Datasets |124|----------|----------|125| **Field Production** | `field_production_{2008-2025}` (18 years) |126| **Field Analysis** | `field_analysis_field_bnbo_intersections_{2024,2025}`, `field_analysis_field_bnbo_water_intersections_{2024,2025}`, `field_analysis_field_grukos_intersections_{2024,2025}`, `field_analysis_field_wetland_intersections_{2024,2025}`, `field_analysis_field_wetland_water_intersections_{2024,2025}`, `field_analysis_soil_intersections_{2024,2025}`, `field_analysis_water_projects_bnbo_intersections_{2024,2025}`, `field_analysis_water_projects_wetlands_intersections_{2024,2025}`, `field_analysis_wetland_water_coverage` |127| **Environmental Analysis** | `field_environmental_analysis_fields_{2024,2025}`, `field_environmental_analysis_properties_{2024,2025}` |128| **Pesticides** | `pesticide_disaggregation_{2010_2011 through 2023_2024}` (13 year-pairs), `pesticide_proximity_{2010_2011 through 2023_2024}` (13 year-pairs) |129| **Pre-computed stages** | `stage0_bnbo_filtered_{2024,2025}`, `stage0_grukos_filtered_{2024,2025}`, `stage0_properties_filtered_{2024,2025}`, `stage0_soil_types_filtered_{2024,2025}`, `stage0_water_projects_filtered_{2024,2025}`, `stage0_wetlands_filtered_{2024,2025}` |130| **Livestock** | `chr_timeline_summary`, `chr_veterinary_timeline` |131| **Companies** | `cvr_enrichment`, `cvr_enrichment_collection`, `cvr_enrichment_companies`, `cvr_enrichment_financial`, `cvr_enrichment_financial_statements`, `cvr_enrichment_pnumbers` |132| **Cadastral** | `property_cadastral_merged` |133134### Other Top-Level135136- `api/` — API-related data137- `cvr_collections/` — CVR collection data138139## Key Identifiers140141| Identifier | Format | Description | Validation |142|------------|--------|-------------|------------|143| **CVR** | 8 digits | Company registration number | `^\d{8}$` |144| **CHR** | 6 digits | Central Husbandry Register (herd ID) | `^\d{6}$` |145| **BFE** | Variable | Cadastral parcel number | varies |146| **field_id** | String | Field identifier from FVM | varies |147| **field_uuid** | UUID | Unique field identifier | UUID format |148149## Dataset Quick Reference150151### Okonomi (Finance)152| Dataset | Path | Rows | Key Columns |153|---------|------|------|-------------|154| Subsidies | `silver/subsidies/` | 554K | cvr_number, tilskudsberetigt |155| CVR Enrichment | `gold/cvr_enrichment/` | varies | cvr_number, company data |156| Property Owners | `silver/property_owners/` | 8.2M | CVRNummer, owner info |157158### Landbrugsareal (Agricultural Land)159| Dataset | Path | Rows | Key Columns |160|---------|------|------|-------------|161| FVM Marker (fields) | `silver/fvm_marker_{year}/` | 617K/year | field_id, cvr_number, crop_code, geometry |162| Field Production | `gold/field_production_{year}/` | 617K/year | field_id, yield_estimate, crop_type |163| Cadastral | `silver/cadastral/` | 2.16M | bfe_number, geometry |164165### Miljo (Environment)166| Dataset | Path | Rows | Key Columns |167|---------|------|------|-------------|168| Pesticide Disaggregation | `gold/pesticide_disaggregation_{year}/` | 1.52M | cvr_number, PesticideName, DosageQuantity |169| BNBO Status | `silver/bnbo_status/` | 5.4K | geometry, status_bnbo |170| Wetlands | `silver/wetlands/` (in bronze) | 1.7M | geometry, toerv_pct |171172### Husdyr (Livestock)173| Dataset | Path | Rows | Key Columns |174|---------|------|------|-------------|175| Svineflytning | `silver/svineflytning/` | 1.27M | sender_chr_number, receiver_chr_number, total_animals |176| CHR Movements | `bronze/chr/` | 124K | reporting_herd_number, animal_count |177| Animal Welfare | `silver/animal welfare/` | varies | chr_number |178179### Medarbejdere (Employees)180| Dataset | Path | Rows | Key Columns |181|---------|------|------|-------------|182| Arbejdstilsynet | `gold/arbejdstilsynet_inspections/` | 536 | cvr_number, decision, severity_score |183| Work Permits | `silver/work permits/` | varies | cvr_number |184| Worker Safety | `silver/worker safety/` | varies | cvr_number |185186## Cross-Dataset Joins187188### CVR-based joins (most common)189```python190# Join subsidies with pesticides on CVR using DuckDB191conn.execute("""192 SELECT s.cvr_number, s.tilskudsberetigt, p.PesticideName193 FROM read_parquet('r2://landbruget-data/silver/subsidies/*/data.parquet') s194 JOIN read_parquet('r2://landbruget-data/gold/pesticide_disaggregation_2023_2024/*/data.parquet') p195 ON s.cvr_number = p.cvr_number196""")197```198199### Field-based joins200```python201# Join field production with environmental analysis202conn.execute("""203 SELECT fp.field_id, fp.yield_estimate, fe.bnbo_overlap_pct204 FROM read_parquet('r2://landbruget-data/gold/field_production_2024/*/data.parquet') fp205 JOIN read_parquet('r2://landbruget-data/gold/field_environmental_analysis_fields_2024/*/data.parquet') fe206 ON fp.field_id = fe.field_id207""")208```209210## Data Update Schedule211212| Layer | Frequency | Notes |213|-------|-----------|-------|214| Bronze | Weekly (Mondays 2AM UTC) | Immutable, timestamped |215| Silver | After bronze update | Cleaned, validated |216| Gold | After silver update | Analysis-ready |217218## Related Skills219220- **okonomi/** - Financial data: subsidies, property values221- **landbrugsareal/** - Field and crop data: FVM marker, production222- **miljo/** - Environmental data: pesticides, nitrogen, BNBO223- **husdyr/** - Livestock data: CHR, movements, welfare224- **medarbejdere/** - Employee data: inspections, safety225226## Troubleshooting227228### Check R2 access229```bash230rclone lsd r2:landbruget-data/231```232233### If rclone fails234Check `~/.config/rclone/rclone.conf` has an `[r2]` section with:235- `type = s3`236- `provider = Cloudflare`237- `access_key_id` and `secret_access_key`238- `endpoint` pointing to your R2 account239240### Large Files241Use DuckDB — never load large parquet files into Pandas:242```python243conn.execute("""244 SELECT cvr_number, SUM(area_ha) as total_area245 FROM read_parquet('r2://landbruget-data/gold/field_production_2024/*/data.parquet')246 GROUP BY cvr_number247""").fetchdf()248```249250### CRS251All geometry stored in EPSG:4326 (WGS84) in Supabase. Bronze/Silver/Gold processing uses EPSG:25832 (UTM 32N).252253---254> Converted and distributed by [TomeVault](https://tomevault.io/claim/klimabevaegelsen) — claim your Tome and manage your conversions.255<!-- tomevault:4.0:skill_md:2026-04-11 -->