A national benchmark dataset for operational crop mapping in Switzerland, providing Sentinel-2 time series, daily temperature data, and parcel-level crop type labels across seven growing seasons (2019–2025).
Introduced in: SwissCrop25: A National Multi-Year Benchmark for Operational Crop Mapping (TerraBytes II Workshop, ECCV 2026) — [Paper] [Code] [Team]

sentinel2/{year}/ Shards (.tar), 120 per year
sentinel2/{year}.json Kerchunk reference index for random access
labels/{year}.tar Per-parcel crop labels
labels/{year}.tar.json Kerchunk index
temperature/{year}.tar Per-parcel GDD time series
temperature/{year}.tar.json Kerchunk index
metadata/
crop_classes.csv Full class list with hierarchy, LNF codes, HCAT4 mapping
tiles.parquet GeoParquet spatial index: one row per tile × year with geometry,
tile names, and tar paths for all three modalities
Each year comes with a Kerchunk reference index (sentinel2/{year}.json) that maps
the full annual collection to a single virtual zarr store, enabling direct fast tile access.
After downloading the dataset locally:
import fsspec
import zarr
mapper = fsspec.filesystem("reference", fo="sentinel2/2021.json").get_mapper("")
store = zarr.open_group(mapper, mode="r")
# Access a specific tile directly by name
tile = store["S2_357340_5169580_20220104_20221230.zarr"]
blue = tile["s2_B02"][:] # (T, 128, 128), uint16, scaled reflectance (÷10000)
time = tile["time"][:] # (T,), days since 1 Jan of that year
Available bands: s2_B02, s2_B03, s2_B04, s2_B05, s2_B06, s2_B07,
s2_B08, s2_B8A, s2_B11, s2_B12, s2_SCL (Scene Classification Layer),
s2_mask (CloudSEN12+ score).
metadata/tiles.parquet is a GeoParquet file (CRS: EPSG:32632) with one row per tile × year.
Use it to find which tiles and Kerchunk stores cover a region of interest, then access the data directly:
import geopandas as gpd
import fsspec
import zarr
from shapely.geometry import box
# 1. Spatial query — find tiles overlapping a region (EPSG:32632, UTM zone 32N)
tiles = gpd.read_parquet("metadata/tiles.parquet")
roi = box(455000, 5237000, 480000, 5260000) # ~25 km box around Zurich
hits = tiles[tiles.intersects(roi) & (tiles.year == 2022)]
# 2. Open the Kerchunk store for that year and access each tile
mapper = fsspec.filesystem("reference", fo="sentinel2/2022.json").get_mapper("")
store = zarr.open_group(mapper, mode="r")
for row in hits.itertuples():
tile = store[row.sentinel2_tile]
blue = tile["s2_B02"][:] # (T, 128, 128), uint16
time = tile["time"][:] # (T,) days since 1 Jan
Columns: year, left, top, row_index, col_index, geometry,
sentinel2_tile, sentinel2_tar, labels_tile, labels_tar,
temperature_tile, temperature_tar.
For training with GDD-based temporal subsampling, cloud filtering, and DDP support,
use the SatelliteDataset class from the code repository.
It reads Kerchunk index files for all three modalities:
from src.dataset import SatelliteDataset
dataset = SatelliteDataset(
satellite_paths=["sentinel2/2021.json", "sentinel2/2022.json"],
gt_paths=["labels/2021.tar.json", "labels/2022.tar.json"],
temp_paths=["temperature/2021.tar.json", "temperature/2022.tar.json"],
use_temperature_calendar=True,
use_temperature_subsampling=True,
)
See train_utae.py, train_tsvit.py, and train_galileo.py for complete training examples.
SwissCrop25 defines a five-fold leave-one-year-out (LOYO) protocol:
| Split | Test | Val | Train |
|---|---|---|---|
| S1 | 2021 | 2020 | 2019, 2022–2025 |
| S2 | 2022 | 2021 | 2019–2020, 2023–2025 |
| S3 | 2023 | 2022 | 2019–2021, 2024–2025 |
| S4 | 2024 | 2023 | 2019–2022, 2025 |
| S5 | 2025 | 2024 | 2019–2023 |
2019–2020 are used as training data only due to incomplete national coverage.
Results under the LOYO protocol (mean ± std across five splits, best temporal encoding per model):
| Model | OA (%) | GIoU (%) | mIoU (%) | mF1 (%) |
|---|---|---|---|---|
| U-TAE | 77.7 ± 1.5 | 63.5 ± 2.0 | 35.8 ± 2.3 | 45.7 ± 2.4 |
| TSViT | 77.1 ± 1.2 | 62.7 ± 1.6 | 48.1 ± 2.7 | 60.7 ± 2.5 |
| Galileo-nano (FT) | 72.9 ± 1.3 | 57.4 ± 1.6 | 30.4 ± 2.2 | 41.1 ± 2.5 |
Full per-split and per-class results are in the paper.
@misc{lauber2026swisscrop25nationalmultiyearbenchmark,
title = {SwissCrop25: A National Multi-Year Benchmark for Operational Crop Mapping},
author = {Thomas Lauber and Mehmet Ozgur Turkoglu and Sélène Ledain and Helge Aasen},
year = {2026},
eprint = {2608.09497},
archivePrefix = {arXiv},
primaryClass = {cs.CV},
url = {https://arxiv.org/abs/2608.09497}
}
Released under CC BY 4.0.
When using this dataset, please cite:
Quelle: Nutzungsflächen, Kanton GraubündenFonte: Amministrazione cantonale - Canton TicinoSource: Géodonnées Etat de VaudKanton St.GallenKanton Nidwalden, Amt für LandwirtschaftKanton Obwalden, Amt für Landwirtschaft und UmweltData provided as is, without warranty. Not for navigation or legally-binding use. Contains no personal or farm-identifying attributes.
A national benchmark dataset for operational crop mapping in Switzerland, providing Sentinel-2 time series, daily temperature data, and parcel-level crop type labels across seven growing seasons (2019–2025).
Introduced in: SwissCrop25: A National Multi-Year Benchmark for Operational Crop Mapping (TerraBytes II Workshop, ECCV 2026) — [Paper] [Code] [Team]

sentinel2/{year}/ Shards (.tar), 120 per year
sentinel2/{year}.json Kerchunk reference index for random access
labels/{year}.tar Per-parcel crop labels
labels/{year}.tar.json Kerchunk index
temperature/{year}.tar Per-parcel GDD time series
temperature/{year}.tar.json Kerchunk index
metadata/
crop_classes.csv Full class list with hierarchy, LNF codes, HCAT4 mapping
tiles.parquet GeoParquet spatial index: one row per tile × year with geometry,
tile names, and tar paths for all three modalities
Each year comes with a Kerchunk reference index (sentinel2/{year}.json) that maps
the full annual collection to a single virtual zarr store, enabling direct fast tile access.
After downloading the dataset locally:
import fsspec
import zarr
mapper = fsspec.filesystem("reference", fo="sentinel2/2021.json").get_mapper("")
store = zarr.open_group(mapper, mode="r")
# Access a specific tile directly by name
tile = store["S2_357340_5169580_20220104_20221230.zarr"]
blue = tile["s2_B02"][:] # (T, 128, 128), uint16, scaled reflectance (÷10000)
time = tile["time"][:] # (T,), days since 1 Jan of that year
Available bands: s2_B02, s2_B03, s2_B04, s2_B05, s2_B06, s2_B07,
s2_B08, s2_B8A, s2_B11, s2_B12, s2_SCL (Scene Classification Layer),
s2_mask (CloudSEN12+ score).
metadata/tiles.parquet is a GeoParquet file (CRS: EPSG:32632) with one row per tile × year.
Use it to find which tiles and Kerchunk stores cover a region of interest, then access the data directly:
import geopandas as gpd
import fsspec
import zarr
from shapely.geometry import box
# 1. Spatial query — find tiles overlapping a region (EPSG:32632, UTM zone 32N)
tiles = gpd.read_parquet("metadata/tiles.parquet")
roi = box(455000, 5237000, 480000, 5260000) # ~25 km box around Zurich
hits = tiles[tiles.intersects(roi) & (tiles.year == 2022)]
# 2. Open the Kerchunk store for that year and access each tile
mapper = fsspec.filesystem("reference", fo="sentinel2/2022.json").get_mapper("")
store = zarr.open_group(mapper, mode="r")
for row in hits.itertuples():
tile = store[row.sentinel2_tile]
blue = tile["s2_B02"][:] # (T, 128, 128), uint16
time = tile["time"][:] # (T,) days since 1 Jan
Columns: year, left, top, row_index, col_index, geometry,
sentinel2_tile, sentinel2_tar, labels_tile, labels_tar,
temperature_tile, temperature_tar.
For training with GDD-based temporal subsampling, cloud filtering, and DDP support,
use the SatelliteDataset class from the code repository.
It reads Kerchunk index files for all three modalities:
from src.dataset import SatelliteDataset
dataset = SatelliteDataset(
satellite_paths=["sentinel2/2021.json", "sentinel2/2022.json"],
gt_paths=["labels/2021.tar.json", "labels/2022.tar.json"],
temp_paths=["temperature/2021.tar.json", "temperature/2022.tar.json"],
use_temperature_calendar=True,
use_temperature_subsampling=True,
)
See train_utae.py, train_tsvit.py, and train_galileo.py for complete training examples.
SwissCrop25 defines a five-fold leave-one-year-out (LOYO) protocol:
| Split | Test | Val | Train |
|---|---|---|---|
| S1 | 2021 | 2020 | 2019, 2022–2025 |
| S2 | 2022 | 2021 | 2019–2020, 2023–2025 |
| S3 | 2023 | 2022 | 2019–2021, 2024–2025 |
| S4 | 2024 | 2023 | 2019–2022, 2025 |
| S5 | 2025 | 2024 | 2019–2023 |
2019–2020 are used as training data only due to incomplete national coverage.
Results under the LOYO protocol (mean ± std across five splits, best temporal encoding per model):
| Model | OA (%) | GIoU (%) | mIoU (%) | mF1 (%) |
|---|---|---|---|---|
| U-TAE | 77.7 ± 1.5 | 63.5 ± 2.0 | 35.8 ± 2.3 | 45.7 ± 2.4 |
| TSViT | 77.1 ± 1.2 | 62.7 ± 1.6 | 48.1 ± 2.7 | 60.7 ± 2.5 |
| Galileo-nano (FT) | 72.9 ± 1.3 | 57.4 ± 1.6 | 30.4 ± 2.2 | 41.1 ± 2.5 |
Full per-split and per-class results are in the paper.
@misc{lauber2026swisscrop25nationalmultiyearbenchmark,
title = {SwissCrop25: A National Multi-Year Benchmark for Operational Crop Mapping},
author = {Thomas Lauber and Mehmet Ozgur Turkoglu and Sélène Ledain and Helge Aasen},
year = {2026},
eprint = {2608.09497},
archivePrefix = {arXiv},
primaryClass = {cs.CV},
url = {https://arxiv.org/abs/2608.09497}
}
Released under CC BY 4.0.
When using this dataset, please cite:
Quelle: Nutzungsflächen, Kanton GraubündenFonte: Amministrazione cantonale - Canton TicinoSource: Géodonnées Etat de VaudKanton St.GallenKanton Nidwalden, Amt für LandwirtschaftKanton Obwalden, Amt für Landwirtschaft und UmweltData provided as is, without warranty. Not for navigation or legally-binding use. Contains no personal or farm-identifying attributes.