From c7e6dbda56455cffcf3679948b385e37ef75a974 Mon Sep 17 00:00:00 2001 From: Ashwin Nair Date: Thu, 17 Nov 2022 10:29:52 +0400 Subject: [PATCH] Add SpaceNet6 & data.py (#878) * Add SpaceNet6 & data.py * For coverage * Added SpaceNet6 to docs * Cleanup * Docfix * Move importskip to module level Co-authored-by: Caleb Robinson --- docs/api/datasets.rst | 1 + tests/data/spacenet/data.py | 283 ++++++++++++++++++ tests/data/spacenet/sn1_AOI_1_RIO.tar.gz | Bin 1308 -> 1052 bytes tests/data/spacenet/sn2_AOI_2_Vegas.tar.gz | Bin 1174 -> 1149 bytes tests/data/spacenet/sn2_AOI_3_Paris.tar.gz | Bin 1074 -> 1182 bytes tests/data/spacenet/sn2_AOI_4_Shanghai.tar.gz | Bin 1090 -> 1175 bytes tests/data/spacenet/sn2_AOI_5_Khartoum.tar.gz | Bin 1084 -> 1191 bytes tests/data/spacenet/sn3_AOI_2_Vegas.tar.gz | Bin 0 -> 1324 bytes tests/data/spacenet/sn3_AOI_3_Paris.tar.gz | Bin 1176 -> 1314 bytes tests/data/spacenet/sn3_AOI_4_Shanghai.tar.gz | Bin 0 -> 1338 bytes tests/data/spacenet/sn3_AOI_5_Khartoum.tar.gz | Bin 1193 -> 1280 bytes tests/data/spacenet/sn4_AOI_6_Atlanta.tar.gz | Bin 1416 -> 1550 bytes tests/data/spacenet/sn5_AOI_7_Moscow.tar.gz | Bin 1313 -> 1332 bytes tests/data/spacenet/sn5_AOI_8_Mumbai.tar.gz | Bin 1507 -> 1457 bytes tests/data/spacenet/sn7_test_source.tar.gz | Bin 465 -> 818 bytes tests/data/spacenet/sn7_train_labels.tar.gz | Bin 561 -> 905 bytes tests/data/spacenet/sn7_train_source.tar.gz | Bin 507 -> 859 bytes .../sn6_AOI_11_Rotterdam/collection.json | 0 .../labels.geojson | 7 + .../sn6_AOI_11_Rotterdam_img1/PAN.tif | Bin 0 -> 374 bytes .../sn6_AOI_11_Rotterdam_img1/PS-RGB.tif | Bin 0 -> 414 bytes .../sn6_AOI_11_Rotterdam_img1/PS-RGBNIR.tif | Bin 0 -> 432 bytes .../sn6_AOI_11_Rotterdam_img1/RGBNIR.tif | Bin 0 -> 432 bytes .../SAR-Intensity.tif | Bin 0 -> 374 bytes .../labels.geojson | 7 + .../sn6_AOI_11_Rotterdam_img2/PAN.tif | Bin 0 -> 374 bytes .../sn6_AOI_11_Rotterdam_img2/PS-RGB.tif | Bin 0 -> 414 bytes .../sn6_AOI_11_Rotterdam_img2/PS-RGBNIR.tif | Bin 0 -> 432 bytes .../sn6_AOI_11_Rotterdam_img2/RGBNIR.tif | Bin 0 -> 432 bytes .../SAR-Intensity.tif | Bin 0 -> 374 bytes tests/datasets/test_spacenet.py | 93 ++++-- torchgeo/datasets/__init__.py | 2 + torchgeo/datasets/spacenet.py | 193 +++++++++--- 33 files changed, 523 insertions(+), 63 deletions(-) create mode 100644 tests/data/spacenet/data.py create mode 100644 tests/data/spacenet/sn3_AOI_2_Vegas.tar.gz create mode 100644 tests/data/spacenet/sn3_AOI_4_Shanghai.tar.gz create mode 100644 tests/data/spacenet/spacenet6/sn6_AOI_11_Rotterdam/collection.json create mode 100644 tests/data/spacenet/spacenet6/sn6_AOI_11_Rotterdam/sn6_AOI_11_Rotterdam_img1-labels/labels.geojson create mode 100644 tests/data/spacenet/spacenet6/sn6_AOI_11_Rotterdam/sn6_AOI_11_Rotterdam_img1/PAN.tif create mode 100644 tests/data/spacenet/spacenet6/sn6_AOI_11_Rotterdam/sn6_AOI_11_Rotterdam_img1/PS-RGB.tif create mode 100644 tests/data/spacenet/spacenet6/sn6_AOI_11_Rotterdam/sn6_AOI_11_Rotterdam_img1/PS-RGBNIR.tif create mode 100644 tests/data/spacenet/spacenet6/sn6_AOI_11_Rotterdam/sn6_AOI_11_Rotterdam_img1/RGBNIR.tif create mode 100644 tests/data/spacenet/spacenet6/sn6_AOI_11_Rotterdam/sn6_AOI_11_Rotterdam_img1/SAR-Intensity.tif create mode 100644 tests/data/spacenet/spacenet6/sn6_AOI_11_Rotterdam/sn6_AOI_11_Rotterdam_img2-labels/labels.geojson create mode 100644 tests/data/spacenet/spacenet6/sn6_AOI_11_Rotterdam/sn6_AOI_11_Rotterdam_img2/PAN.tif create mode 100644 tests/data/spacenet/spacenet6/sn6_AOI_11_Rotterdam/sn6_AOI_11_Rotterdam_img2/PS-RGB.tif create mode 100644 tests/data/spacenet/spacenet6/sn6_AOI_11_Rotterdam/sn6_AOI_11_Rotterdam_img2/PS-RGBNIR.tif create mode 100644 tests/data/spacenet/spacenet6/sn6_AOI_11_Rotterdam/sn6_AOI_11_Rotterdam_img2/RGBNIR.tif create mode 100644 tests/data/spacenet/spacenet6/sn6_AOI_11_Rotterdam/sn6_AOI_11_Rotterdam_img2/SAR-Intensity.tif diff --git a/docs/api/datasets.rst b/docs/api/datasets.rst index ea3615dc404..10d49dde8f5 100644 --- a/docs/api/datasets.rst +++ b/docs/api/datasets.rst @@ -288,6 +288,7 @@ SpaceNet .. autoclass:: SpaceNet3 .. autoclass:: SpaceNet4 .. autoclass:: SpaceNet5 +.. autoclass:: SpaceNet6 .. autoclass:: SpaceNet7 Tropical Cyclone diff --git a/tests/data/spacenet/data.py b/tests/data/spacenet/data.py new file mode 100644 index 00000000000..37d67e98518 --- /dev/null +++ b/tests/data/spacenet/data.py @@ -0,0 +1,283 @@ +#!/usr/bin/env python3 + +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +import os +import shutil +from collections import OrderedDict +from typing import List, cast + +import fiona +import numpy as np +import rasterio +from rasterio.crs import CRS +from rasterio.transform import Affine +from torchvision.datasets.utils import calculate_md5 + +from torchgeo.datasets import ( + SpaceNet, + SpaceNet1, + SpaceNet2, + SpaceNet3, + SpaceNet4, + SpaceNet5, + SpaceNet6, + SpaceNet7, +) + +transform = Affine(0.3, 0.0, 616500.0, 0.0, -0.3, 3345000.0) +crs = CRS.from_epsg(4326) + +img_count = { + "MS.tif": 8, + "PAN.tif": 1, + "PS-MS.tif": 8, + "PS-RGB.tif": 3, + "PS-RGBNIR.tif": 4, + "RGB.tif": 3, + "RGBNIR.tif": 4, + "SAR-Intensity.tif": 1, + "mosaic.tif": 3, + "8Band.tif": 8, +} + + +sn4_catalog = [ + "10300100023BC100", + "10300100036D5200", + "1030010003BDDC00", + "1030010003CD4300", +] +sn4_angles = [8, 30, 52, 53] + +sn4_imgdirname = "sn4_SN4_buildings_train_AOI_6_Atlanta_732701_3730989-nadir{}_catid_{}" +sn4_lbldirname = "sn4_SN4_buildings_train_AOI_6_Atlanta_732701_3730989-labels" +sn4_emptyimgdirname = ( + "sn4_SN4_buildings_train_AOI_6_Atlanta_732701_3720639-nadir53_" + + "catid_1030010003CD4300" +) +sn4_emptylbldirname = "sn4_SN4_buildings_train_AOI_6_Atlanta_732701_3720639-labels" + + +datasets = [SpaceNet1, SpaceNet2, SpaceNet3, SpaceNet4, SpaceNet5, SpaceNet6, SpaceNet7] + + +def create_test_image(img_dir: str, imgs: List[str]) -> List[List[float]]: + """Create test image + + Args: + img_dir (str): Name of image directory + imgs (List[str]): List of images to be created + + Returns: + List[List[float]]: Boundary coordinates + """ + for img in imgs: + imgpath = os.path.join(img_dir, img) + Z = np.arange(4, dtype="uint16").reshape(2, 2) + count = img_count[img] + with rasterio.open( + imgpath, + "w", + driver="GTiff", + height=Z.shape[0], + width=Z.shape[1], + count=count, + dtype=Z.dtype, + crs=crs, + transform=transform, + ) as dst: + for i in range(1, dst.count + 1): + dst.write(Z, i) + + tim = rasterio.open(imgpath) + slice_index = [[1, 1], [1, 2], [2, 2], [2, 1], [1, 1]] + return [list(tim.transform * p) for p in slice_index] + + +def create_test_label( + lbldir: str, + lblname: str, + coords: List[List[float]], + det_type: str, + empty: bool = False, + diff_crs: bool = False, +) -> None: + """Create test label + + Args: + lbldir (str): Name of label directory + lblname (str): Name of label file + coords (List[Tuple[float, float]]): Boundary coordinates + det_type (str): Type of dataset. Must be either buildings or roads. + empty (bool, optional): Creates empty label file if True. Defaults to False. + diff_crs (bool, optional): Assigns EPSG:3857 as CRS instead of + default EPSG:4326. Defaults to False. + """ + if empty: + # Creates a new file + with open(os.path.join(lbldir, lblname), "w"): + pass + return + + if det_type == "buildings": + meta_properties = OrderedDict() + geom = "Polygon" + rec = { + "type": "Feature", + "id": "0", + "properties": OrderedDict(), + "geometry": {"type": "Polygon", "coordinates": [coords]}, + } + else: + meta_properties = OrderedDict( + [ + ("heading", "str"), + ("lane_number", "str"), + ("one_way_ty", "str"), + ("paved", "str"), + ("road_id", "int"), + ("road_type", "str"), + ("origarea", "int"), + ("origlen", "float"), + ("partialDec", "int"), + ("truncated", "int"), + ("bridge_type", "str"), + ("inferred_speed_mph", "float"), + ("inferred_speed_mps", "float"), + ] + ) + geom = "LineString" + + dummy_vals = {"str": "a", "float": 45.0, "int": 0} + ROAD_DICT = [(k, dummy_vals[v]) for k, v in meta_properties.items()] + rec = { + "type": "Feature", + "id": "0", + "properties": OrderedDict(ROAD_DICT), + "geometry": {"type": "LineString", "coordinates": [coords[0], coords[2]]}, + } + + meta = { + "driver": "GeoJSON", + "schema": {"properties": meta_properties, "geometry": geom}, + "crs": {"init": "epsg:4326"}, + } + if diff_crs: + meta["crs"] = {"init": "epsg:3857"} + out_file = os.path.join(lbldir, lblname) + with fiona.open(out_file, "w", **meta) as dst: + dst.write(rec) + + +def main() -> None: + ROOT_DIR = os.path.dirname(os.path.realpath(__file__)) + + num_samples = 2 + + for dataset in datasets: + + collections = list(dataset.collection_md5_dict.keys()) + for collection in collections: + dataset = cast(SpaceNet, dataset) + if dataset.dataset_id == "spacenet4": + num_samples = 4 + elif collection == "sn5_AOI_7_Moscow" or collection not in [ + "sn5_AOI_8_Mumbai", + "sn7_test_source", + ]: + num_samples = 2 + elif collection == "sn5_AOI_8_Mumbai": + num_samples = 3 + else: + num_samples = 1 + for sample in range(num_samples): + out_dir = os.path.join(ROOT_DIR, collection) + if collection == "sn6_AOI_11_Rotterdam": + out_dir = os.path.join(ROOT_DIR, "spacenet6", collection) + + # Create img dir + if dataset.dataset_id == "spacenet4": + assert num_samples == 4 + if sample != 3: + imgdirname = sn4_imgdirname.format( + sn4_angles[sample], sn4_catalog[sample] + ) + lbldirname = sn4_lbldirname + else: + imgdirname = sn4_emptyimgdirname.format( + sn4_angles[sample], sn4_catalog[sample] + ) + lbldirname = sn4_emptylbldirname + else: + imgdirname = f"{collection}_img{sample + 1}" + lbldirname = f"{collection}_img{sample + 1}-labels" + + imgdir = os.path.join(out_dir, imgdirname) + os.makedirs(imgdir, exist_ok=True) + bounds = create_test_image(imgdir, list(dataset.imagery.values())) + + # Create lbl dir + lbldir = os.path.join(out_dir, lbldirname) + os.makedirs(lbldir, exist_ok=True) + det_type = "roads" if dataset in [SpaceNet3, SpaceNet5] else "buildings" + if dataset.dataset_id == "spacenet4" and sample == 3: + # Creates an empty file + create_test_label( + lbldir, dataset.label_glob, bounds, det_type, empty=True + ) + else: + create_test_label(lbldir, dataset.label_glob, bounds, det_type) + + if collection == "sn5_AOI_8_Mumbai": + if sample == 1: + create_test_label( + lbldir, dataset.label_glob, bounds, det_type, empty=True + ) + if sample == 2: + create_test_label( + lbldir, dataset.label_glob, bounds, det_type, diff_crs=True + ) + + if collection == "sn1_AOI_1_RIO" and sample == 1: + create_test_label( + lbldir, dataset.label_glob, bounds, det_type, diff_crs=True + ) + + if collection not in [ + "sn2_AOI_2_Vegas", + "sn3_AOI_5_Khartoum", + "sn4_AOI_6_Atlanta", + "sn5_AOI_8_Mumbai", + "sn6_AOI_11_Rotterdam", + "sn7_train_source", + ]: + # Create collection.json + with open( + os.path.join(ROOT_DIR, collection, "collection.json"), "w" + ): + pass + if collection == "sn6_AOI_11_Rotterdam": + # Create collection.json + with open( + os.path.join( + ROOT_DIR, "spacenet6", collection, "collection.json" + ), + "w", + ): + pass + + # Create archive + if collection == "sn6_AOI_11_Rotterdam": + break + archive_path = os.path.join(ROOT_DIR, collection) + shutil.make_archive( + archive_path, "gztar", root_dir=ROOT_DIR, base_dir=collection + ) + shutil.rmtree(out_dir) + print(f'{collection}: {calculate_md5(f"{archive_path}.tar.gz")}') + + +if __name__ == "__main__": + main() diff --git a/tests/data/spacenet/sn1_AOI_1_RIO.tar.gz b/tests/data/spacenet/sn1_AOI_1_RIO.tar.gz index 231c81e1c5620f22f653b03b1273e06ed64b2d14..bf7ad82733b4bb27e9b36713ae12ff71d2b47e99 100644 GIT binary patch literal 1052 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 PnlJqe1Q8MF0C)fZ;GKp{ literal 1174 zcmV;H1Zn#piwFP!000001MQqmY~w@}$Hz%kx}ietfn_B?GUk9lZSai0l1QxDtwdD` zcB>jKE3r$I?YbdsY8S^9s+J=0A;JkbK*f;*S~$TjXC%0QIB`K-_Qa_|oH@V+G2=Mf ziQCi(iHBzM{-epf*v~Vz$G?f^b<~DS%8M6P%A|bJsa6_KqZFi4S(d>{Y#AzFwuP`x zux?>&Vd{r9Y+6V*(m0v8wi`jkmt|CGyz+X@?e3Sfe?--Y^*{S=pC{$3+qL?&npODO#z4bpPL?c8ssUOh{i$MR2(4hVQyqynf8^^c7I@mPz zuKmyK&i>a;O!-$u+<-Cf|CN=e&=f6a5t6b}x8I#clhl@}{dF^o zWNNQc`&M&0totKs-)?5YV?UExS2hz%oswc{;Tij_>mTo*ZI?;+?X_>8d-^=Iq z&+1#a`NE~e7ng0hpucgb{rLH3VksL--83lw)J_}%`sd%k8t^Yfz<(<}dHKU{^qW7P zZI?;+4fwyyKedk^0FwAOH8ajXeFFskMW{Fa+4Iv2|L<}9vty3p{|q|Je&HQPO`HLL$8xiv-pK~c>`{Zaa{_%Xh za@DCPgbn+P|EcWvU)5BI|A^3#`adl4RmXd^;T^h3iSK`h=6{xM!TX;O-N-4y&X%K; zWaU|>5^Vdp{(PmARatEAp|z|Qj7oSz`qay|D7|$zyCCT z>gUZ7_)jPPqr?19h{h}abF%3kz4(unUi`-d{zd5CjQ^Zm&hN4K&k)ytcKrUU8pMBu zXh{7(?De1Y0f6yegvN3GXQ4oJw#2enEa-aIm7P6%5fXZtMbdR;XU|@IizBf9Q%`UF ohyVW|L__NT;gA0?{}-Zh9RFecKL`W@fyQ0`0y7}hK>$zy0AY2AXaE2J diff --git a/tests/data/spacenet/sn2_AOI_3_Paris.tar.gz b/tests/data/spacenet/sn2_AOI_3_Paris.tar.gz index 3eaec04c45de86eefa4c21c40dfbee90435c6aeb..6c26bde44d72be677393a4cf096bb4a5fda4ef97 100644 GIT binary patch literal 1182 zcmV;P1Y!FhiwFqxbzfrw|8s6KUqMevUo&4&VRC76E_7jX0PUPjZ{tK5$Hz%kLa0#p z!0sMc$uc+8b^SU{BB5=lMCk!GY7iiyRpm|HZct)Zjw`m>?H+gwC&Y;}2ZXq>`$Z5E zH%^>-;1h5{%s6i9I8Bpuw|2VuKbAX_@yytcGXLK^_B@qW<<+&C{qTLq-f?_#DW>#n zRH`Vtewydys-meX5g(Ei?4T3aK07^`Ptz>19W>j{J1V7?rYNSO$ObixvQ;Fom)|Ay)a|DRL+Pki2Pw)fQ47cl;(oBvaO81sMVKlC5^56fErKd8$= zbNABb|CX85f6K!BKONiLe47+ldW{evPXw0Bv0aGeb1ctm{KfWsRL=LsSpJ%@5T?Jf zKW{|kyv_AkKR2Q}Yixfr)^>~KUt#G#Y_CV>`j_pmf3-yNydPHS%deNnBFl>`|64at zM3%3y{L}7I*!K@C|E!w}+x{fp z;Q1U87NW8OPmh;{!m}>F+r{wn_iw#gc-rO1Ukg)0zH0|R-ul_+U((tyAAMT=WTP&Y zjK@RgPF{a5vE>sR_z(Vr|F8@3zgGS5c_skk_-|4=$bXG10QjFK|Ci6@ztF2Omj7;y z|H26V7ZUuh$MPr4|DBvN|CpRI|9Xu1AIF%#8!>{^~o$K!y|BqwO0{)9V3y@>{cVqm2GQj_8z{)hEn(0}MZ^dB}G`X46pp5sj!88Y_yuVy9m zU*px`|D|A$ic)a6??@FP@q?xl z9S_Ud@dMwjczcb?j1V}Q=g}pc(f<)E zV!yn$6ZnUN7gY0FhkN{DMXBL={!Y`igI>?!Mpeo+P4DBypeCg&qOKc8xm=d5lXA60 zHEN3YRwig<3{*4AC&qrksx@`B3thrcqi|ziZ}DF7XmaVs`(M2OMf^Ybe-8h(OyYkK z{}2BU`VapPmc9OG5&vVs|4YNL{s-%S;Qzt@gZ~HqkK}(A@jp8FpCitVc>kX||MCC-!T&M* w&m{f_>%USl=s)xy`Vak|ME_Hb|AGIPiXr}IzT;E;08A5@RR910 literal 1074 zcmV-21kL*&iwFRjqDf%@1MQl-Z__{=$InSsN~lmf@Dd# zAYM`0y1^*5E5{Y8APj&A3l9m286kw&cuY)8fS8b2nV35C4?s+aJIA3{r>)Z@n3n!N zr|X@44?B1M{?7jOik6feI5nJ=vm-gjEFMOG0g<5VDowGjVm7UUu!1E?#;Pi7NW`)v zN{Cng#?1toDY`j_=TWYB<(g?NUoWhDol*?UKRwQzl(J(pW?{m#^2My{4HK+3Op+auVD1J8}`+rT{B2@f;BRs%gw)pgY&Pe z64AdH#Q<#Z`M;hJ+}UYENb|x`Bj?UI#-Lp&7~`&KTS8Al7^lFamX(__gdSd) zcI;`xaZST7_s)~@8OKW7`SJ9GF_|Wf)2D_8(>N)o2S+o#iolon66tlaaw*#MLLzY~ zQA+&laoDIdr+-PT=Y?VQ_FvXT8SH-)G(G?1;6x_rnv=_4Bh3EmYR&pj-T=V?{WRNKJ4y$aQ9e0+b^QOr;X-gh->rD zbgoIW>jb|}O5DmQAbAH4rq zAjAVIZw;|BV#uKxok!wf)}{#8w@ z`Tmy`(0>$E_20Fk{<%txQ2kqs{%KrF|MY6C{xeLzs`)QyLGyEHLG#-g&7Wa3Kj~|J z?XTjTr_HrPE8hRf!HOmzO#hl(qkmb^K>txt-}+CV*m~CgyNv#6o2B%>6VBd z{;HOsyJuJOl~?W7(WL*kuKyP`;Q!Gi@c&0b zv-4kv`==5A57sf*|0sa(zs6RG{huEn`B>WM-+yvF?w>~dKbi{qj|9+vWBwn|zrX&6 zyMG$+|0ueug8rjmWBY%iSMmSl|B>r)|1{$Nku)9j9|hq5S&DzNy01U~k0jQ!0d)2L z9~CRG|0fb!HUBGZ01dVOq8i-)sbTp3i-a|>|C8z5zlA0GFOgH^>6$WJXLj)ojo5|R zJiS?77`JVQJhVBt(z6$&Bu-&XPl>5iO7G#7R8my2gk_1p)bppf7wfAk7FD*mrt^?u s+PN3VV8G^A00000000000000000000000000H78829hZN_yAA<0KQy1oB#j- diff --git a/tests/data/spacenet/sn2_AOI_4_Shanghai.tar.gz b/tests/data/spacenet/sn2_AOI_4_Shanghai.tar.gz index 138a9079e43c4f7463446c0d0f42b0c702b046b9..b7d8ba655e1f6747817f8f0e6890b625abb48941 100644 GIT binary patch literal 1175 zcmV;I1ZevoiwFqxbzfrw|8s6KUqMevUo>A+Xkl(=XklqCbYXG;?VL?-<3t$8$4ON} zs8IL7!T}`9+)&r?*ke11glMQl>4Dvxz z%oy0X(l9J`=EwEaFsVt@yF`K=^dc|hyC+xE%(B{vS{?sw>Nu`x7`9>PtXyUl*Dey+ zb8o%C+^*f)*k;@HJuhhPd9Big%zxLlU+d|<{^sk;UoVk-JPvR4)i+CIk^3t5 z@AvaW<^Cr3AM}@!v476Pg@0E$JbU=Z9nYp`(f1b)9pz;-+mAV z)o!y<-SKy;ymR%|`dXFhR&{NwUS^tlq#p56cL%$QyM9^}22T&+3F9B}Dt^y({3tve zKA_ER`>+`wtg1D--EgNBc+p_wWO1kyYnpY67v|WGv!YrSW0gupcTehR*)bhky}dF; zCpOf~uACUZgQvp`;J-}%BmW2aKj1(3kN3ae|2Y0j z&Hq9CkN6+)KjMGzAN+^S3I8SL|G41){O}+7KQic!{2%atKKPIS{}29W`7b&D2j725 pG3Y<^ANmjdpI-kZ<^Lf5lVZsKx!UOL z;uer9x-!ApxZT*1*Aa>!NI=`|i6Vr!wn7N?*1$i&sXbPz)DtI8Iq(bhzT(I2Qg5`WcvPJ|9L!+f+XcAj)KqOU? zWkr@n9ok8XuF8bhGJlc|EH?tn=Xqi^7OpvN_jYOZ?J0(OCaM{`k%yDbjwR(d{1wNk7;;*nc#Oga>;D?6u}# z*!MlKpEe8Oy}xm-Z#EQ5?QpSl=lXW}tJwNeFSf;(Vf6gBG`cM1Yv5P-m`10Q~ zr^ncS3H?5O)GiRNFS<5B%k?2{;AxY7+y3zL-OmmTtTk!-z`mr(T!LuuOYz zsQ&f4X9~v;Y6Z z=%3!xN&m;l*8RT_J&hTS^^$D*0;>NFU+|i2`hqg!3tYw*+-%$b-=$yo>`tD%YiCC$ z`afB>uGsZPw_~84pa1BRf#*NDkm>w~MY(2s-!(kuRi*lWu-oQe5ySIe^#6O$^^y>* zEZIVZ7tY#NuURd(ICEE`iJE{+_L;bSv zR=nC=<*GejftxGmCnqXWS*c9Snj@;fukx$V>wIe{dh0hOrt|0#I`qE^mtbKn+JV2) z{y;NceWgYpmKWwc&xaLj1+AXLB*{`)8-)cYjSlmQR0iK7sv|NiyHN^%d6;da>a8Uy z$vrmKH255A$Bvv<&khzQcwwc>rPb0N&3_j9SH$EEpa=giLpA#U9LRS5J8uAK{$G~F zxc@gq1O0y<>;wP5m+lQoAshWC2Y`3(|20uU|DOvP&3|G5xR>~^hUY)IfbpN*oe&it zt^NAR^oJe)0sSWifP2utsG$CH0rkJT_%G_ewf`ptfP0AlN_hU44;cT=SH*zk@pg9iw-NtE5ClOG1VIo4K@bE%5ClOG1VIo4LEaDk2Obuc IL;z3#00VnO7ytkO diff --git a/tests/data/spacenet/sn2_AOI_5_Khartoum.tar.gz b/tests/data/spacenet/sn2_AOI_5_Khartoum.tar.gz index f0131ad3b8cc0a74d2dbc0d06b8d62fbec943f96..b0a4b29ca34433a7b0c273b3f48bda44747e946e 100644 GIT binary patch literal 1191 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 C);mD} diff --git a/tests/data/spacenet/sn3_AOI_2_Vegas.tar.gz b/tests/data/spacenet/sn3_AOI_2_Vegas.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..0e17e78befc43632f4ab23e3737889efa8bd9a5d GIT binary patch literal 1324 zcmaKrSx{4V7{yURLMf(JS;ka?O0}SX5}j78WY~sAY$6Cm6my5gpezXl1VzkkK{i1s zP{dLyU{na2#Hok^LKHC;K|nAP_JkM$!#Eo^V+QOQ~w&Ah~JE#XWma*=Ssb#H{(w}>V zU1pZg2Pa9CT3MV+7km2>;Z#7-uqolS=uc}Y>)sNN* zc1xpua;lnKMSoiJ=J16`efggFwIISJEcNF0exLyHi*VQ*un&Q^V(fAS*t88~>LG7H9B^!SaJlZo z#t$G`2{Q@y60nj8Qcx%pJOdvwz;!bjN;4&Z!MFFo28Ug_ps0I!dCEPbhmdM>+o*tJ zcl`M=S1;W?2~>NVHy?X4SH;dUomr%RI7_m}=hvG@sc%(xt`&${^M-Gs@xNmpQCnR4 z#I?3C>z1B2Wk@jgaWf1 z;M=6oO}Qyc5#+}df;a_iVi|u=0bt~UF)J)01A($sjUC|R1PS=BTwty)DXfE>bq&_pIo9>( z>c|Kl^Ps1L^g-JE`X?O=@JVS*2iOB%pu`1O1Fu700Qf0z!{%5`XJ=PEvBgMX;TT)C z7J<(r<<|?rs01mueg;aq`?*_7|7xVwxuIU=N+MD15#HA?M` zB>zD*S9F)^^}b9Q8auQz@`rLQhutnZpt?a|-5D0l@(-9HtmoSL4FS0C?+o!Adi~xc zMkRPrmtq)~BMq?vI%oAr3}-Z{-P~1HJ+(P@RILiV|8z1*5GP~DhC`$Q?}wB^ewFl` zoQQ8;GgoizWXL^7s;2T8?DXec@RC z9DJPswE8YN*oe}8#M%vk6CSJw#fHNo_U9~*l47vJYgvG@aTxwHv`Py+mEzsN$1@AK Zqn2Z08(ixDNSKEi-!fA+8&nt={0sgl=`sKS literal 0 HcmV?d00001 diff --git a/tests/data/spacenet/sn3_AOI_3_Paris.tar.gz b/tests/data/spacenet/sn3_AOI_3_Paris.tar.gz index d8cb305dc35915aae2653c0bfd1a231a2b3dbc42..3a960eca9af21a79af29bbeae30e8681c44a355c 100644 GIT binary patch literal 1314 zcmZ{jdoZ`h}M2!2GIBnKw4xj@;;J!-!ZoeB(e*m)$k7*rMgOOhZrjR5rt- z6%na4N_Iv0t{Tgxh%Ry|?I$;C&t~_WC$_V^F1I_f({+kYF}io%-!KFejFAIYN{AkY z?)bWno5|v-x8!@Yv5ZMnxJ5Jw`M!H|bB{n8%$xP0$5{i;laMi*DUPaCkV}C>(=qzi z3qXl#AWVk{^B{U&J^+cGFgb`r7HLnC6og*9OEg_C_c>-*;f!T6@f zYD@Ha;l;<=CTpR@gxxlA;PfdQg1r587FQkSe=Ow{JG}iLKWwEBT;W<@Rv>{Kh}!F= zj<0;dMrsU%EcQkSBH4SfBv*8wFrVHjV;1_1oZ61rE*o2h^2^d@)Y+k@3lkHR z-&OM|vZ7JH=0nLm&bkt^q14Yme`rK?v*6S-`B=Q`YYgi?wsm?o31UMD1`_T$JfiKB zZ;O<%jdwYmsi)?T3*;1eNi+76pIZ{}09E2u_!AD;7;6A6)_Xw2it?R1P^wca*lKw* zUf6{c%UJE$Lyex!Tt;Z+vabj;}LaaPA*6U8cs&TPe1G#Sd+JS|Czn|9FecisTGqJpiE;3|@u4#>SO+vd=0S^`2sY@h6 zH0Aj!d99iC#mpU|V}H5ykBfb)q~o-scbtinrFs(D_Fb`Mi<9a)i2Ymk9W)Fow~Hxc z+=}vFt4uuHZP;7eaYj<*+}q)Ks792;=_b5cTHdo?9`btd<$ZcRlb**aFL@P~jGi1f zKiM-G;HuPimhR||7gt!h_m~X)5V*Np>QK%6H7elx(JJpI`ij&&yBpHpMGd^zOz97@ z!XH_7zD!ivFH89A91yb%r%yf<*6Xsr)lnonPLFl1lr+))RYTn#9_qD}GD{}&+X5ZKL0XYq72%>Ei zqk@E@)y5t>i|k!%c1;zP^w6TZ7v3(MQB@TVNVI$bIKhn%02h!@4*di@A!gQVd%baD zH_mRG=J~D0^YYBjuIJhRjI&Q%TQ-)jtQoSgZW7CV3&nsy(RG#OqOOYJyay5$Nz??D zbwq+FOM;AeHIAE!(sn(Q@H{fz?Q52OaKCZ(6N(%0KdYB7%LZ}Gs%v<}wCu3mSTCR7 zSiN9a&AO~k`mj8)|0P*a6!3o%Oyz%Cxm3=1R_*X>Fb8Xza-jcpHR^vw5k&!bsd=4tt-P8#vFyiUsxI`jV6U(@o# zPRc*`JFff979z(mT;!1DuYOkU|MvDTZ*=o<^Y+)J%)d8&|Fkl82^gn;P2Q(}RnS5INif;|&z{&x_W#=<{j+mM>Hk%Fxl;s+$CxK?hcCV4KzyH7EF^(K|95@8C+%!y|3G zVtTkYV`7@CBOyPyhf^_HqsY diff --git a/tests/data/spacenet/sn3_AOI_4_Shanghai.tar.gz b/tests/data/spacenet/sn3_AOI_4_Shanghai.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..f3b479e43b1046de8b63d1cfb1dc8e10e2d9f310 GIT binary patch literal 1338 zcmaKr`!|#c9LAlYLAG^0QDL?cW!KK`N{E`HO)ljwa-C4fWt>Hm*5%z+lcJ~?mLb*3 zI3?1!x8rpyQ{*xtX&KF6j%HnljJ)%H*Y*eOInVR!^ULS?kg`-%md{he2#`QCr`owW zQTJ25B132qks;^4PYj7ym}R|=6CKriFR;?V|d4crb&(XE;it0w10$x8_OXgUl0yJPjQQwSw%wZn~0# z+_qKmuVTbxmkauD`}YS7dcPm2OgX&U4v;!UPAxr-bB38|L9Q6KMW&8?MkS-RLqP#< z4)PV3bb-ZBbC!qtH!Lz?`mIq{R0iYvKv z^P~fE!7r8OGF0SWUlzG*oq~auT(ErwQN+oekieFqv8UFG6%_*AfMjO6cH?2olD8aA zh>&zCL4<5gwy>P!6r7aONtsQFSbyewhnkewxr+8X?U{Lh zY`LSG!oZ9l;~4G`O`_>Ai&x(9nlh>>7PVy=TNg-}GTdWN!0>3Yc!$CXA?ngLt^r%d zHi7*TGII?pcxGX|L~&f88g>9!n=7#Q%vrOpgxc?;QNlQ?VpWl?bb(zmSzYt8iF#Sw@0S+aJH=`~;J9V>f2U@#{PCspK!+4MdQEy`#1 ziBC58R*CgHYM3QcZFck)laJS%ZLD~n^vHX0WKOQN(zYM)U9?OxD@QoH}g02m8AK9=Y3DoA1OJA_yZWCz#8ubbh&zhu6BO$o1>_7YyV1=ud z07FJvqzEBe3q-4e<048LYy$Q)+PX$1$|yEi7e>}hL|de2E3!Z;ipACL0Am%stg_*I l26O;>6|s||8lbBAWq2B~(@^@K1R2PcNAk@z6z(c0{0p(M;!OYm literal 0 HcmV?d00001 diff --git a/tests/data/spacenet/sn3_AOI_5_Khartoum.tar.gz b/tests/data/spacenet/sn3_AOI_5_Khartoum.tar.gz index 0daea2f5392966c25ce41bac36e2ad1103581498..f3a1b809291ffafcea3b3da564da862f3fad36c7 100644 GIT binary patch literal 1280 zcmV+b1^@aViwFqxbzfrw|8s6LUqMevUo~G#Xkl`6Z*^@hbYXG;?VC$)<5U#K?W8Ip zRH(CHm<32y*r879x6??7h9XMEW2y!L(x{5u>BfhCt`BX zCZ)2h>BD?juE?sQ3er7+gLT@0?bGRnt7&RMY6eb|y{4F^rOL7)%Xy<9>l+(tR)GEQ zt?g=+(yg6}QF-Uc_5-ieTz?|--?EG_RV+h^r-M1K=$dNLU!Y}DJ4Kgen*RpR`ER$6 z?mF(|cGK#gQp+!d{%fQ9uR#B~=)W~a|1FjDAM$@i^?$Ue;xy~Z`eV)iN78?l=D!U6 zhyFwVFGc^&0`wpHpVa^N%K5-KoOAx0ran>sEhDM_imDlcB=emAS5*IZc3u@SlwK1A zF)fIcOVKXI@+r!PE&iZA9hHasax8yMTSf;#0`Cm@cf<*aU%0D<=>5ly!jQ2)9~9acaOh) z<=M=G)3E-zZYl`hG=uM7{?QL_(&kSed|diyyDSy-Pe;z3y#7>TOD8t)AN&XZVUNN8 z-O~H>EdZwR-!RQ2|216!|9SF%^+NuOy%tmX@5cBqPT+qg!T)kB-)H`>!jSoA!jSpb zW6b|B#{9#G`HN3+vCC%o|KR@u^B>QD!T&M*FW;Q+5x^Y&zhS`thyM@%AO1i15B|dz zg#UZnZ_Kd(n8tro8}a{5Lj(U8hyUpr`Tuo{|LF<*zcGgYspx9T(YgMN@&7FLEa0Em zvw(bz|89)`pPl3X(?s_;$uFih{D1Ht{D<-6|ILPdz#8rK`R4zlz5k`?2HyYTV$gr+ zKlC5^KfC_-l6;+cciNsi>-@jK|5N0V|NrWm4F8Xd-OuKN;}**mrQBQ04mv*D@)`|R z4IIzStz~mnzfE=br9ms#ZnE5(lxz83i}``WqWW$*)pvZi=+&#m8apgf=i;sHt)i0G zid%c-f}WF3q!SwTuy?Ak>+Ni8@aPi8jekUda@=~@$`0!rw#zDRr+L8qL77KIckSa! za6Bk#*`Ki5;K=vvTEz*E<^ECs)V%?Gr*8Yqjv9oA4d&93Zsg_eXmmw(<4snLS_FQ_ zt=a+W4|(7_wK_XLsN)_o-)FT-yT$0U**Y2yI8xV+>gYB}Ihtcl7Wl{Ke}Q)$mz4uQ zycyJ{>Uloh7`le;-K5P_%uvO(0Z?_*FwHed({z&cjl9(_R|=+T8q)sSu#>UTH=2x! zHSDBI`?S%om)*~v01a6G{io|c#Q$E}`VaBHSpUtk{!=-}e<|?)q5shTOVNMJg#JVS zllsp${>y~_&%^Nk7vBE@|G|IoAN-%ff4=cwD)`Tn|A_xW{1^BS{)7ME|0Mo%jsJrG z5C0$jKm332pFjWc|6lNbEdM#if9c@=;_x5wUp(l3b>qLlfAAl+*!<@l|AqIzxES;w q`Vakw{?D%eoZ`RW|8X(IeD1`}cmMz;#^XK! literal 1193 zcmV;a1XlYWiwFP!000001MOMQZ{tK1o+MQXp+emQyBt8W!VPt^w#SZ>97?)HR29&z z8U#qFvfN~n8YOmQJFKdudtedS6XL{q4`{`WUH%A;To4xyh*J*;ap1%O0dE|qaeg%E zHi@_0zR#M@uQxOHJb&{!udYS)wOgCIs=vK&IG){V+#s`t2+%Z@=aQyM;k*kXDYBFm zRc=T`iE6S$1a;xm*t85FHMgK>EY5l)ly8dn{ zg!D>i><*NlgZy_$rC_bUA-#BSi6r zxIgwmtn*~c16My{16T6ygYT7xKdg51N&EK4!e5Dh-Y6Dt9v%F&dhJFrJTKwTv%t%7 z5?ct`k~}|JjwK(r`O_}?^)Fw0KKZE4`(N;LLhd)buV4Mf;qw(AzW3qU2OA|Jr+hlJ z{^0$`2d>1xbrPoK|3vbWGw~lj0g(Su0Qn#0|IunUpR{kt|3LrOwk93`llZT~$KC+{ zB}qg6M}aQ?m&fuy*0Gq#e=Ed)o<{MXuNLNiDOB!q{zuZ|{1NGK{%VNx?}s>F4LE=P zRXpZ%^ZZ~2-~T%sH^(0VllY&dL;P2$g#3>Jr_+D_#-2w1zXftvAR1x4D{sj9~CMX z|A_)K@_#4G)R_ITYY*b@3%vL%drY}tz4+EY5@ipZf&d=qzo;r z@04;%S~wIAVb*GADL(Y0RA}8jyjKF|b>&$|hqGm*YHn>lt{w6C27M|0x z%7(|fQ<_$lIS#AnZj-^^MsvS6c&N_}`e37kG!Ux6Jm;X_2k)2`D|rrobg(JgwgcM$ z>-qZ$7nL(gK1(%8;`E{#l~)8w&8U(_rJRz_=V>-iWnp(EWJ_}$TRGRWRkgsD3cGND z?^3&|!_?D$XA!f*l>h&ooBqqF|B+xu{-3%2tEm5x0QLV_)&G1h*U^84s@aaFD=N+V z`macNnTGTqY&-f7wsOzb*Z;s4^&f#iAP@)y0)apv5C{YUfj}S-2m}IwIQRG;o=i0} H08jt`@2PC2 diff --git a/tests/data/spacenet/sn4_AOI_6_Atlanta.tar.gz b/tests/data/spacenet/sn4_AOI_6_Atlanta.tar.gz index 1c382ff25dd4c07dd55dabdddd96a0e13106b5ff..a1e0c8a6910c9560196678e8bebd62fa0f9a49e1 100644 GIT binary patch literal 1550 zcmXYwc~p~k7KS5KYzqZ+v`P`FmKK#lMxjQb5*C-LXevsyDEWp$hfT?tvYbHRXACwN zY7tU|0un|LWfK%QsVsgdJDviA1e6#<6JkJQm6(Kne0Q+z-_O10Jm=o`wNHEZ-T7E7 z#00*NcEh|G2e2KOcg&gK=$K%am|zZNGN_lW-m@-txGdE7V!bfPB`x%#?aPu4a@V*` zmEpOfep5x6_xTiNhBQ`Q=vKP^L~UTg@4|Y=TF0LC)~fa?`h_dMo*S+9$=}Hd%`dKe z-4ea3F2pfeqUnkGGQ{J~;&VNb6vugVPm|?5G3qNHuCp6w`bC`jx^#1Ha)5sL()CpV znGA2TrlF}017}IKUf66xBfYoK2ca`KMc(VWP@MPdr&FvGSblTPm|ClJI zqV6hNyFjyenblg@im_O)_Y55uNcd*z#ngQteAab*RLB0p>VCzb;Ey0F&&PQMv4S)O zK4crF>wc!`x*w|}&q@Q8Z06~XvcZPL01L~Z_e;Zx{NO+`__u_}q1;Eb6xjNm$nx*K z>aGV6mm!zhVs5svpzF=?{F00k-JYAkR&p0j;gc4WMS-I2KF5un9IFiqYwLkZMVW71 z_fHyTyi*F+O@woPpjM7I*5@x%`h7|Y?cW?-L_dK$A0+DtZKzTR?-;0Na5%#NM|WwN zdXtl0+RvMtO^#iHU=sIUF+#rx)Q3BEJQw#jHaZIu@uh3yl+GaTt+^J* zF3`)SOI`$Os6=nmkp|j}`|RE9_=SoYBcJ_hM-~3y5i*>fIx|7{#C5-2aGR(U#xE?$ zmq!!~ea8YFkD19$N*lrosI`NO7lyEFy|wLRP9(b9R!}PU-z^@zOMi}U78<84lY2jG z@`vc6F|2AdsbE)?=O;H_xSx%v;x*+Q#NG9tle`I-RyK)~xl_)lCg5QIYhS%EKAF=< zjnHV*=}yV@tgD9?%kQ7nPk~>ro7}Z6555?~I}LPdCP+nj|DiO4f?(K8sFCOoXkR+=&{y3-@xN*cQ4?ls0>lhv`jZNZaDA)jl!NV!IqPJ>lI+t0lAqp_C^qY-HOE5 z;XIscLC;c`lj#CbYY=B(8i#UkxKthXOGRQrXqY+Yjj5cIZr3nyOZLi6I(#cEd;3$n zn_bzv#nePurLRYWLs)u#d&cCi0Sz^cvYu>v51mg4x>+4Hy~Z%|P_6UlkJkD`G@N<) zjnU6j9i@n3ciS#-+of|oE*2-jhON3O`|qUtO@&9T?AEoZL=UI1_>VpiO732jv%Zh| zHies064am8vpM9@-4gD{*}XPvCtE|e7R`xoY&07WQiPKa4K{v1W;9%`Gfxr({sR(R z8Qa5Jd}(ti0}@^JNWQ19e&ww#Ni>tE9|Z{JP(;D(u|Ofd?H*yD{G_83WUI&U;xYOt z?7IXdUlCSaaD$swLs@RV6#DdBC?D@bn=FiYC+sDub7=W2I!RL3pHG>CLIRsMGG_3d zrL1M<8`{0^b~-2lS`_RQkQda&w-i)6ZZX`m|nnxvS(T2aveNUh;Ur2Wc@+m%@t zl#s$xM~pyoi)R9ny=v(rMPLn=t>5;_et~qXZk|^`>MVA!5WX#bOVV5{hEXee0P0!9 zasVL??^$|nG9oV`yDSyn*DSG>u$Q3m31mB~v?lFUi;NkQRqbG^!u#M(Kcs?a(AXt{ z$PwtAr{Cj}v_!6#jCsgmW)^##s4g;Vm&A}(?yo`?NvmXV-L=55D}>b}_&S32jtV_d zGQMLPRe^4;Nu|BgZW=lmtDy6 vKNDW&k_lCaSj+NK8BpKrC9QLRYh732|6FHbCU}q;2BzkR20AE(6w3brH*tAD literal 1416 zcmZ9Kc{J1u9L4A8Jw=O3q0pqHP>n&M)ZihMBwOCdJiP`HN@FUo{CbEd%bcuiYi1Z^XJi{==J$QPKi~cL-gD2n=X0^)n=rjQNiLWT)5(@TL&geqhrL+& z8Im#*jlU|Xt1JCok~=-u-S0FeZ)?(j`NaNhQ)-Rb-twP&(%(dgu^cp>n5SGC=v!eUF%$chd-wOq@ zv0S6uE;qg{FX>FON4wrhwO76;`}LI)SX-OMKgv+53;j&rwRoON*;g`+79?ySN_bX<;gAa456S4RjWY3WuuqV78**r%Q_vM1f7oRsveps+SDv$5e z*O@iPdEIIU&OCwP*I0Y%&eQ2KwxerUn~!m4|KJKyUqo*kX{|uH^XECu(dH>=^(Z5?E&4`E zMWX|MkP_{#&#aqw%aIzMYHiw#3ucfiTd6jzLZkq|bRm)B-g~cgF z=TmE=(%`6yAiJUBhK9u$)5{RFjG|DVgxQ%q#!auO0lWd;_6w3^2yd@xi$()aMx%&) zJM#KsH0r5b07h8>N?sz_Ns;OC1+el>2d-nv*1lAP%<)X%19^o&1X7SOVX z984rcZYSB`8mufLu>*gqhe-usE(wz_tseT2J%D7FlPyzWTB*8Nnd9)*(?~%Pj7W1lOY|BQHO{3hd-m zrx~;v(6o4r5>G?pRzvM7>Au-lgwK4E5r`hE8$sLl%D|t~R(=*jD2AH19pf1=ojqr)TbF-+eV`Jy0Ns3?XiwtZ;bNChK7s({+Z`n(*@_ zt-q?wUU!S|H=RwB-Z>R^t&=n{#_(*HMd^%l7{kfmr?kvj&HCHPsX%H5o#!=EbXVD4 zsEzHRjAC}a52y;~n=E#34H{xs_bkcRuW~OH8MQ2L2>4`Qy%bNhS=BuD=6)n8H^f9X z{K8+loP3RN!KU5*nHg?23HCh8B9(xWmC%)#2c41nm_uy1A~A~$fSFPY3fGWjPNw=R z@es(3h*-jouF%4Cl@?ODD^}tbHAwsb*sP5=3j;Yc=ja9FDMD;uZd7S|h#6$^Vb#N$X4jIRn0gVIX#|rEAe~6f1ln$Dee5Q9#ivr{XqeH8> z#HX&p9RHib;_|u+a+Q(?vqX!xg`D>&k%wfZ84J$=PHVUZk*j=pKpmw`f~F89O7f7k zcN730J@5LtecfA!yu$o~=v9KHIO^lSWfs<|9hJ<%1*85%Qjj_fzw^=XT?0UE^3I0M SnE#0nJRF0{dWcEGVEzR(ODli? diff --git a/tests/data/spacenet/sn5_AOI_7_Moscow.tar.gz b/tests/data/spacenet/sn5_AOI_7_Moscow.tar.gz index acb289ebacd890f8376a24e5aa33bebab83fa961..c666f1b837c4c9d105f9f2661cc48b53b09a92ef 100644 GIT binary patch literal 1332 zcmZ{jZ8Ve#6vrK{rJaUok(x2u6iQ|z30sr*owbrsp)o|O!c1n!OL#;{q$$Lfw-g4` zN-J8#tb|Zn%95OhXtXP5X1vbB(od5lwbASI!NmEgoiC_jO0+(gZ zv~i^~EtoEBZU8&dB;22)Fq!v)J!-$cZL)aVCXcdnej^GQnyj*kg|~Eldpq?KjjqE) zMSTwkmMJ}5!nR#dt=@Er#DyG4h<|ht<|tNkQXyd9lj8izvuEqygt##z_Xy8 z6ZD-fkIbLOemW-9>~Eb-Cr^x6Kd;!yYfz`hF|vQi*v6Z(sWUdp=vb{*_r>c;dA1XO zT+2Pxt8Wgm#Y3N-qu+CIDkeKg%ZBW9KT9{{$n(y)NA3}7{p>QxE!8dlwY;k* zd|>>9i|3CE#9hP+1Hr8#PGUhIJhD>0RLhNS3|nNE+skPf1y=)#9O(<)?bY{);e-{B zTDb~fWAa%dSnSGN5M~9!C3yJ<)Npa?b}86nG~_xsdly|(R@CZ&Q6h1|L{7%x zU79B3hjurb>U{^*sfGQH+$A-&_p}7phU0my}YE#cwI4H5G(GWOHbvTdn;;O2ocNZRZ!>K z878X5D86V1fz{jgQi6CaoDmq0)x7M^w~k*bAIP}6W0)pa!|mLs5dO@&nN|Q z!QPAa-gp%@0dr!B>R=l97;dBtgA`fL2x1BngX2kc{g;V4W{_FJMZnXXI4!iFG0dIj z4H_T$n!`5hlEj2?*DGZCbcri`FU{@MNUk9XS~~5P>O~1b7REd;|BHUr9i+kDaJRo} z9FGK=i;nkIB}*dmD?U`)WG)skf~%_22M^>&>k2%rLLF&7lSyt#<8u*D;=*$;kY=m3 zrW@~8i+*pYZRu>%9$Hi39>L(T)-dcOtX_@BO?D=gs^=?o>izGn-ZoodTcmd@iDSt& zOg8!SOS)<=VU=4@){7pSTUAbkxN~nBKka;$AQQQhVPr{oGac4KnoRVYtk5(`PQ^fZ z<+6_W{pRI|aRXN?-1)BRWfW0-vdD}A0=B|g3SZ#{6eu|l^eKvrnF5L{LkcEL0eU-P z^fUY$i(yzJ=LsPZ!f*o;oJfG_7UU_i#b&-W{j=m`JW5;k{4Y}1Z*jsh!wYiiQ)ClP WNYqpL|N1!hk=A1Uk*084LE#_52iZCR literal 1313 zcmV++1>X7}iwFQKilAWt1MOJNZyQAvUnfy8u0biNMIew?MqE&0=6hy+sGLS3ibOvY z^CeJZTzj1uCAPKRs469*d`LkY5K>SNhyxN7aijecI3NOto_gX2hay#+kdP23W_G>y z+Qh8m#9NxqZ!~@{GjC>R=Iw7@_OX8*n^OOFd(tqaeqQR=x6|I- zpGf`2_JlX~i-fU^c78h*$f$GM`Q^JikC5g3iK`QTSN=r#@VtiF z&y><9jKoyCEve+~nMCr&w%YBq_xHz7KbX9}t@@97(l9>UaIZe~m80g%fBoXC^RFxx zOhMi@cKgbeh?4FrgD^7x&ll!~y#n^ne*%f-e=N}a_e+wwpTD;A!>K?--M!)=ogPfjv14@p&z~Lk z10ah3l=br;bBs0r zt8M;&5|4^dZ5u#k@e`3MN{vUJx2kP&?SfIcE z{6e1a^FD!$I=6RjK3clQmh)T3e*Nk3B+iHDJ^J5&lK*4Q|6tAkSfKgumoHEId7nT= zotx(Wc=JD4=YL|s(arz-DEz!nAfrwqc1GXB`5(pq@#cS!&i}-Mqm}=8=3PJU6UeCD z#~;OyM*fG0x%JWod%ZPO8fahnAI??$2Ndi4PaHU?|9z2NwHt4?8Uv0e;{JySkdFVc zvO|n~)nf;sv8gv$n9L8BN00 zfk0Mgf2oz!R_bnZ;C{xa|NoCI{(JYoB9V^&ap0i-KaBVfQRn-QPy)R8&!CR~ap362 ze|+%xPq82jV1c<{fXO&!WdVjV#9J6}04&rEdCHVROUUSkN!Jny%#gg)I6Lf!emJ|M z6bTD(Mqp>n*pgJF2m&N}wM_E9MwC*c#)Au!3w@FZA>OJp446G(xAQN4}3d&Er*{@3y>dJH=ykbZs>cIw;lUue)HR zU*~s%{@{V#cvU~IW~@3YkMlTBztS-B!u?EF>d>1K&0)vFw4#72$2}QHfFYa38>s8K zi5AVg9(Vb>aI<&O{l=`0ed@Y zN?t*oy15TExiBr;;arce?bKl+=a_Qo)S}CiP@9ZTsjRNVU1MKEn2s@_)Yw6dF5Jg? zM5hQbn;6ly=Ux#QFG|zSSp*G}bk?}VZf?n6Hus`K?G~GR?F)%OuNwBsiY@x`A#Y|q z`vdB#Rron`yvJpEsdZ2Ig2t35Z-u*${H)YoK1FZ_7g+Lx&n2sI88&qvm`V8=)AIoa z97kfdcaKft3bs6TGk5>3!PwBiiTwM_oJb~u1mb2>h`2a>v1}(J(+H93xDj42@g&%R|nR!-n0qGI^uI)_J3-2?r zMa1$5s&zGVSzU9b{~o4{OF&j}BfLwWM>Z;`5&>J9;4W+fRYC%q7e}~}QbagN5v7M& z$0kKawTbRPtqzp^yaA^92x>~8DWfQ%K#ZKc1Fx`NTVbzKMH%~h!L15(Zd|7SC z-#dc`5g3InBLKFxM-ytaRA6<_U;pVvyV$uSSQ9;@-plSw_Z`Ne8rh9_KZ4;!>ww$%GbfY zQ|$wn-Ml}AN@R`jjV7D7V$La>%3U}`eY|*T5<4WWmn&~wt<+O@cWccDNkMS9(sU2$ zCkKU>!4-o}OJ%(rMMmH?N8Mr5d~@~pj6P@UYG1xCKSTNX8M%cNLl5^E|I=zwRO7iD z@5evkBLPLn#EK^R6SRsS<iNB1yz6(jbn)P7;+Cx$B?n@3oOef;G-DAMGuM+JRhDo02dw4W zI@3Z3i54)5SVz1;0wW3MZxp2PT}%j@L$|*}$59m!6;jQwk}*^cBBxLl!t7r%q1br$ zC~Fia9S5>8Zbn2))~E`_o#L<>5N05(QF&2FCj9q5WKS~S%HB|dR1cK9n)oW>Rce>k fPA_w*4a7)$2~k5?vHv>)${Oi{Sz)_Kn~2EY52HJ7 literal 1507 zcmV<91swVxiwFRIl%Qb%1MQpdYaB%w$M=#D&ooM_w4x|1C%%#EIlpK2UX-LkL%_Bn zr&W}4UXx98lH7&84N_~c{(y)tM2Pf-_(IT%?`;1BUx?KgebraK(-#$ruLMDSy54dw03j#`zALne5KY?(DOl-I=*(S`A*EJTp^O)l+LL=WF$6to;`PNy&ALB}ef% zl7$)O2qS@+v=FA0Vaw(NxR$%L*79qfZCkb0(i`>0-uaS_-=k`E+F$ReoaR-pSzBmT zeXmw;?8s1^U#hP%q`G)e(%T@ftlY4bgVYdgxmbD#(mKaauno8O>uofaK9U;= z;;-S)(e{2_=2)zrN7{KNV0%1Pb`H|_L3{_cO8Z=Y!uH^MGq81^pKSsY46MH`1avk{`!V)?P&1-M^E0LzqX-|9|~g2`e4Ps z^2C>(u5aS27haxxX}V%7_Lg;{BV0}h;~ily_0Ion<#@_hK==GJOb!2;$nYPAyzoDJ zW%K(JQJi$&4FACY-1NybFMuTe1rnY76N(N0St#QF@IUgeIlO7@&cDtR@&9Iwe_dub z{`IpM=fBdf|CY7Qynfe2%>Qm}Ghc`?e?G>%*JeH+gplY`@#-g4AUTSY?nLH9-?(u( z(D?Y?cn(~B@IQGvi z;{Ud_&Hu3&|7T5gqmy0-63_Cb~3M@Gq{qg|c0E&aL@t zo;%fCUUujGdb3d|jujfUmEd4#XT4|MYr&37_ExzdOVKW@dd*eW^XqQ=cvN)FYm}Q8 z=F1E2Vi^jT&rDC1afz0v<|>L6>~(t`YF!LZu8Y1p7OT8{QM=W@SYLnyh9mXHqU(9? zLbbK(!rztEB{)EN2|?9%0iMkj*Y_^&yz1xc4Y%TZ^~MEV_k6SIEz}z|KfD46l9Uvu ziU~v&l?uivMH@RMM6qDVp-3X+5c^y)mX%{iAw?+L&Pfy%gfk(9eGWp<)^1uy_G+Ej zpVo0sl!K&Tc>*jGcK8m+BbG?Y<=wCeyWYqs<-z) zCb)|ZKsUet5u$(pVF+{c{m(*u+doAIAZh$}xBZ2n)O`Q5P|xH4f$)zB!qo7eq58Ie z|NKMupKSg9F9ig}UqilYJQgJUd&NE|;m|a&WzW(qI2rVZ^y~N|-oI2uEN{ zrNfIh(W6wZO3<_C1bX!p5iTSSJIZ|(g6E$wp%`JrL5ysdg6=hzQb@R6QXsP5;|R7d z_la|*Bn3G_5wdmldX%6XN?=UHG2@8uY%_fB83X(!k`!|mYcu3P1l|dhIS8Av#o*NI z{7*N2f?dr2!6PC9|1WI(zcNwJ_D}Er)rLV55pHHL%**mPP%V~|J3eZUHX3o z{KH_#@SlYauK(8$D)jq`;-ou~Innp9|Ci=Jwfk3>{$DIu|G~`seBE|B4?B|1V7NAlCoENPr<6%>Qs<=6|wK@Ae<;`afjme=?C7|C#lFz41TT^?$_h zpNS0rX8m8!{10&bA2I&lndsoo|CsfEY19Y*16}`z&HQgBI#}~RX8oU$k&#ha{SE0Y Jxv~II004;bFoysD diff --git a/tests/data/spacenet/sn7_test_source.tar.gz b/tests/data/spacenet/sn7_test_source.tar.gz index f1ca4f1c87e63c80beadf9e6202324efbcebacb2..e411894fb3a666526731ce96663416831e773ddc 100644 GIT binary patch literal 818 zcmV-21I_#&iwFqxbzfrw|8s6PUvy=2bYF9Cb#h~6E_7jX0PUGgPZL2H$7fptwGsmd zUk;jV)|;u@eVuKa7$GDgCkdEnVhCBwP}a1&WOo}OSP#C{lSe;+@hW^16K|e8@iB}u z+ocwiKoyF@|2LUF&(7OUCo}(<$*M)QI5F$4-DU0)3(2vdb=c2pnrZ#?MY^sTx$Ivue(^N+o-N+Mg>WO@3F=kP`7zNF+%8JLe{vF2_ zR(EW@*LK&uZkdL|XP`rQIo+hDLu7l9>)(x5o_hZN z{?7l7qZv5=L;s=wIRAqa*Z)Qkxn5O`z2##$|5KCh)_;RfMvC+QAefoCL2}%V6C!1a z#JvoUQjeeEewN#>JZ95$5r=#HacL;AZ}`u}G+orW)YH!8w9FMAulCfP<9;UX&3yW< zZ#-UjIhy#}Jid4}N`|@p&f}+cmdIk~;*~esqe)$#`&;cy@=u;iowml3ASJ;}_;P#4 z9%f`#J}Z;LTCZm&chaP!$0LLc2|q)mp)@Tg?Dm+H+iH)9u}PlaT|bxGY>WK!i6!K1 zBYuDFLpZ_RiI4XmPCl5PmrK^Op4LUHB4kNtB(VQu|Hu9hPICXhS$7|^dQ|+I_21Y1 z&(L)X_dneKp#RW+@XzRf$EYTXKuHy4-n{sQM`1(|Fp2-?ZQ2NqpipSRAhJ?$B&dU$2SI%1Si|!X?jl z<4(&-pgI+rW_Gt1i`tYHWYe^)a=9$Tu7h5p2DRmd!XYYIyNcQ69rz5^oxY3xQ5Sxx wlmtG!`GtH7(hUFr00000000000000000000000000Gwui02%EXJpfPu08Oi?EC2ui literal 465 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 literal 507 zcmVk2y=)Y zJciJ<+Jj9=T6XC{RLErv{5QNv*RS&HtnLSN*>_V83K$)expysWQ&RE1OBaYzw|@*-Y5nV0GINe|~Fj z?>{c5(0?wZG|B&QkdptquJ5!POTBjMH+zHzTb8`me~YWj-#<5{WS|@4cmNab|LW>f zD4;$B(6XRmmch^xc?RL-kBJRU|qQB%@#Q6AvWY&;&G^C(eMj%#oyc$`>gBT=&% z@AVnu!9fwSsNXR54~vjTJ;OK&vY?|b;z`3G1M`@-w2Qkb#D^9i+sECN^SPO4BfaTq zl)D4>?f0DzKfWBDzW=)Rd^D~_S2z{jRJ3xencOg_g!6@AFa;IJ7sBy(3s4NTG@Xm| z$->r)O}#Gln!fHg`>);VTGMMdJ=YstObp;7vKLcC{?^Vrlgjtc)9e4ZVATHw{r``J xl>AS>{~Of*#{u>KB$L-owRWL9^*&uanNNhny7O>ttpoA!rxEPcT zGE*F?24tHIlA2&7HeWLj12a(m91u6P@G!6e>1RN^zMYvt0Z5Ah&EL?@19oE=kiD^; z3GDhbAR7dX!QiqzjE0EfCo?W6If7J}w0eSR5StO~8+HZ;77&|>0qAsy7|`*I49^4@ zIX1QfWf|DO{61w)jt%V~J=|cLfuSR}WSZ=fA_t%nhh-rVj^XaX3Kk|cV3V1EJ_G<* CfgbDt literal 0 HcmV?d00001 diff --git a/tests/data/spacenet/spacenet6/sn6_AOI_11_Rotterdam/sn6_AOI_11_Rotterdam_img1/PS-RGB.tif b/tests/data/spacenet/spacenet6/sn6_AOI_11_Rotterdam/sn6_AOI_11_Rotterdam_img1/PS-RGB.tif new file mode 100644 index 0000000000000000000000000000000000000000..022510c2df5897311ad94a0e7643d4f6ed06cc63 GIT binary patch literal 414 zcmebD)MDUZU|-mK1I2CuF*8&gq>c@VEy&0M*4qY@5QU0^ z^oT*(AT!0GY9xSc86>?yKsHDo1cHHVkiG{%%-75VW%MGwljf!QU_#%fB+aW0^P;PU?imfep;>Q|9E@&<@hW4W=0wI&w><$u22! g04i}<782nY?jEdQVNwI+f&j#=Oh9v)fIbI702xvt(*OVf literal 0 HcmV?d00001 diff --git a/tests/data/spacenet/spacenet6/sn6_AOI_11_Rotterdam/sn6_AOI_11_Rotterdam_img1/PS-RGBNIR.tif b/tests/data/spacenet/spacenet6/sn6_AOI_11_Rotterdam/sn6_AOI_11_Rotterdam_img1/PS-RGBNIR.tif new file mode 100644 index 0000000000000000000000000000000000000000..daadc4a2e39c82ef03fe23e6f567ef707b138269 GIT binary patch literal 432 zcmaKoy$%6E5XWb4FXzNXDA15x=(H3%RC2A8@CX`>C=@CmS(T_ffoSn25}i^ZN{`?_ zyDPcMOlIe|^Of0+qB{9RlqV9B1jvDj1Uq0Cu?I}rIM;az&I?!f?vW_iIQJAS^URX1 z3Blz=ZyziXd%|Kc_q}1+RiNV^@NylH2k&G4SxE}PE$~GJdfz$tsvP~2Etn-|)!YR3 zV{K@;w}0Mb|DWSqwaXRFO{6_D&mu|@uPd+v9%o|sOhK=l@UIG4^7MUIOZykaJsItZ hwv*YRa-4Qh(m4%A-C-{dTg?ToM$EQ6*(m=J>lYLQA{_t# literal 0 HcmV?d00001 diff --git a/tests/data/spacenet/spacenet6/sn6_AOI_11_Rotterdam/sn6_AOI_11_Rotterdam_img1/RGBNIR.tif b/tests/data/spacenet/spacenet6/sn6_AOI_11_Rotterdam/sn6_AOI_11_Rotterdam_img1/RGBNIR.tif new file mode 100644 index 0000000000000000000000000000000000000000..daadc4a2e39c82ef03fe23e6f567ef707b138269 GIT binary patch literal 432 zcmaKoy$%6E5XWb4FXzNXDA15x=(H3%RC2A8@CX`>C=@CmS(T_ffoSn25}i^ZN{`?_ zyDPcMOlIe|^Of0+qB{9RlqV9B1jvDj1Uq0Cu?I}rIM;az&I?!f?vW_iIQJAS^URX1 z3Blz=ZyziXd%|Kc_q}1+RiNV^@NylH2k&G4SxE}PE$~GJdfz$tsvP~2Etn-|)!YR3 zV{K@;w}0Mb|DWSqwaXRFO{6_D&mu|@uPd+v9%o|sOhK=l@UIG4^7MUIOZykaJsItZ hwv*YRa-4Qh(m4%A-C-{dTg?ToM$EQ6*(m=J>lYLQA{_t# literal 0 HcmV?d00001 diff --git a/tests/data/spacenet/spacenet6/sn6_AOI_11_Rotterdam/sn6_AOI_11_Rotterdam_img1/SAR-Intensity.tif b/tests/data/spacenet/spacenet6/sn6_AOI_11_Rotterdam/sn6_AOI_11_Rotterdam_img1/SAR-Intensity.tif new file mode 100644 index 0000000000000000000000000000000000000000..a9aef1da576c0c15b4c6f95102c686c595cb696a GIT binary patch literal 374 zcmebD)MDUZU|-owRWL9^*&uanNNhny7O>ttpoA!rxEPcT zGE*F?24tHIlA2&7HeWLj12a(m91u6P@G!6e>1RN^zMYvt0Z5Ah&EL?@19oE=kiD^; z3GDhbAR7dX!QiqzjE0EfCo?W6If7J}w0eSR5StO~8+HZ;77&|>0qAsy7|`*I49^4@ zIX1QfWf|DO{61w)jt%V~J=|cLfuSR}WSZ=fA_t%nhh-rVj^XaX3Kk|cV3V1EJ_G<* CfgbDt literal 0 HcmV?d00001 diff --git a/tests/data/spacenet/spacenet6/sn6_AOI_11_Rotterdam/sn6_AOI_11_Rotterdam_img2-labels/labels.geojson b/tests/data/spacenet/spacenet6/sn6_AOI_11_Rotterdam/sn6_AOI_11_Rotterdam_img2-labels/labels.geojson new file mode 100644 index 00000000000..0a418938820 --- /dev/null +++ b/tests/data/spacenet/spacenet6/sn6_AOI_11_Rotterdam/sn6_AOI_11_Rotterdam_img2-labels/labels.geojson @@ -0,0 +1,7 @@ +{ +"type": "FeatureCollection", +"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } }, +"features": [ +{ "type": "Feature", "properties": { }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 616500.300000000046566, 3344999.700000000186265 ], [ 616500.300000000046566, 3344999.4 ], [ 616500.599999999976717, 3344999.4 ], [ 616500.599999999976717, 3344999.700000000186265 ], [ 616500.300000000046566, 3344999.700000000186265 ] ] ] } } +] +} diff --git a/tests/data/spacenet/spacenet6/sn6_AOI_11_Rotterdam/sn6_AOI_11_Rotterdam_img2/PAN.tif b/tests/data/spacenet/spacenet6/sn6_AOI_11_Rotterdam/sn6_AOI_11_Rotterdam_img2/PAN.tif new file mode 100644 index 0000000000000000000000000000000000000000..a9aef1da576c0c15b4c6f95102c686c595cb696a GIT binary patch literal 374 zcmebD)MDUZU|-owRWL9^*&uanNNhny7O>ttpoA!rxEPcT zGE*F?24tHIlA2&7HeWLj12a(m91u6P@G!6e>1RN^zMYvt0Z5Ah&EL?@19oE=kiD^; z3GDhbAR7dX!QiqzjE0EfCo?W6If7J}w0eSR5StO~8+HZ;77&|>0qAsy7|`*I49^4@ zIX1QfWf|DO{61w)jt%V~J=|cLfuSR}WSZ=fA_t%nhh-rVj^XaX3Kk|cV3V1EJ_G<* CfgbDt literal 0 HcmV?d00001 diff --git a/tests/data/spacenet/spacenet6/sn6_AOI_11_Rotterdam/sn6_AOI_11_Rotterdam_img2/PS-RGB.tif b/tests/data/spacenet/spacenet6/sn6_AOI_11_Rotterdam/sn6_AOI_11_Rotterdam_img2/PS-RGB.tif new file mode 100644 index 0000000000000000000000000000000000000000..022510c2df5897311ad94a0e7643d4f6ed06cc63 GIT binary patch literal 414 zcmebD)MDUZU|-mK1I2CuF*8&gq>c@VEy&0M*4qY@5QU0^ z^oT*(AT!0GY9xSc86>?yKsHDo1cHHVkiG{%%-75VW%MGwljf!QU_#%fB+aW0^P;PU?imfep;>Q|9E@&<@hW4W=0wI&w><$u22! g04i}<782nY?jEdQVNwI+f&j#=Oh9v)fIbI702xvt(*OVf literal 0 HcmV?d00001 diff --git a/tests/data/spacenet/spacenet6/sn6_AOI_11_Rotterdam/sn6_AOI_11_Rotterdam_img2/PS-RGBNIR.tif b/tests/data/spacenet/spacenet6/sn6_AOI_11_Rotterdam/sn6_AOI_11_Rotterdam_img2/PS-RGBNIR.tif new file mode 100644 index 0000000000000000000000000000000000000000..daadc4a2e39c82ef03fe23e6f567ef707b138269 GIT binary patch literal 432 zcmaKoy$%6E5XWb4FXzNXDA15x=(H3%RC2A8@CX`>C=@CmS(T_ffoSn25}i^ZN{`?_ zyDPcMOlIe|^Of0+qB{9RlqV9B1jvDj1Uq0Cu?I}rIM;az&I?!f?vW_iIQJAS^URX1 z3Blz=ZyziXd%|Kc_q}1+RiNV^@NylH2k&G4SxE}PE$~GJdfz$tsvP~2Etn-|)!YR3 zV{K@;w}0Mb|DWSqwaXRFO{6_D&mu|@uPd+v9%o|sOhK=l@UIG4^7MUIOZykaJsItZ hwv*YRa-4Qh(m4%A-C-{dTg?ToM$EQ6*(m=J>lYLQA{_t# literal 0 HcmV?d00001 diff --git a/tests/data/spacenet/spacenet6/sn6_AOI_11_Rotterdam/sn6_AOI_11_Rotterdam_img2/RGBNIR.tif b/tests/data/spacenet/spacenet6/sn6_AOI_11_Rotterdam/sn6_AOI_11_Rotterdam_img2/RGBNIR.tif new file mode 100644 index 0000000000000000000000000000000000000000..daadc4a2e39c82ef03fe23e6f567ef707b138269 GIT binary patch literal 432 zcmaKoy$%6E5XWb4FXzNXDA15x=(H3%RC2A8@CX`>C=@CmS(T_ffoSn25}i^ZN{`?_ zyDPcMOlIe|^Of0+qB{9RlqV9B1jvDj1Uq0Cu?I}rIM;az&I?!f?vW_iIQJAS^URX1 z3Blz=ZyziXd%|Kc_q}1+RiNV^@NylH2k&G4SxE}PE$~GJdfz$tsvP~2Etn-|)!YR3 zV{K@;w}0Mb|DWSqwaXRFO{6_D&mu|@uPd+v9%o|sOhK=l@UIG4^7MUIOZykaJsItZ hwv*YRa-4Qh(m4%A-C-{dTg?ToM$EQ6*(m=J>lYLQA{_t# literal 0 HcmV?d00001 diff --git a/tests/data/spacenet/spacenet6/sn6_AOI_11_Rotterdam/sn6_AOI_11_Rotterdam_img2/SAR-Intensity.tif b/tests/data/spacenet/spacenet6/sn6_AOI_11_Rotterdam/sn6_AOI_11_Rotterdam_img2/SAR-Intensity.tif new file mode 100644 index 0000000000000000000000000000000000000000..a9aef1da576c0c15b4c6f95102c686c595cb696a GIT binary patch literal 374 zcmebD)MDUZU|-owRWL9^*&uanNNhny7O>ttpoA!rxEPcT zGE*F?24tHIlA2&7HeWLj12a(m91u6P@G!6e>1RN^zMYvt0Z5Ah&EL?@19oE=kiD^; z3GDhbAR7dX!QiqzjE0EfCo?W6If7J}w0eSR5StO~8+HZ;77&|>0qAsy7|`*I49^4@ zIX1QfWf|DO{61w)jt%V~J=|cLfuSR}WSZ=fA_t%nhh-rVj^XaX3Kk|cV3V1EJ_G<* CfgbDt literal 0 HcmV?d00001 diff --git a/tests/datasets/test_spacenet.py b/tests/datasets/test_spacenet.py index bf84b60633d..a20d6e9b2d8 100644 --- a/tests/datasets/test_spacenet.py +++ b/tests/datasets/test_spacenet.py @@ -19,10 +19,12 @@ SpaceNet3, SpaceNet4, SpaceNet5, + SpaceNet6, SpaceNet7, ) TEST_DATA_DIR = "tests/data/spacenet" +radiant_mlhub = pytest.importorskip("radiant_mlhub", minversion="0.2.1") class Collection: @@ -35,18 +37,33 @@ def download(self, output_dir: str, **kwargs: str) -> None: shutil.copy(tarball, output_dir) +class Dataset: + def __init__(self, dataset_id: str) -> None: + self.dataset_id = dataset_id + + def download(self, output_dir: str, **kwargs: str) -> None: + glob_path = os.path.join(TEST_DATA_DIR, "spacenet*") + for directory in glob.iglob(glob_path): + dataset_name = os.path.basename(directory) + output_dir = os.path.join(output_dir, dataset_name) + shutil.copytree(directory, output_dir) + + def fetch_collection(collection_id: str, **kwargs: str) -> Collection: return Collection(collection_id) +def fetch_dataset(dataset_id: str, **kwargs: str) -> Dataset: + return Dataset(dataset_id) + + class TestSpaceNet1: @pytest.fixture(params=["rgb", "8band"]) def dataset( self, request: SubRequest, monkeypatch: MonkeyPatch, tmp_path: Path ) -> SpaceNet1: - radiant_mlhub = pytest.importorskip("radiant_mlhub", minversion="0.2.1") monkeypatch.setattr(radiant_mlhub.Collection, "fetch", fetch_collection) - test_md5 = {"sn1_AOI_1_RIO": "829652022c2df4511ee4ae05bc290250"} + test_md5 = {"sn1_AOI_1_RIO": "246e27fcd7ae73496212a7f585a43dbb"} # Refer https://github.com/python/mypy/issues/1032 monkeypatch.setattr(SpaceNet1, "collection_md5_dict", test_md5) @@ -58,6 +75,7 @@ def dataset( def test_getitem(self, dataset: SpaceNet1) -> None: x = dataset[0] + dataset[1] assert isinstance(x, dict) assert isinstance(x["image"], torch.Tensor) assert isinstance(x["mask"], torch.Tensor) @@ -90,13 +108,12 @@ class TestSpaceNet2: def dataset( self, request: SubRequest, monkeypatch: MonkeyPatch, tmp_path: Path ) -> SpaceNet2: - radiant_mlhub = pytest.importorskip("radiant_mlhub", minversion="0.2.1") monkeypatch.setattr(radiant_mlhub.Collection, "fetch", fetch_collection) test_md5 = { - "sn2_AOI_2_Vegas": "6ceae7ff8c557346e8a4c8b6c61cc1b9", - "sn2_AOI_3_Paris": "811e6a26fdeb8be445fed99769fa52c5", - "sn2_AOI_4_Shanghai": "139d1627d184c74426a85ad0222f7355", - "sn2_AOI_5_Khartoum": "435535120414b74165aa87f051c3a2b3", + "sn2_AOI_2_Vegas": "131048686ba21a45853c05f227f40b7f", + "sn2_AOI_3_Paris": "62242fd198ee32b59f0178cf656e1513", + "sn2_AOI_4_Shanghai": "563b0817ecedd8ff3b3e4cb2991bf3fb", + "sn2_AOI_5_Khartoum": "e4185a2e9a12cf7b3d0cd1db6b3e0f06", } monkeypatch.setattr(SpaceNet2, "collection_md5_dict", test_md5) @@ -123,9 +140,8 @@ def test_getitem(self, dataset: SpaceNet2) -> None: else: assert x["image"].shape[0] == 1 - # TODO: Change len to 4 when radiantearth/radiant-mlhub#65 is fixed def test_len(self, dataset: SpaceNet2) -> None: - assert len(dataset) == 5 + assert len(dataset) == 4 def test_already_downloaded(self, dataset: SpaceNet2) -> None: SpaceNet2(root=dataset.root, download=True) @@ -153,11 +169,10 @@ class TestSpaceNet3: def dataset( self, request: SubRequest, monkeypatch: MonkeyPatch, tmp_path: Path ) -> SpaceNet3: - radiant_mlhub = pytest.importorskip("radiant_mlhub", minversion="0.2.1") monkeypatch.setattr(radiant_mlhub.Collection, "fetch", fetch_collection) test_md5 = { - "sn3_AOI_3_Paris": "197440e0ade970169a801a173a492c27", - "sn3_AOI_5_Khartoum": "b21ff7dd33a15ec32bd380c083263cdf", + "sn3_AOI_3_Paris": "93452c68da11dd6b57dc83dba43c2c9d", + "sn3_AOI_5_Khartoum": "7c9d96810198bf101cbaf54f7a5e8b3b", } monkeypatch.setattr(SpaceNet3, "collection_md5_dict", test_md5) @@ -218,9 +233,8 @@ class TestSpaceNet4: def dataset( self, request: SubRequest, monkeypatch: MonkeyPatch, tmp_path: Path ) -> SpaceNet4: - radiant_mlhub = pytest.importorskip("radiant_mlhub", minversion="0.2.1") monkeypatch.setattr(radiant_mlhub.Collection, "fetch", fetch_collection) - test_md5 = {"sn4_AOI_6_Atlanta": "ea37c2d87e2c3a1d8b2a7c2230080d46"} + test_md5 = {"sn4_AOI_6_Atlanta": "097a76a2319b7ba34dac1722862fc93b"} test_angles = ["nadir", "off-nadir", "very-off-nadir"] @@ -281,11 +295,10 @@ class TestSpaceNet5: def dataset( self, request: SubRequest, monkeypatch: MonkeyPatch, tmp_path: Path ) -> SpaceNet5: - radiant_mlhub = pytest.importorskip("radiant_mlhub", minversion="0.2.1") monkeypatch.setattr(radiant_mlhub.Collection, "fetch", fetch_collection) test_md5 = { - "sn5_AOI_7_Moscow": "e0d5f41f1b6b0ee7696c15e5ff3141f5", - "sn5_AOI_8_Mumbai": "ab898700ee586a137af492b84a08e662", + "sn5_AOI_7_Moscow": "5c511dd31eea739cc1f81ef5962f3d56", + "sn5_AOI_8_Mumbai": "e00452b87bbe87feaef65f373be3978e", } monkeypatch.setattr(SpaceNet5, "collection_md5_dict", test_md5) @@ -339,17 +352,55 @@ def test_plot(self, dataset: SpaceNet5) -> None: plt.close() +class TestSpaceNet6: + @pytest.fixture(params=["PAN", "RGBNIR", "PS-RGB", "PS-RGBNIR", "SAR-Intensity"]) + def dataset( + self, request: SubRequest, monkeypatch: MonkeyPatch, tmp_path: Path + ) -> SpaceNet6: + monkeypatch.setattr(radiant_mlhub.Dataset, "fetch", fetch_dataset) + root = str(tmp_path) + transforms = nn.Identity() + return SpaceNet6( + root, image=request.param, transforms=transforms, download=True, api_key="" + ) + + def test_getitem(self, dataset: SpaceNet6) -> None: + x = dataset[0] + assert isinstance(x, dict) + assert isinstance(x["image"], torch.Tensor) + assert isinstance(x["mask"], torch.Tensor) + if dataset.image == "PS-RGB": + assert x["image"].shape[0] == 3 + elif dataset.image in ["RGBNIR", "PS-RGBNIR"]: + assert x["image"].shape[0] == 4 + else: + assert x["image"].shape[0] == 1 + + def test_len(self, dataset: SpaceNet6) -> None: + assert len(dataset) == 2 + + def test_already_downloaded(self, dataset: SpaceNet6) -> None: + SpaceNet6(root=dataset.root, download=True) + + def test_plot(self, dataset: SpaceNet6) -> None: + x = dataset[0].copy() + x["prediction"] = x["mask"] + dataset.plot(x, suptitle="Test") + plt.close() + dataset.plot(x, show_titles=False) + plt.close() + + class TestSpaceNet7: @pytest.fixture(params=["train", "test"]) def dataset( self, request: SubRequest, monkeypatch: MonkeyPatch, tmp_path: Path ) -> SpaceNet7: - radiant_mlhub = pytest.importorskip("radiant_mlhub", minversion="0.2.1") monkeypatch.setattr(radiant_mlhub.Collection, "fetch", fetch_collection) test_md5 = { - "sn7_train_source": "254fd6b16e350b071137b2658332091f", - "sn7_train_labels": "05befe86b037a3af75c7143553033664", - "sn7_test_source": "37d98d44a9da39657ed4b7beee22a21e", + "sn7_train_source": "197bfa8842a40b09b6837b824a6370e0", + "sn7_train_labels": "625ad8a989a5105bc766a53e53df4d0e", + "sn7_test_source": "461f59eb21bb4f416c867f5037dfceeb", } monkeypatch.setattr(SpaceNet7, "collection_md5_dict", test_md5) diff --git a/torchgeo/datasets/__init__.py b/torchgeo/datasets/__init__.py index 6b6aa6fbc6e..f85ff83510d 100644 --- a/torchgeo/datasets/__init__.py +++ b/torchgeo/datasets/__init__.py @@ -92,6 +92,7 @@ SpaceNet3, SpaceNet4, SpaceNet5, + SpaceNet6, SpaceNet7, ) from .ucmerced import UCMerced @@ -184,6 +185,7 @@ "SpaceNet3", "SpaceNet4", "SpaceNet5", + "SpaceNet6", "SpaceNet7", "TropicalCyclone", "UCMerced", diff --git a/torchgeo/datasets/spacenet.py b/torchgeo/datasets/spacenet.py index 3bbf24daa11..3e5baa7ad75 100644 --- a/torchgeo/datasets/spacenet.py +++ b/torchgeo/datasets/spacenet.py @@ -28,6 +28,7 @@ from .utils import ( check_integrity, download_radiant_mlhub_collection, + download_radiant_mlhub_dataset, extract_archive, percentile_normalization, ) @@ -40,6 +41,13 @@ class SpaceNet(NonGeoDataset, abc.ABC): datasets that all together contain >11M building footprints and ~20,000 km of road labels mapped over high-resolution satellite imagery obtained from a variety of sensors such as Worldview-2, Worldview-3 and Dove. + + .. note:: + + The SpaceNet datasets require the following additional library to be installed: + + * `radiant-mlhub `_ to download the + imagery and labels from the Radiant Earth MLHub """ @property @@ -384,13 +392,6 @@ class SpaceNet1(SpaceNet): * https://arxiv.org/abs/1807.01232 - .. note:: - - This dataset requires the following additional library to be installed: - - * `radiant-mlhub `_ to download the - imagery and labels from the Radiant Earth MLHub - """ dataset_id = "spacenet1" @@ -490,13 +491,6 @@ class SpaceNet2(SpaceNet): * https://arxiv.org/abs/1807.01232 - .. note:: - - This dataset requires the following additional library to be installed: - - * `radiant-mlhub `_ to download the - imagery and labels from the Radiant Earth MLHub - """ dataset_id = "spacenet2" @@ -616,13 +610,6 @@ class SpaceNet3(SpaceNet): * https://arxiv.org/abs/1807.01232 - .. note:: - - This dataset requires the following additional library to be installed: - - * `radiant-mlhub `_ to download the - imagery and labels from the Radiant Earth MLHub - .. versionadded:: 0.3 """ @@ -853,13 +840,6 @@ class SpaceNet4(SpaceNet): * https://arxiv.org/abs/1903.12239 - .. note:: - - This dataset requires the following additional library to be installed: - - * `radiant-mlhub `_ to download the - imagery and labels from the Radiant Earth MLHub - """ dataset_id = "spacenet4" @@ -1050,13 +1030,6 @@ class SpaceNet5(SpaceNet3): Route Travel Time Estimation from Satellite Imageryā€¯, https://spacenet.ai/sn5-challenge/ - .. note:: - - This dataset requires the following additional library to be installed: - - * `radiant-mlhub `_ to download the - imagery and labels from the Radiant Earth MLHub - .. versionadded:: 0.2 """ @@ -1122,6 +1095,149 @@ def __init__( ) +class SpaceNet6(SpaceNet): + r"""SpaceNet 6: Multi-Sensor All-Weather Mapping. + + `SpaceNet 6 `_ is a dataset + of optical and SAR imagery over the city of Rotterdam. + + Collection features: + + +------------+---------------------+------------+-----------------------------+ + | AOI | Area (km\ :sup:`2`\)| # Images | # Building Footprint Labels | + +============+=====================+============+=============================+ + | Rotterdam | 120 | 3401 | 48000 | + +------------+---------------------+------------+-----------------------------+ + + + Imagery features: + + .. list-table:: + :widths: 10 10 10 10 10 10 + :header-rows: 1 + :stub-columns: 1 + + * - + - PAN + - RGBNIR + - PS-RGB + - PS-RGBNIR + - SAR-Intensity + * - GSD (m) + - 0.5 + - 2.0 + - 0.5 + - 0.5 + - 0.5 + * - Chip size (px) + - 900 x 900 + - 450 x 450 + - 900 x 900 + - 900 x 900 + - 900 x 900 + + + Dataset format: + + * Imagery - GeoTIFFs from Worldview-2 (optical) and Capella Space (SAR) + + * PAN.tif (Panchromatic) + * RGBNIR.tif (Multispectral) + * PS-RGB (Pansharpened RGB) + * PS-RGBNIR (Pansharpened RGBNIR) + * SAR-Intensity (SAR Intensity) + + * Labels - GeoJSON + + * labels.geojson + + If you use this dataset in your research, please cite the following paper: + + * https://arxiv.org/abs/2004.06500 + + .. note:: + + This dataset requires the following additional library to be installed: + + * `radiant-mlhub `_ to download the + imagery and labels from the Radiant Earth MLHub + + .. versionadded:: 0.4 + """ + + dataset_id = "spacenet6" + collections = ["sn6_AOI_11_Rotterdam"] + # This is actually the metadata hash + collection_md5_dict = {"sn6_AOI_11_Rotterdam": "66f7312218fec67a1e0b3b02b22c95cc"} + imagery = { + "PAN": "PAN.tif", + "RGBNIR": "RGBNIR.tif", + "PS-RGB": "PS-RGB.tif", + "PS-RGBNIR": "PS-RGBNIR.tif", + "SAR-Intensity": "SAR-Intensity.tif", + } + chip_size = { + "PAN": (900, 900), + "RGBNIR": (450, 450), + "PS-RGB": (900, 900), + "PS-RGBNIR": (900, 900), + "SAR-Intensity": (900, 900), + } + label_glob = "labels.geojson" + + def __init__( + self, + root: str = "data", + image: str = "PS-RGB", + transforms: Optional[Callable[[Dict[str, Any]], Dict[str, Any]]] = None, + download: bool = False, + api_key: Optional[str] = None, + ) -> None: + """Initialize a new SpaceNet 6 Dataset instance. + + Args: + root: root directory where dataset can be found + image: image selection which must be in ["PAN", "RGBNIR", + "PS-RGB", "PS-RGBNIR", "SAR-Intensity"] + 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. + api_key: a RadiantEarth MLHub API key to use for downloading the dataset + + Raises: + RuntimeError: if ``download=False`` but dataset is missing + """ + self.root = root + self.image = image # For testing + + self.filename = self.imagery[image] + self.transforms = transforms + + if download: + self.__download(api_key) + + self.files = self._load_files(os.path.join(root, self.dataset_id)) + + def __download(self, api_key: Optional[str] = None) -> None: + """Download the dataset and extract it. + + Args: + api_key: a RadiantEarth MLHub API key to use for downloading the dataset + + Raises: + RuntimeError: if download doesn't work correctly or checksums don't match + """ + if os.path.exists( + os.path.join( + self.root, self.dataset_id, self.collections[0], "collection.json" + ) + ): + print("Files already downloaded and verified") + return + + download_radiant_mlhub_dataset(self.dataset_id, self.root, api_key) + + class SpaceNet7(SpaceNet): """SpaceNet 7: Multi-Temporal Urban Development Challenge. @@ -1155,13 +1271,6 @@ class SpaceNet7(SpaceNet): * https://arxiv.org/abs/2102.04420 - .. note:: - - This dataset requires the following additional library to be installed: - - * `radiant-mlhub `_ to download the - imagery and labels from the Radiant Earth MLHub - .. versionadded:: 0.2 """