diff --git a/docs/api/datasets.rst b/docs/api/datasets.rst
index 6c5c57ff176..143da4a9d39 100644
--- a/docs/api/datasets.rst
+++ b/docs/api/datasets.rst
@@ -215,6 +215,7 @@ BigEarthNet
^^^^^^^^^^^
.. autoclass:: BigEarthNet
+.. autoclass:: BigEarthNetV2
BioMassters
^^^^^^^^^^^
diff --git a/requirements/datasets.txt b/requirements/datasets.txt
index 680dae8987d..97d9bd5af10 100644
--- a/requirements/datasets.txt
+++ b/requirements/datasets.txt
@@ -6,3 +6,4 @@ pandas[parquet]==2.2.3
pycocotools==2.0.8
scikit-image==0.25.0
scipy==1.15.1
+zstandard==0.23.0
diff --git a/tests/data/bigearthnetV2/BigEarthNet-S1.tar.zst b/tests/data/bigearthnetV2/BigEarthNet-S1.tar.zst
new file mode 100644
index 00000000000..24751c24655
Binary files /dev/null and b/tests/data/bigearthnetV2/BigEarthNet-S1.tar.zst differ
diff --git a/tests/data/bigearthnetV2/BigEarthNet-S1/S1A_IW_GRDH_1SDV_20170613T165043/S1A_IW_GRDH_1SDV_20170613T165043_33UUP_61_39/S1A_IW_GRDH_1SDV_20170613T165043_33UUP_61_39_VH.tif b/tests/data/bigearthnetV2/BigEarthNet-S1/S1A_IW_GRDH_1SDV_20170613T165043/S1A_IW_GRDH_1SDV_20170613T165043_33UUP_61_39/S1A_IW_GRDH_1SDV_20170613T165043_33UUP_61_39_VH.tif
new file mode 100644
index 00000000000..46cd1d2951f
Binary files /dev/null and b/tests/data/bigearthnetV2/BigEarthNet-S1/S1A_IW_GRDH_1SDV_20170613T165043/S1A_IW_GRDH_1SDV_20170613T165043_33UUP_61_39/S1A_IW_GRDH_1SDV_20170613T165043_33UUP_61_39_VH.tif differ
diff --git a/tests/data/bigearthnetV2/BigEarthNet-S1/S1A_IW_GRDH_1SDV_20170613T165043/S1A_IW_GRDH_1SDV_20170613T165043_33UUP_61_39/S1A_IW_GRDH_1SDV_20170613T165043_33UUP_61_39_VV.tif b/tests/data/bigearthnetV2/BigEarthNet-S1/S1A_IW_GRDH_1SDV_20170613T165043/S1A_IW_GRDH_1SDV_20170613T165043_33UUP_61_39/S1A_IW_GRDH_1SDV_20170613T165043_33UUP_61_39_VV.tif
new file mode 100644
index 00000000000..53b3d36c053
Binary files /dev/null and b/tests/data/bigearthnetV2/BigEarthNet-S1/S1A_IW_GRDH_1SDV_20170613T165043/S1A_IW_GRDH_1SDV_20170613T165043_33UUP_61_39/S1A_IW_GRDH_1SDV_20170613T165043_33UUP_61_39_VV.tif differ
diff --git a/tests/data/bigearthnetV2/BigEarthNet-S1/S1A_IW_GRDH_1SDV_20170614T165154/S1A_IW_GRDH_1SDV_20170614T165154_32TQT_71_84/S1A_IW_GRDH_1SDV_20170614T165154_32TQT_71_84_VH.tif b/tests/data/bigearthnetV2/BigEarthNet-S1/S1A_IW_GRDH_1SDV_20170614T165154/S1A_IW_GRDH_1SDV_20170614T165154_32TQT_71_84/S1A_IW_GRDH_1SDV_20170614T165154_32TQT_71_84_VH.tif
new file mode 100644
index 00000000000..06a96d6a08a
Binary files /dev/null and b/tests/data/bigearthnetV2/BigEarthNet-S1/S1A_IW_GRDH_1SDV_20170614T165154/S1A_IW_GRDH_1SDV_20170614T165154_32TQT_71_84/S1A_IW_GRDH_1SDV_20170614T165154_32TQT_71_84_VH.tif differ
diff --git a/tests/data/bigearthnetV2/BigEarthNet-S1/S1A_IW_GRDH_1SDV_20170614T165154/S1A_IW_GRDH_1SDV_20170614T165154_32TQT_71_84/S1A_IW_GRDH_1SDV_20170614T165154_32TQT_71_84_VV.tif b/tests/data/bigearthnetV2/BigEarthNet-S1/S1A_IW_GRDH_1SDV_20170614T165154/S1A_IW_GRDH_1SDV_20170614T165154_32TQT_71_84/S1A_IW_GRDH_1SDV_20170614T165154_32TQT_71_84_VV.tif
new file mode 100644
index 00000000000..d66971038ca
Binary files /dev/null and b/tests/data/bigearthnetV2/BigEarthNet-S1/S1A_IW_GRDH_1SDV_20170614T165154/S1A_IW_GRDH_1SDV_20170614T165154_32TQT_71_84/S1A_IW_GRDH_1SDV_20170614T165154_32TQT_71_84_VV.tif differ
diff --git a/tests/data/bigearthnetV2/BigEarthNet-S1/S1A_IW_GRDH_1SDV_20170615T170156/S1A_IW_GRDH_1SDV_20170615T170156_32TNS_77_12/S1A_IW_GRDH_1SDV_20170615T170156_32TNS_77_12_VH.tif b/tests/data/bigearthnetV2/BigEarthNet-S1/S1A_IW_GRDH_1SDV_20170615T170156/S1A_IW_GRDH_1SDV_20170615T170156_32TNS_77_12/S1A_IW_GRDH_1SDV_20170615T170156_32TNS_77_12_VH.tif
new file mode 100644
index 00000000000..e03c3e9faec
Binary files /dev/null and b/tests/data/bigearthnetV2/BigEarthNet-S1/S1A_IW_GRDH_1SDV_20170615T170156/S1A_IW_GRDH_1SDV_20170615T170156_32TNS_77_12/S1A_IW_GRDH_1SDV_20170615T170156_32TNS_77_12_VH.tif differ
diff --git a/tests/data/bigearthnetV2/BigEarthNet-S1/S1A_IW_GRDH_1SDV_20170615T170156/S1A_IW_GRDH_1SDV_20170615T170156_32TNS_77_12/S1A_IW_GRDH_1SDV_20170615T170156_32TNS_77_12_VV.tif b/tests/data/bigearthnetV2/BigEarthNet-S1/S1A_IW_GRDH_1SDV_20170615T170156/S1A_IW_GRDH_1SDV_20170615T170156_32TNS_77_12/S1A_IW_GRDH_1SDV_20170615T170156_32TNS_77_12_VV.tif
new file mode 100644
index 00000000000..7d64ca1e0be
Binary files /dev/null and b/tests/data/bigearthnetV2/BigEarthNet-S1/S1A_IW_GRDH_1SDV_20170615T170156/S1A_IW_GRDH_1SDV_20170615T170156_32TNS_77_12/S1A_IW_GRDH_1SDV_20170615T170156_32TNS_77_12_VV.tif differ
diff --git a/tests/data/bigearthnetV2/BigEarthNet-S1/S1A_IW_GRDH_1SDV_20170618T165722/S1A_IW_GRDH_1SDV_20170618T165722_32TQR_92_45/S1A_IW_GRDH_1SDV_20170618T165722_32TQR_92_45_VH.tif b/tests/data/bigearthnetV2/BigEarthNet-S1/S1A_IW_GRDH_1SDV_20170618T165722/S1A_IW_GRDH_1SDV_20170618T165722_32TQR_92_45/S1A_IW_GRDH_1SDV_20170618T165722_32TQR_92_45_VH.tif
new file mode 100644
index 00000000000..b561b09c2b0
Binary files /dev/null and b/tests/data/bigearthnetV2/BigEarthNet-S1/S1A_IW_GRDH_1SDV_20170618T165722/S1A_IW_GRDH_1SDV_20170618T165722_32TQR_92_45/S1A_IW_GRDH_1SDV_20170618T165722_32TQR_92_45_VH.tif differ
diff --git a/tests/data/bigearthnetV2/BigEarthNet-S1/S1A_IW_GRDH_1SDV_20170618T165722/S1A_IW_GRDH_1SDV_20170618T165722_32TQR_92_45/S1A_IW_GRDH_1SDV_20170618T165722_32TQR_92_45_VV.tif b/tests/data/bigearthnetV2/BigEarthNet-S1/S1A_IW_GRDH_1SDV_20170618T165722/S1A_IW_GRDH_1SDV_20170618T165722_32TQR_92_45/S1A_IW_GRDH_1SDV_20170618T165722_32TQR_92_45_VV.tif
new file mode 100644
index 00000000000..2314e8f92f8
Binary files /dev/null and b/tests/data/bigearthnetV2/BigEarthNet-S1/S1A_IW_GRDH_1SDV_20170618T165722/S1A_IW_GRDH_1SDV_20170618T165722_32TQR_92_45/S1A_IW_GRDH_1SDV_20170618T165722_32TQR_92_45_VV.tif differ
diff --git a/tests/data/bigearthnetV2/BigEarthNet-S2.tar.zst b/tests/data/bigearthnetV2/BigEarthNet-S2.tar.zst
new file mode 100644
index 00000000000..7b15a9672d4
Binary files /dev/null and b/tests/data/bigearthnetV2/BigEarthNet-S2.tar.zst differ
diff --git a/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57_B01.tif b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57_B01.tif
new file mode 100644
index 00000000000..d68892d0d22
Binary files /dev/null and b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57_B01.tif differ
diff --git a/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57_B02.tif b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57_B02.tif
new file mode 100644
index 00000000000..586afd4c168
Binary files /dev/null and b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57_B02.tif differ
diff --git a/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57_B03.tif b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57_B03.tif
new file mode 100644
index 00000000000..6bd560eb2b9
Binary files /dev/null and b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57_B03.tif differ
diff --git a/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57_B04.tif b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57_B04.tif
new file mode 100644
index 00000000000..1ec75d76018
Binary files /dev/null and b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57_B04.tif differ
diff --git a/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57_B05.tif b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57_B05.tif
new file mode 100644
index 00000000000..806e4ee556b
Binary files /dev/null and b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57_B05.tif differ
diff --git a/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57_B06.tif b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57_B06.tif
new file mode 100644
index 00000000000..daf323ba28e
Binary files /dev/null and b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57_B06.tif differ
diff --git a/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57_B07.tif b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57_B07.tif
new file mode 100644
index 00000000000..ad5faaad2a5
Binary files /dev/null and b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57_B07.tif differ
diff --git a/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57_B08.tif b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57_B08.tif
new file mode 100644
index 00000000000..ff40bc9628a
Binary files /dev/null and b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57_B08.tif differ
diff --git a/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57_B09.tif b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57_B09.tif
new file mode 100644
index 00000000000..e7ab05bc8bb
Binary files /dev/null and b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57_B09.tif differ
diff --git a/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57_B11.tif b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57_B11.tif
new file mode 100644
index 00000000000..78be0517361
Binary files /dev/null and b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57_B11.tif differ
diff --git a/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57_B12.tif b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57_B12.tif
new file mode 100644
index 00000000000..175e45f4a53
Binary files /dev/null and b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57_B12.tif differ
diff --git a/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57_B8A.tif b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57_B8A.tif
new file mode 100644
index 00000000000..abc7f2eb7b5
Binary files /dev/null and b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57_B8A.tif differ
diff --git a/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38_B01.tif b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38_B01.tif
new file mode 100644
index 00000000000..a78067737be
Binary files /dev/null and b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38_B01.tif differ
diff --git a/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38_B02.tif b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38_B02.tif
new file mode 100644
index 00000000000..cdb7563cfaf
Binary files /dev/null and b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38_B02.tif differ
diff --git a/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38_B03.tif b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38_B03.tif
new file mode 100644
index 00000000000..9e79bb8dfa0
Binary files /dev/null and b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38_B03.tif differ
diff --git a/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38_B04.tif b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38_B04.tif
new file mode 100644
index 00000000000..e9e8b51b11e
Binary files /dev/null and b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38_B04.tif differ
diff --git a/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38_B05.tif b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38_B05.tif
new file mode 100644
index 00000000000..36340de20b4
Binary files /dev/null and b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38_B05.tif differ
diff --git a/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38_B06.tif b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38_B06.tif
new file mode 100644
index 00000000000..e5857927408
Binary files /dev/null and b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38_B06.tif differ
diff --git a/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38_B07.tif b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38_B07.tif
new file mode 100644
index 00000000000..7f32e548b8d
Binary files /dev/null and b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38_B07.tif differ
diff --git a/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38_B08.tif b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38_B08.tif
new file mode 100644
index 00000000000..d17482a21c9
Binary files /dev/null and b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38_B08.tif differ
diff --git a/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38_B09.tif b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38_B09.tif
new file mode 100644
index 00000000000..aa41ecddedd
Binary files /dev/null and b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38_B09.tif differ
diff --git a/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38_B11.tif b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38_B11.tif
new file mode 100644
index 00000000000..84f151a14b9
Binary files /dev/null and b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38_B11.tif differ
diff --git a/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38_B12.tif b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38_B12.tif
new file mode 100644
index 00000000000..cccff155375
Binary files /dev/null and b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38_B12.tif differ
diff --git a/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38_B8A.tif b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38_B8A.tif
new file mode 100644
index 00000000000..caecde996b4
Binary files /dev/null and b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38_B8A.tif differ
diff --git a/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34_B01.tif b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34_B01.tif
new file mode 100644
index 00000000000..ea47f6dab79
Binary files /dev/null and b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34_B01.tif differ
diff --git a/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34_B02.tif b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34_B02.tif
new file mode 100644
index 00000000000..3f4defd893c
Binary files /dev/null and b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34_B02.tif differ
diff --git a/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34_B03.tif b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34_B03.tif
new file mode 100644
index 00000000000..42dd524a5e2
Binary files /dev/null and b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34_B03.tif differ
diff --git a/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34_B04.tif b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34_B04.tif
new file mode 100644
index 00000000000..13c8b832de2
Binary files /dev/null and b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34_B04.tif differ
diff --git a/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34_B05.tif b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34_B05.tif
new file mode 100644
index 00000000000..2bfc07f289e
Binary files /dev/null and b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34_B05.tif differ
diff --git a/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34_B06.tif b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34_B06.tif
new file mode 100644
index 00000000000..08341debb66
Binary files /dev/null and b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34_B06.tif differ
diff --git a/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34_B07.tif b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34_B07.tif
new file mode 100644
index 00000000000..53956a81d6a
Binary files /dev/null and b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34_B07.tif differ
diff --git a/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34_B08.tif b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34_B08.tif
new file mode 100644
index 00000000000..2b1215fafe5
Binary files /dev/null and b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34_B08.tif differ
diff --git a/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34_B09.tif b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34_B09.tif
new file mode 100644
index 00000000000..f139167c437
Binary files /dev/null and b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34_B09.tif differ
diff --git a/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34_B11.tif b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34_B11.tif
new file mode 100644
index 00000000000..f71293a2579
Binary files /dev/null and b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34_B11.tif differ
diff --git a/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34_B12.tif b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34_B12.tif
new file mode 100644
index 00000000000..b7036883aae
Binary files /dev/null and b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34_B12.tif differ
diff --git a/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34_B8A.tif b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34_B8A.tif
new file mode 100644
index 00000000000..a8048e68cdd
Binary files /dev/null and b/tests/data/bigearthnetV2/BigEarthNet-S2/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34_B8A.tif differ
diff --git a/tests/data/bigearthnetV2/BigEarthNet-S2/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23_B01.tif b/tests/data/bigearthnetV2/BigEarthNet-S2/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23_B01.tif
new file mode 100644
index 00000000000..95caa6e48dd
Binary files /dev/null and b/tests/data/bigearthnetV2/BigEarthNet-S2/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23_B01.tif differ
diff --git a/tests/data/bigearthnetV2/BigEarthNet-S2/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23_B02.tif b/tests/data/bigearthnetV2/BigEarthNet-S2/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23_B02.tif
new file mode 100644
index 00000000000..aa4da5a6dc1
Binary files /dev/null and b/tests/data/bigearthnetV2/BigEarthNet-S2/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23_B02.tif differ
diff --git a/tests/data/bigearthnetV2/BigEarthNet-S2/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23_B03.tif b/tests/data/bigearthnetV2/BigEarthNet-S2/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23_B03.tif
new file mode 100644
index 00000000000..74d549e5ef1
Binary files /dev/null and b/tests/data/bigearthnetV2/BigEarthNet-S2/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23_B03.tif differ
diff --git a/tests/data/bigearthnetV2/BigEarthNet-S2/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23_B04.tif b/tests/data/bigearthnetV2/BigEarthNet-S2/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23_B04.tif
new file mode 100644
index 00000000000..513975a55ee
Binary files /dev/null and b/tests/data/bigearthnetV2/BigEarthNet-S2/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23_B04.tif differ
diff --git a/tests/data/bigearthnetV2/BigEarthNet-S2/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23_B05.tif b/tests/data/bigearthnetV2/BigEarthNet-S2/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23_B05.tif
new file mode 100644
index 00000000000..9fde4bb9abd
Binary files /dev/null and b/tests/data/bigearthnetV2/BigEarthNet-S2/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23_B05.tif differ
diff --git a/tests/data/bigearthnetV2/BigEarthNet-S2/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23_B06.tif b/tests/data/bigearthnetV2/BigEarthNet-S2/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23_B06.tif
new file mode 100644
index 00000000000..6de6e639274
Binary files /dev/null and b/tests/data/bigearthnetV2/BigEarthNet-S2/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23_B06.tif differ
diff --git a/tests/data/bigearthnetV2/BigEarthNet-S2/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23_B07.tif b/tests/data/bigearthnetV2/BigEarthNet-S2/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23_B07.tif
new file mode 100644
index 00000000000..80096189eac
Binary files /dev/null and b/tests/data/bigearthnetV2/BigEarthNet-S2/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23_B07.tif differ
diff --git a/tests/data/bigearthnetV2/BigEarthNet-S2/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23_B08.tif b/tests/data/bigearthnetV2/BigEarthNet-S2/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23_B08.tif
new file mode 100644
index 00000000000..aeab0e61489
Binary files /dev/null and b/tests/data/bigearthnetV2/BigEarthNet-S2/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23_B08.tif differ
diff --git a/tests/data/bigearthnetV2/BigEarthNet-S2/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23_B09.tif b/tests/data/bigearthnetV2/BigEarthNet-S2/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23_B09.tif
new file mode 100644
index 00000000000..c3f4ff0ebb5
Binary files /dev/null and b/tests/data/bigearthnetV2/BigEarthNet-S2/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23_B09.tif differ
diff --git a/tests/data/bigearthnetV2/BigEarthNet-S2/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23_B11.tif b/tests/data/bigearthnetV2/BigEarthNet-S2/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23_B11.tif
new file mode 100644
index 00000000000..6abaf436f35
Binary files /dev/null and b/tests/data/bigearthnetV2/BigEarthNet-S2/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23_B11.tif differ
diff --git a/tests/data/bigearthnetV2/BigEarthNet-S2/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23_B12.tif b/tests/data/bigearthnetV2/BigEarthNet-S2/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23_B12.tif
new file mode 100644
index 00000000000..080a2afcd84
Binary files /dev/null and b/tests/data/bigearthnetV2/BigEarthNet-S2/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23_B12.tif differ
diff --git a/tests/data/bigearthnetV2/BigEarthNet-S2/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23_B8A.tif b/tests/data/bigearthnetV2/BigEarthNet-S2/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23_B8A.tif
new file mode 100644
index 00000000000..7f752e83a94
Binary files /dev/null and b/tests/data/bigearthnetV2/BigEarthNet-S2/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23_B8A.tif differ
diff --git a/tests/data/bigearthnetV2/Reference_Maps.tar.zst b/tests/data/bigearthnetV2/Reference_Maps.tar.zst
new file mode 100644
index 00000000000..ae01efbaed4
Binary files /dev/null and b/tests/data/bigearthnetV2/Reference_Maps.tar.zst differ
diff --git a/tests/data/bigearthnetV2/Reference_Maps/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57_reference_map.tif b/tests/data/bigearthnetV2/Reference_Maps/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57_reference_map.tif
new file mode 100644
index 00000000000..2e270dd1cf1
Binary files /dev/null and b/tests/data/bigearthnetV2/Reference_Maps/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57/S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57_reference_map.tif differ
diff --git a/tests/data/bigearthnetV2/Reference_Maps/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38_reference_map.tif b/tests/data/bigearthnetV2/Reference_Maps/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38_reference_map.tif
new file mode 100644
index 00000000000..09e8c38997d
Binary files /dev/null and b/tests/data/bigearthnetV2/Reference_Maps/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38/S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38_reference_map.tif differ
diff --git a/tests/data/bigearthnetV2/Reference_Maps/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34_reference_map.tif b/tests/data/bigearthnetV2/Reference_Maps/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34_reference_map.tif
new file mode 100644
index 00000000000..359004dd777
Binary files /dev/null and b/tests/data/bigearthnetV2/Reference_Maps/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34/S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34_reference_map.tif differ
diff --git a/tests/data/bigearthnetV2/Reference_Maps/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23_reference_map.tif b/tests/data/bigearthnetV2/Reference_Maps/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23_reference_map.tif
new file mode 100644
index 00000000000..7b92011fd00
Binary files /dev/null and b/tests/data/bigearthnetV2/Reference_Maps/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23/S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23_reference_map.tif differ
diff --git a/tests/data/bigearthnetV2/data.py b/tests/data/bigearthnetV2/data.py
new file mode 100644
index 00000000000..6222cbbe45f
--- /dev/null
+++ b/tests/data/bigearthnetV2/data.py
@@ -0,0 +1,233 @@
+#!/usr/bin/env python3
+
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License.
+
+import hashlib
+import os
+import shutil
+import tarfile
+from pathlib import Path
+
+import numpy as np
+import pandas as pd
+import rasterio
+import zstandard as zstd
+
+# Constants
+IMG_SIZE = 120
+ROOT_DIR = '.'
+
+# Sample patch definitions
+SAMPLE_PATCHES = [
+ {
+ 's2_name': 'S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP_26_57',
+ 's2_base': 'S2A_MSIL2A_20170613T101031_N9999_R022_T33UUP',
+ 's1_name': 'S1A_IW_GRDH_1SDV_20170613T165043_33UUP_61_39',
+ 's1_base': 'S1A_IW_GRDH_1SDV_20170613T165043',
+ 'split': 'train',
+ 'labels': [
+ 'Urban fabric',
+ 'Industrial or commercial units',
+ 'Complex cultivation patterns',
+ ],
+ },
+ {
+ 's2_name': 'S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT_45_38',
+ 's2_base': 'S2A_MSIL2A_20170614T102021_N9999_R122_T32TQT',
+ 's1_name': 'S1A_IW_GRDH_1SDV_20170614T165154_32TQT_71_84',
+ 's1_base': 'S1A_IW_GRDH_1SDV_20170614T165154',
+ 'split': 'train',
+ 'labels': [
+ 'Broad-leaved forest',
+ 'Mixed forest',
+ 'Transitional woodland, shrub',
+ ],
+ },
+ {
+ 's2_name': 'S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS_45_23',
+ 's2_base': 'S2B_MSIL2A_20170615T102019_N9999_R122_T32TNS',
+ 's1_name': 'S1A_IW_GRDH_1SDV_20170615T170156_32TNS_77_12',
+ 's1_base': 'S1A_IW_GRDH_1SDV_20170615T170156',
+ 'split': 'val',
+ 'labels': ['Arable land', 'Pastures', 'Inland waters'],
+ },
+ {
+ 's2_name': 'S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR_89_34',
+ 's2_base': 'S2A_MSIL2A_20170618T101021_N9999_R022_T32TQR',
+ 's1_name': 'S1A_IW_GRDH_1SDV_20170618T165722_32TQR_92_45',
+ 's1_base': 'S1A_IW_GRDH_1SDV_20170618T165722',
+ 'split': 'test',
+ 'labels': [
+ 'Coniferous forest',
+ 'Natural grassland and sparsely vegetated areas',
+ ],
+ },
+]
+
+LABEL_TO_CLC = {
+ 'Urban fabric': 111,
+ 'Industrial or commercial units': 121,
+ 'Arable land': 211,
+ 'Permanent crops': 221,
+ 'Pastures': 231,
+ 'Complex cultivation patterns': 242,
+ 'Land principally occupied by agriculture, with significant areas of natural vegetation': 243,
+ 'Agro-forestry areas': 244,
+ 'Broad-leaved forest': 311,
+ 'Coniferous forest': 312,
+ 'Mixed forest': 313,
+ 'Natural grassland and sparsely vegetated areas': 321,
+ 'Moors, heathland and sclerophyllous vegetation': 322,
+ 'Transitional woodland, shrub': 324,
+ 'Beaches, dunes, sands': 331,
+ 'Inland wetlands': 411,
+ 'Coastal wetlands': 421,
+ 'Inland waters': 511,
+ 'Marine waters': 523,
+}
+
+S1_BANDS = ['VV', 'VH']
+S2_BANDS = [
+ 'B01',
+ 'B02',
+ 'B03',
+ 'B04',
+ 'B05',
+ 'B06',
+ 'B07',
+ 'B08',
+ 'B8A',
+ 'B09',
+ 'B11',
+ 'B12',
+]
+
+
+def create_directory_structure() -> None:
+ """Create the base directory structure"""
+
+ for dir_name in ['BigEarthNet-S1', 'BigEarthNet-S2', 'Reference_Maps']:
+ if os.path.exists(os.path.join(ROOT_DIR, dir_name)):
+ shutil.rmtree(os.path.join(ROOT_DIR, dir_name))
+ Path(os.path.join(ROOT_DIR, dir_name)).mkdir(parents=True, exist_ok=True)
+
+
+def create_dummy_image(
+ path: str, shape: tuple[int, int], dtype: str, labels: list[str] | None = None
+) -> None:
+ """Create a dummy GeoTIFF file"""
+ if dtype == 's1':
+ data = np.random.randint(-25, 0, shape).astype(np.int16)
+ elif dtype == 's2':
+ data = np.random.randint(0, 10000, shape).astype(np.int16)
+ else: # reference map
+ clc_codes = [LABEL_TO_CLC[label] for label in labels]
+ data = np.random.choice(clc_codes, size=shape).astype(np.uint16)
+
+ with rasterio.open(
+ path,
+ 'w',
+ driver='GTiff',
+ height=shape[0],
+ width=shape[1],
+ count=1,
+ dtype=data.dtype,
+ crs='+proj=utm +zone=32 +datum=WGS84 +units=m +no_defs',
+ transform=rasterio.transform.from_origin(0, 0, 10, 10),
+ ) as dst:
+ dst.write(data, 1)
+
+
+def generate_sample(patch_info: dict) -> None:
+ """Generate a complete sample with S1, S2 and reference data"""
+ # Create S1 data
+ s1_dir = os.path.join(
+ ROOT_DIR, 'BigEarthNet-S1', patch_info['s1_base'], patch_info['s1_name']
+ )
+ os.makedirs(s1_dir, exist_ok=True)
+
+ for band in S1_BANDS:
+ path = os.path.join(s1_dir, f'{patch_info["s1_name"]}_{band}.tif')
+ create_dummy_image(path, (IMG_SIZE, IMG_SIZE), 's1')
+
+ # Create S2 data
+ s2_dir = os.path.join(
+ ROOT_DIR, 'BigEarthNet-S2', patch_info['s2_base'], patch_info['s2_name']
+ )
+ os.makedirs(s2_dir, exist_ok=True)
+
+ for band in S2_BANDS:
+ path = os.path.join(s2_dir, f'{patch_info["s2_name"]}_{band}.tif')
+ create_dummy_image(path, (IMG_SIZE, IMG_SIZE), 's2')
+
+ # Create reference map
+ ref_dir = os.path.join(
+ ROOT_DIR, 'Reference_Maps', patch_info['s2_base'], patch_info['s2_name']
+ )
+ os.makedirs(ref_dir, exist_ok=True)
+
+ path = os.path.join(ref_dir, f'{patch_info["s2_name"]}_reference_map.tif')
+ create_dummy_image(
+ path, (IMG_SIZE, IMG_SIZE), 'reference', labels=patch_info['labels']
+ )
+
+
+def create_metadata() -> None:
+ """Create metadata parquet file"""
+ records = []
+
+ for patch in SAMPLE_PATCHES:
+ records.append(
+ {
+ 'patch_id': patch['s2_name'],
+ 's1_name': patch['s1_name'],
+ 'split': patch['split'],
+ 'labels': patch['labels'],
+ }
+ )
+
+ df = pd.DataFrame.from_records(records)
+ df.to_parquet(os.path.join(ROOT_DIR, 'metadata.parquet'))
+
+
+def compress_directory(dirname: str) -> None:
+ """Compress directory using tar+zstd"""
+ tar_path = os.path.join(ROOT_DIR, f'{dirname}.tar')
+ with tarfile.open(tar_path, 'w') as tar:
+ tar.add(os.path.join(ROOT_DIR, dirname), arcname=dirname)
+
+ with open(tar_path, 'rb') as f_in:
+ data = f_in.read()
+ cctx = zstd.ZstdCompressor()
+ compressed = cctx.compress(data)
+ with open(f'{tar_path}.zst', 'wb') as f_out:
+ f_out.write(compressed)
+
+ os.remove(tar_path)
+
+ # print md5sum with hashlib
+ hash_md5 = hashlib.md5()
+ with open(f'{tar_path}.zst', 'rb') as f:
+ for chunk in iter(lambda: f.read(4096), b''):
+ hash_md5.update(chunk)
+
+ print(f'{tar_path}.zst: {hash_md5.hexdigest()}')
+
+
+def main() -> None:
+ # Create directories and generate data
+ create_directory_structure()
+
+ for patch_info in SAMPLE_PATCHES:
+ generate_sample(patch_info)
+
+ create_metadata()
+
+ # Compress directories
+ for dirname in ['BigEarthNet-S1', 'BigEarthNet-S2', 'Reference_Maps']:
+ compress_directory(dirname)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/tests/data/bigearthnetV2/metadata.parquet b/tests/data/bigearthnetV2/metadata.parquet
new file mode 100644
index 00000000000..7fa48f0c23f
Binary files /dev/null and b/tests/data/bigearthnetV2/metadata.parquet differ
diff --git a/tests/datasets/test_bigearthnet.py b/tests/datasets/test_bigearthnet.py
index c93240e21f1..a8a1c7430b3 100644
--- a/tests/datasets/test_bigearthnet.py
+++ b/tests/datasets/test_bigearthnet.py
@@ -12,7 +12,9 @@
from _pytest.fixtures import SubRequest
from pytest import MonkeyPatch
-from torchgeo.datasets import BigEarthNet, DatasetNotFoundError
+from torchgeo.datasets import BigEarthNet, BigEarthNetV2, DatasetNotFoundError
+
+pytest.importorskip('zstandard', minversion='0.23')
class TestBigEarthNet:
@@ -140,3 +142,142 @@ def test_plot(self, dataset: BigEarthNet) -> None:
x['prediction'] = x['label'].clone()
dataset.plot(x)
plt.close()
+
+
+class TestBigEarthNetV2:
+ @pytest.fixture(params=zip(['all', 's1', 's2'], ['train', 'val', 'test']))
+ def dataset(
+ self, monkeypatch: MonkeyPatch, tmp_path: Path, request: SubRequest
+ ) -> BigEarthNetV2:
+ data_dir = os.path.join('tests', 'data', 'bigearthnetV2')
+ metadata = {
+ 's1': {
+ 'url': os.path.join(data_dir, 'BigEarthNet-S1.tar.zst'),
+ 'md5': '7c40abec6662bf1df4335e92a9caf5ab',
+ 'filename': 'BigEarthNet-S1.tar.zst',
+ 'directory': 'BigEarthNet-S1',
+ },
+ 's2': {
+ 'url': os.path.join(data_dir, 'BigEarthNet-S2.tar.zst'),
+ 'md5': '9a699ac4a8aade77ce53d35e198ba2d0',
+ 'filename': 'BigEarthNet-S2.tar.zst',
+ 'directory': 'BigEarthNet-S2',
+ },
+ 'maps': {
+ 'url': os.path.join(data_dir, 'Reference_Maps.tar.zst'),
+ 'md5': '1e4b2fdfb954594aa9465f4496defea6',
+ 'filename': 'Reference_Maps.tar.zst',
+ 'directory': 'Reference_Maps',
+ },
+ 'metadata': {
+ 'url': os.path.join(data_dir, 'metadata.parquet'),
+ 'md5': 'ad100d6b020f2e693673f77ebbe57891',
+ 'filename': 'metadata.parquet',
+ },
+ }
+ monkeypatch.setattr(BigEarthNetV2, 'metadata_locs', metadata)
+
+ bands, split = request.param
+
+ root = tmp_path
+ transforms = nn.Identity()
+ return BigEarthNetV2(
+ root, split, bands, transforms, download=True, checksum=True
+ )
+
+ def test_getitem(self, dataset: BigEarthNetV2) -> None:
+ """Test loading data."""
+ x = dataset[0]
+
+ if dataset.bands in ['s2', 'all']:
+ if dataset.bands == 's2':
+ assert x['image'].shape == (12, 120, 120)
+ else:
+ assert x['image_s2'].shape == (12, 120, 120)
+
+ if dataset.bands in ['s1', 'all']:
+ if dataset.bands == 's1':
+ assert x['image'].shape == (2, 120, 120)
+ else:
+ assert x['image_s1'].shape == (2, 120, 120)
+
+ assert x['mask'].shape == (1, 120, 120)
+
+ assert x['mask'].dtype == torch.int64
+ assert x['label'].dtype == torch.int64
+ if 'image' in x:
+ assert x['image'].dtype == torch.float32
+ if 'image_s1' in x:
+ assert x['image_s1'].dtype == torch.float32
+ if 'image_s2' in x:
+ assert x['image_s2'].dtype == torch.float32
+
+ def test_len(self, dataset: BigEarthNetV2) -> None:
+ """Test dataset length."""
+ if dataset.split == 'train':
+ assert len(dataset) == 2
+ else:
+ assert len(dataset) == 1
+
+ def test_already_downloaded(self, dataset: BigEarthNetV2, tmp_path: Path) -> None:
+ BigEarthNetV2(
+ root=tmp_path, bands=dataset.bands, split=dataset.split, download=True
+ )
+
+ def test_not_downloaded(self, tmp_path: Path) -> None:
+ """Test error handling when data not present."""
+ with pytest.raises(DatasetNotFoundError, match='Dataset not found'):
+ BigEarthNetV2(tmp_path)
+
+ def test_already_downloaded_not_extracted(
+ self, dataset: BigEarthNetV2, tmp_path: Path
+ ) -> None:
+ shutil.copy(dataset.metadata_locs['metadata']['url'], tmp_path)
+ if dataset.bands == 'all':
+ shutil.rmtree(
+ os.path.join(dataset.root, dataset.metadata_locs['s1']['directory'])
+ )
+ shutil.rmtree(
+ os.path.join(dataset.root, dataset.metadata_locs['s2']['directory'])
+ )
+ shutil.copy(dataset.metadata_locs['s1']['url'], tmp_path)
+ shutil.copy(dataset.metadata_locs['s2']['url'], tmp_path)
+ elif dataset.bands == 's1':
+ shutil.rmtree(
+ os.path.join(dataset.root, dataset.metadata_locs['s1']['directory'])
+ )
+ shutil.copy(dataset.metadata_locs['s1']['url'], tmp_path)
+ else:
+ shutil.rmtree(
+ os.path.join(dataset.root, dataset.metadata_locs['s2']['directory'])
+ )
+ shutil.copy(dataset.metadata_locs['s2']['url'], tmp_path)
+
+ BigEarthNetV2(
+ root=tmp_path, bands=dataset.bands, split=dataset.split, download=False
+ )
+
+ def test_invalid_split(self, tmp_path: Path) -> None:
+ """Test error on invalid split."""
+ with pytest.raises(AssertionError, match='split must be one of'):
+ BigEarthNetV2(tmp_path, split='invalid')
+
+ def test_invalid_bands(self, tmp_path: Path) -> None:
+ """Test error on invalid bands selection."""
+ with pytest.raises(AssertionError):
+ BigEarthNetV2(tmp_path, bands='invalid')
+
+ def test_plot(self, dataset: BigEarthNetV2) -> None:
+ """Test plotting functionality."""
+ x = dataset[0].copy()
+ dataset.plot(x, suptitle='Test')
+ plt.close()
+
+ # Test without titles
+ dataset.plot(x, show_titles=False)
+ plt.close()
+
+ # Test with prediction
+ x['prediction'] = x['label'].clone()
+ dataset.plot(x)
+ plt.close()
diff --git a/torchgeo/datasets/__init__.py b/torchgeo/datasets/__init__.py
index 8f238abd916..a3b5fa01ab5 100644
--- a/torchgeo/datasets/__init__.py
+++ b/torchgeo/datasets/__init__.py
@@ -9,7 +9,7 @@
from .airphen import Airphen
from .astergdem import AsterGDEM
from .benin_cashews import BeninSmallHolderCashews
-from .bigearthnet import BigEarthNet
+from .bigearthnet import BigEarthNet, BigEarthNetV2
from .biomassters import BioMassters
from .cabuar import CaBuAr
from .caffe import CaFFe
@@ -181,6 +181,7 @@
'AsterGDEM',
'BeninSmallHolderCashews',
'BigEarthNet',
+ 'BigEarthNetV2',
'BioMassters',
'BoundingBox',
'CMSGlobalMangroveCanopy',
diff --git a/torchgeo/datasets/bigearthnet.py b/torchgeo/datasets/bigearthnet.py
index ef62ac1a280..da0d1f6ef1c 100644
--- a/torchgeo/datasets/bigearthnet.py
+++ b/torchgeo/datasets/bigearthnet.py
@@ -6,20 +6,32 @@
import glob
import json
import os
+import tarfile
+import tempfile
+import textwrap
from collections.abc import Callable
from typing import ClassVar
import matplotlib.pyplot as plt
import numpy as np
+import pandas as pd
import rasterio
import torch
+from matplotlib.colors import BoundaryNorm, ListedColormap
from matplotlib.figure import Figure
+from matplotlib.patches import Rectangle
from rasterio.enums import Resampling
from torch import Tensor
from .errors import DatasetNotFoundError
from .geo import NonGeoDataset
-from .utils import Path, download_url, extract_archive, sort_sentinel2_bands
+from .utils import (
+ Path,
+ download_url,
+ extract_archive,
+ lazy_import,
+ sort_sentinel2_bands,
+)
class BigEarthNet(NonGeoDataset):
@@ -573,3 +585,441 @@ def plot(
if suptitle is not None:
plt.suptitle(suptitle)
return fig
+
+
+class BigEarthNetV2(NonGeoDataset):
+ """BigEarthNetV2 dataset.
+
+ The `BigEarthNet V2 `__ dataset contains improved labels, improved
+ geospatial data splits and additionally pixel-level labels from CORINE Land
+ Cover (CLC) map of 2018. Additionally, some probelmatic patches from V1 have been removed.
+
+ .. note::
+
+ This dataset rquires the following additional library to automatically decompress the files:
+
+ * `zstandard `__
+
+ .. versionadded:: 0.7
+ """
+
+ class_set = BigEarthNet.class_sets[19]
+
+ image_size = BigEarthNet.image_size
+
+ metadata_locs: ClassVar[dict[str, dict[str, str]]] = {
+ 's1': {
+ 'url': 'https://zenodo.org/records/10891137/files/BigEarthNet-S1.tar.zst',
+ 'md5': 'a55eaa2cdf6a917e296bd6601ec1e348',
+ 'filename': 'BigEarthNet-S1.tar.zst',
+ 'directory': 'BigEarthNet-S1',
+ },
+ 's2': {
+ 'url': 'https://zenodo.org/records/10891137/files/BigEarthNet-S2.tar.zst',
+ 'md5': '2245ed2d1a93f6ce637d839bc856396e',
+ 'filename': 'BigEarthNet-S2.tar.zst',
+ 'directory': 'BigEarthNet-S2',
+ },
+ 'maps': {
+ 'url': 'https://zenodo.org/records/10891137/files/Reference_Maps.tar.zst',
+ 'md5': '95d85a222fa983faddcac51a19f28917',
+ 'filename': 'Reference_Maps.zst',
+ 'directory': 'Reference_Maps',
+ },
+ 'metadata': {
+ 'url': 'https://zenodo.org/records/10891137/files/metadata.parquet',
+ 'md5': 'b2d7b4b2e6c7c7d8f3f5b8f3c5a8f3b1',
+ 'filename': 'metadata.parquet',
+ 'directory': '',
+ },
+ }
+
+ # https://collections.sentinel-hub.com/corine-land-cover/readme.html
+ # Table 1 of https://bigearth.net/static/documents/Description_BigEarthNet_v2.pdf
+ clc_colors: ClassVar[dict[str, str]] = {
+ 'Urban fabric': '#e6004d',
+ 'Industrial or commercial units': '#cc4df2',
+ 'Arable land': '#ffffa8',
+ 'Permanent crops': '#e68000',
+ 'Pastures': '#e6e64d',
+ 'Complex cultivation patterns': '#ffe64d',
+ 'Land principally occupied by agriculture, with significant areas of natural vegetation': '#e6cc4d',
+ 'Agro-forestry areas': '#f2cca6',
+ 'Broad-leaved forest': '#80ff00',
+ 'Coniferous forest': '#00a600',
+ 'Mixed forest': '#4dff00',
+ 'Natural grassland and sparsely vegetated areas': '#ccf24d',
+ 'Moors, heathland and sclerophyllous vegetation': '#a6ff80',
+ 'Transitional woodland, shrub': '#a6f200',
+ 'Beaches, dunes, sands': '#e6e6e6',
+ 'Inland wetlands': '#a6a6ff',
+ 'Coastal wetlands': '#ccccff',
+ 'Inland waters': '#80f2e6',
+ 'Marine waters': '#e6f2ff',
+ }
+
+ clc_codes: ClassVar[dict[int, int]] = {
+ 111: 0, # Continuous Urban fabric
+ 112: 0, # Discontinuous Urban fabric
+ 121: 1, # Industrial or commercial units
+ 211: 2, # Non-irrigated arable land
+ 212: 2, # Permanently irrigated land
+ 213: 2, # Rice fields
+ 221: 3, # Vineyards
+ 222: 3, # Fruit trees and berry plantations
+ 223: 3, # Olive groves
+ 231: 4, # Pastures
+ 241: 3, # Annual crops with permanent crops
+ 242: 5, # Complex cultivation patterns
+ 243: 6, # Land principally occupied by agriculture...
+ 244: 7, # Agro-forestry areas
+ 311: 8, # Broad-leaved forest
+ 312: 9, # Coniferous forest
+ 313: 10, # Mixed forest
+ 321: 11, # Natural grassland
+ 322: 12, # Moors and heathland
+ 323: 12, # Sclerophyllous vegetation
+ 324: 13, # Transitional woodland/shrub
+ 331: 14, # Beaches, dunes, sands
+ 333: 11, # Sparsely vegetated areas
+ 411: 15, # Inland marshes
+ 412: 15, # Peatbogs
+ 421: 16, # Salt marshes
+ 422: 16, # Salines
+ 511: 17, # Water courses
+ 512: 17, # Water bodies
+ 521: 18, # Coastal lagoons
+ 522: 18, # Estuaries
+ 523: 18, # Sea and ocean
+ }
+
+ valid_splits = ('train', 'val', 'test')
+
+ def __init__(
+ self,
+ root: Path = 'data',
+ split: str = 'train',
+ bands: str = 'all',
+ transforms: Callable[[dict[str, Tensor]], dict[str, Tensor]] | None = None,
+ download: bool = False,
+ checksum: bool = False,
+ ) -> None:
+ """Initialize a new BigEarthNet V2 dataset instance.
+
+ Args:
+ root: root directory where dataset can be found
+ split: train/val/test split to load
+ bands: load Sentinel-1 bands, Sentinel-2, or both. one of {s1, s2, all}
+ transforms: a function/transform that takes input sample and its target as
+ entry and returns a transformed version
+ download: if True, download dataset and store it in the root directory
+ checksum: if True, check the MD5 of the downloaded files (may be slow)
+
+ Raises:
+ DatasetNotFoundError: If dataset is not found and *download* is False.
+ AssertionError: If *split*, or *bands*, are not valid.
+ """
+ lazy_import('zstandard')
+ assert split in self.valid_splits, f'split must be one of {self.valid_splits}'
+ assert bands in ['s1', 's2', 'all']
+ self.root = root
+ self.split = split
+ self.bands = bands
+ self.transforms = transforms
+ self.num_classes = 19
+ self.download = download
+ self.checksum = checksum
+ self.class2idx = {c: i for i, c in enumerate(self.class_set)}
+ self._verify()
+
+ self.metadata_df = pd.read_parquet(os.path.join(self.root, 'metadata.parquet'))
+ self.metadata_df = self.metadata_df[
+ self.metadata_df['split'] == self.split
+ ].reset_index(drop=True)
+
+ # Map chosen classes to ordinal numbers, all others mapped to background class
+ self.ordinal_map = torch.zeros(19)
+ for corine, ordinal in self.clc_codes.items():
+ self.ordinal_map[ordinal] = corine
+
+ def __len__(self) -> int:
+ """Return the number of data points in the dataset.
+
+ Returns:
+ length of the dataset
+ """
+ return len(self.metadata_df)
+
+ def __getitem__(self, index: int) -> dict[str, Tensor]:
+ """Return an index within the dataset.
+
+ Args:
+ index: index to return
+
+ Returns:
+ data and label at that index
+ """
+ sample: dict[str, Tensor] = {}
+
+ match self.bands:
+ case 's1':
+ sample['image'] = self._load_image(index, 's1')
+ case 's2':
+ sample['image'] = self._load_image(index, 's2')
+ case 'all':
+ sample['image_s1'] = self._load_image(index, 's1')
+ sample['image_s2'] = self._load_image(index, 's2')
+
+ sample['mask'] = self._load_map(index)
+ sample['label'] = self._load_target(index)
+
+ if self.transforms is not None:
+ sample = self.transforms(sample)
+
+ return sample
+
+ def _load_image(self, index: int, sensor: str) -> Tensor:
+ """Generic image loader for both S1 and S2.
+
+ Args:
+ index: index to return
+ sensor: 's1' or 's2'
+
+ Returns:
+ the sensor image
+ """
+ row = self.metadata_df.loc[index]
+ id_field = 's1_name' if sensor == 's1' else 'patch_id'
+ patch_id = row[id_field]
+ if sensor == 's2':
+ patch_dir = '_'.join(patch_id.split('_')[0:-2])
+ else:
+ patch_dir = '_'.join(patch_id.split('_')[0:-3])
+
+ paths = glob.glob(
+ os.path.join(
+ self.root,
+ self.metadata_locs[sensor]['directory'],
+ patch_dir,
+ patch_id,
+ '*.tif',
+ )
+ )
+
+ if sensor == 's2':
+ paths = sorted(paths, key=sort_sentinel2_bands)
+ else:
+ paths = sorted(paths)
+
+ images = []
+ for path in paths:
+ with rasterio.open(path) as dataset:
+ array = dataset.read(
+ indexes=1,
+ out_shape=self.image_size,
+ out_dtype='int32',
+ resampling=Resampling.bilinear,
+ )
+ images.append(array)
+
+ return torch.from_numpy(np.stack(images, axis=0)).float()
+
+ def _load_map(self, index: int) -> Tensor:
+ """Load a single image.
+
+ Args:
+ index: index to return
+
+ Returns:
+ the Corine Land Cover map
+ """
+ row = self.metadata_df.loc[index]
+ patch_id = row['patch_id']
+ patch_dir = '_'.join(patch_id.split('_')[0:-2])
+ path = os.path.join(
+ self.root,
+ self.metadata_locs['maps']['directory'],
+ patch_dir,
+ patch_id,
+ patch_id + '_reference_map.tif',
+ )
+ with rasterio.open(path) as dataset:
+ map = dataset.read(out_dtype='int32')
+
+ tensor = torch.from_numpy(map)
+ # remap to ordinal values
+ for corine, ordinal in self.clc_codes.items():
+ tensor[tensor == corine] = ordinal
+ return tensor.long()
+
+ def _load_target(self, index: int) -> Tensor:
+ """Load the target mask for a single image.
+
+ Args:
+ index: index to return
+
+ Returns:
+ the target label
+ """
+ label_names = self.metadata_df.iloc[index]['labels']
+
+ indices = [self.class2idx[label_names] for label_names in label_names]
+
+ image_target = torch.zeros(self.num_classes, dtype=torch.long)
+ image_target[indices] = 1
+ return image_target
+
+ def _verify(self) -> None:
+ """Verify the integrity of the dataset."""
+ exists = []
+ for key, metadata in self.metadata_locs.items():
+ if key != 'metadata':
+ exists.append(
+ os.path.exists(os.path.join(self.root, metadata['directory']))
+ )
+ else:
+ exists.append(
+ os.path.exists(os.path.join(self.root, metadata['filename']))
+ )
+
+ if all(exists):
+ return
+
+ # check if compressed files already exist
+ exists = []
+ for key, metadata in self.metadata_locs.items():
+ if os.path.exists(os.path.join(self.root, metadata['filename'])):
+ exists.append(True)
+ if key != 'metadata':
+ self._extract(os.path.join(self.root, metadata['filename']))
+ else:
+ exists.append(False)
+
+ if all(exists):
+ return
+
+ if not self.download:
+ raise DatasetNotFoundError(self)
+
+ for key, metadata in self.metadata_locs.items():
+ self._download(metadata['url'], metadata['filename'], metadata['md5'])
+ filepath = os.path.join(self.root, metadata['filename'])
+ if key != 'metadata':
+ self._extract(filepath)
+
+ def _download(self, url: str, filename: Path, md5: str) -> None:
+ """Download the dataset.
+
+ Args:
+ url: url to download file
+ filename: output filename to write downloaded file
+ md5: md5 of downloaded file
+ """
+ if not os.path.exists(os.path.join(self.root, filename)):
+ download_url(
+ url, self.root, filename=filename, md5=md5 if self.checksum else None
+ )
+
+ def _extract(self, filepath: Path) -> None:
+ """Extract the dataset.
+
+ Args:
+ filepath: path to file to be extracted
+ """
+ zstandard = lazy_import('zstandard')
+ if not str(filepath).endswith('.csv'):
+ dctx = zstandard.ZstdDecompressor()
+
+ with tempfile.TemporaryFile(suffix='.tar') as ofh:
+ with open(filepath, 'rb') as ifh:
+ dctx.copy_stream(ifh, ofh)
+ ofh.seek(0)
+ with tarfile.open(fileobj=ofh) as z:
+ z.extractall(self.root)
+
+ def plot(
+ self,
+ sample: dict[str, Tensor],
+ show_titles: bool = True,
+ suptitle: str | None = None,
+ ) -> Figure:
+ """Plot a sample from the dataset.
+
+ Args:
+ sample: a sample returned by :meth:`__getitem__`
+ show_titles: flag indicating whether to show titles above each panel
+ suptitle: optional string to use as a suptitle
+
+ Returns:
+ a matplotlib Figure with the rendered sample
+ """
+ fig, axes = plt.subplots(1, 2 if self.bands != 'all' else 3, figsize=(12, 4))
+
+ if self.bands in ['s2', 'all']:
+ s2_img = sample['image_s2' if self.bands == 'all' else 'image']
+ rgb = np.rollaxis(s2_img[[3, 2, 1]].numpy(), 0, 3)
+ axes[0].imshow(np.clip(rgb / 2000, 0, 1))
+ if show_titles:
+ axes[0].set_title('Sentinel-2 RGB')
+ axes[0].axis('off')
+
+ if self.bands in ['s1', 'all']:
+ idx = 0 if self.bands == 's1' else 1
+ s1_img = sample['image_s1' if self.bands == 'all' else 'image']
+ axes[idx].imshow(s1_img[0].numpy())
+ if show_titles:
+ axes[idx].set_title('Sentinel-1 VV')
+ axes[idx].axis('off')
+
+ # Handle mask plotting
+ mask_idx = 1 if self.bands != 'all' else 2
+ mask = sample['mask'][0].numpy()
+
+ # Get unique ordinal labels from mask
+ unique_labels = sorted(np.unique(mask))
+
+ # Map ordinal labels to class names and colors directly
+ colors = []
+ class_names = []
+ for label in unique_labels:
+ name = self.class_set[label] # Get class name from ordinal index
+ colors.append(self.clc_colors[name]) # Get color for class name
+ class_names.append(name)
+
+ # Create custom colormap
+ cmap = ListedColormap(colors)
+ bounds = [*unique_labels, unique_labels[-1] + 1]
+ norm = BoundaryNorm(bounds, len(colors))
+
+ axes[mask_idx].imshow(mask, cmap=cmap, norm=norm)
+
+ # Add legend with class names
+ legend_elements = [Rectangle((0, 0), 1, 1, facecolor=color) for color in colors]
+ wrapped_names = [textwrap.fill(name, width=25) for name in class_names]
+ axes[mask_idx].legend(
+ legend_elements,
+ wrapped_names,
+ loc='center left',
+ bbox_to_anchor=(1, 0.5),
+ fontsize='x-small',
+ )
+ axes[mask_idx].axis('off')
+
+ if show_titles:
+ axes[mask_idx].set_title('Land Cover Map')
+
+ if 'label' in sample:
+ label_indices = sample['label'].nonzero().squeeze(1).tolist()
+ label_names = [self.class_set[idx] for idx in label_indices]
+ if suptitle:
+ suptitle = f'{suptitle}\nLabels: {", ".join(label_names)}'
+ else:
+ suptitle = f'Labels: {", ".join(label_names)}'
+
+ if suptitle:
+ plt.suptitle(suptitle)
+
+ # Adjust layout to prevent overlap
+ plt.tight_layout()
+
+ return fig