From d6cb939427f5854def26be845a5ef2bdb82aacfc Mon Sep 17 00:00:00 2001 From: davrob Date: Fri, 21 Feb 2025 20:08:26 +0000 Subject: [PATCH] Making GeoDatasets use seperate values for x and y resolution --- tests/datamodules/test_geo.py | 2 +- tests/datasets/test_cbf.py | 2 +- tests/datasets/test_geo.py | 35 +++++++++++---------- tests/datasets/test_kakuma_aerial.py | 0 tests/datasets/test_sentinel.py | 2 +- tests/datasets/test_splits.py | 2 +- tests/samplers/test_batch.py | 2 +- tests/samplers/test_single.py | 2 +- torchgeo/datasets/agb_live_woody_density.py | 2 +- torchgeo/datasets/astergdem.py | 2 +- torchgeo/datasets/cbf.py | 2 +- torchgeo/datasets/cdl.py | 2 +- torchgeo/datasets/chesapeake.py | 4 +-- torchgeo/datasets/cms_mangrove_canopy.py | 2 +- torchgeo/datasets/eddmaps.py | 2 +- torchgeo/datasets/enmap.py | 2 +- torchgeo/datasets/enviroatlas.py | 2 +- torchgeo/datasets/esri2020.py | 2 +- torchgeo/datasets/eudem.py | 2 +- torchgeo/datasets/eurocrops.py | 2 +- torchgeo/datasets/gbif.py | 2 +- torchgeo/datasets/geo.py | 26 +++++++-------- torchgeo/datasets/globbiomass.py | 2 +- torchgeo/datasets/inaturalist.py | 2 +- torchgeo/datasets/iobench.py | 2 +- torchgeo/datasets/l7irish.py | 4 +-- torchgeo/datasets/l8biome.py | 2 +- torchgeo/datasets/landcoverai.py | 2 +- torchgeo/datasets/landsat.py | 2 +- torchgeo/datasets/mmflood.py | 4 +-- torchgeo/datasets/nccm.py | 2 +- torchgeo/datasets/nlcd.py | 2 +- torchgeo/datasets/openbuildings.py | 7 ++--- torchgeo/datasets/sentinel.py | 6 ++-- torchgeo/datasets/south_america_soybean.py | 2 +- torchgeo/models/scale_mae.py | 2 +- 36 files changed, 71 insertions(+), 71 deletions(-) create mode 100644 tests/datasets/test_kakuma_aerial.py diff --git a/tests/datamodules/test_geo.py b/tests/datamodules/test_geo.py index 4e5431c684f..f924914d545 100644 --- a/tests/datamodules/test_geo.py +++ b/tests/datamodules/test_geo.py @@ -28,7 +28,7 @@ def __init__( super().__init__() for i in range(length): self.index.insert(i, (0, 1, 2, 3, 4, 5)) - self.res = 1 + self.res = (1, 1) def __getitem__(self, query: BoundingBox) -> dict[str, Any]: image = torch.arange(3 * 2 * 2, dtype=torch.float).view(3, 2, 2) diff --git a/tests/datasets/test_cbf.py b/tests/datasets/test_cbf.py index 17adb1961cc..425b913e266 100644 --- a/tests/datasets/test_cbf.py +++ b/tests/datasets/test_cbf.py @@ -37,7 +37,7 @@ def dataset( root = tmp_path transforms = nn.Identity() return CanadianBuildingFootprints( - root, res=0.1, transforms=transforms, download=True, checksum=True + root, res=(0.1, 0.1), transforms=transforms, download=True, checksum=True ) def test_getitem(self, dataset: CanadianBuildingFootprints) -> None: diff --git a/tests/datasets/test_geo.py b/tests/datasets/test_geo.py index 71e07f6928b..1d44fca39ca 100644 --- a/tests/datasets/test_geo.py +++ b/tests/datasets/test_geo.py @@ -37,7 +37,7 @@ def __init__( self, bounds: BoundingBox = BoundingBox(0, 1, 2, 3, 4, 5), crs: CRS = CRS.from_epsg(4087), - res: float = 1, + res: tuple[float, float] = (1, 1), paths: str | os.PathLike[str] | Iterable[str | os.PathLike[str]] | None = None, ) -> None: super().__init__() @@ -324,7 +324,8 @@ def test_getitem_separate_files(self, sentinel: Sentinel2) -> None: def test_reprojection(self, naip: NAIP) -> None: naip2 = NAIP(naip.paths, crs='EPSG:4326') assert naip.crs != naip2.crs - assert not math.isclose(naip.res, naip2.res) + assert not math.isclose(naip.res[0], naip2.res[0]) + assert not math.isclose(naip.res[1], naip2.res[1]) @pytest.mark.parametrize('dtype', ['uint16', 'uint32']) def test_getitem_uint_dtype(self, dtype: str) -> None: @@ -381,14 +382,14 @@ class TestVectorDataset: def dataset(self) -> CustomVectorDataset: root = os.path.join('tests', 'data', 'vector') transforms = nn.Identity() - return CustomVectorDataset(root, res=0.1, transforms=transforms) + return CustomVectorDataset(root, res=(0.1, 0.1), transforms=transforms) @pytest.fixture(scope='class') def multilabel(self) -> CustomVectorDataset: root = os.path.join('tests', 'data', 'vector') transforms = nn.Identity() return CustomVectorDataset( - root, res=0.1, transforms=transforms, label_name='label_id' + root, res=(0.1, 0.1), transforms=transforms, label_name='label_id' ) def test_getitem(self, dataset: CustomVectorDataset) -> None: @@ -562,7 +563,7 @@ def test_different_crs_12(self) -> None: ds = IntersectionDataset(ds1, ds2) sample = ds[ds.bounds] assert ds1.crs == ds2.crs == ds.crs == CRS.from_epsg(4087) - assert ds1.res == ds2.res == ds.res == 2 + assert ds1.res == ds2.res == ds.res == (2, 2) assert len(ds1) == len(ds2) == len(ds) == 1 assert isinstance(sample['image'], torch.Tensor) @@ -573,7 +574,7 @@ def test_different_crs_12_3(self) -> None: ds = (ds1 & ds2) & ds3 sample = ds[ds.bounds] assert ds1.crs == ds2.crs == ds3.crs == ds.crs == CRS.from_epsg(4087) - assert ds1.res == ds2.res == ds3.res == ds.res == 2 + assert ds1.res == ds2.res == ds3.res == ds.res == (2, 2) assert len(ds1) == len(ds2) == len(ds3) == len(ds) == 1 assert isinstance(sample['image'], torch.Tensor) @@ -584,7 +585,7 @@ def test_different_crs_1_23(self) -> None: ds = ds1 & (ds2 & ds3) sample = ds[ds.bounds] assert ds1.crs == ds2.crs == ds3.crs == ds.crs == CRS.from_epsg(4087) - assert ds1.res == ds2.res == ds3.res == ds.res == 2 + assert ds1.res == ds2.res == ds3.res == ds.res == (2, 2) assert len(ds1) == len(ds2) == len(ds3) == len(ds) == 1 assert isinstance(sample['image'], torch.Tensor) @@ -594,7 +595,7 @@ def test_different_res_12(self) -> None: ds = IntersectionDataset(ds1, ds2) sample = ds[ds.bounds] assert ds1.crs == ds2.crs == ds.crs == CRS.from_epsg(4087) - assert ds1.res == ds2.res == ds.res == 2 + assert ds1.res == ds2.res == ds.res == (2, 2) assert len(ds1) == len(ds2) == len(ds) == 1 assert isinstance(sample['image'], torch.Tensor) @@ -605,7 +606,7 @@ def test_different_res_12_3(self) -> None: ds = (ds1 & ds2) & ds3 sample = ds[ds.bounds] assert ds1.crs == ds2.crs == ds3.crs == ds.crs == CRS.from_epsg(4087) - assert ds1.res == ds2.res == ds3.res == ds.res == 2 + assert ds1.res == ds2.res == ds3.res == ds.res == (2, 2) assert len(ds1) == len(ds2) == len(ds3) == len(ds) == 1 assert isinstance(sample['image'], torch.Tensor) @@ -616,7 +617,7 @@ def test_different_res_1_23(self) -> None: ds = ds1 & (ds2 & ds3) sample = ds[ds.bounds] assert ds1.crs == ds2.crs == ds3.crs == ds.crs == CRS.from_epsg(4087) - assert ds1.res == ds2.res == ds3.res == ds.res == 2 + assert ds1.res == ds2.res == ds3.res == ds.res == (2, 2) assert len(ds1) == len(ds2) == len(ds3) == len(ds) == 1 assert isinstance(sample['image'], torch.Tensor) @@ -625,7 +626,7 @@ def test_point_dataset(self) -> None: ds2 = CustomGeoDataset(BoundingBox(1, 1, 3, 3, 5, 5)) ds = IntersectionDataset(ds1, ds2) assert ds1.crs == ds2.crs == ds.crs == CRS.from_epsg(4087) - assert ds1.res == ds2.res == ds.res == 1 + assert ds1.res == ds2.res == ds.res == (1, 1) assert len(ds1) == len(ds2) == len(ds) == 1 def test_no_overlap(self) -> None: @@ -678,7 +679,7 @@ def test_different_crs_12(self) -> None: ds = UnionDataset(ds1, ds2) sample = ds[ds.bounds] assert ds1.crs == ds2.crs == ds.crs == CRS.from_epsg(4087) - assert ds1.res == ds2.res == ds.res == 2 + assert ds1.res == ds2.res == ds.res == (2, 2) assert len(ds1) == len(ds2) == 1 assert len(ds) == 2 assert isinstance(sample['image'], torch.Tensor) @@ -690,7 +691,7 @@ def test_different_crs_12_3(self) -> None: ds = (ds1 | ds2) | ds3 sample = ds[ds.bounds] assert ds1.crs == ds2.crs == ds3.crs == ds.crs == CRS.from_epsg(4087) - assert ds1.res == ds2.res == ds3.res == ds.res == 2 + assert ds1.res == ds2.res == ds3.res == ds.res == (2, 2) assert len(ds1) == len(ds2) == len(ds3) == 1 assert len(ds) == 3 assert isinstance(sample['image'], torch.Tensor) @@ -702,7 +703,7 @@ def test_different_crs_1_23(self) -> None: ds = ds1 | (ds2 | ds3) sample = ds[ds.bounds] assert ds1.crs == ds2.crs == ds3.crs == ds.crs == CRS.from_epsg(4087) - assert ds1.res == ds2.res == ds3.res == ds.res == 2 + assert ds1.res == ds2.res == ds3.res == ds.res == (2, 2) assert len(ds1) == len(ds2) == len(ds3) == 1 assert len(ds) == 3 assert isinstance(sample['image'], torch.Tensor) @@ -713,7 +714,7 @@ def test_different_res_12(self) -> None: ds = UnionDataset(ds1, ds2) sample = ds[ds.bounds] assert ds1.crs == ds2.crs == ds.crs == CRS.from_epsg(4087) - assert ds1.res == ds2.res == ds.res == 2 + assert ds1.res == ds2.res == ds.res == (2, 2) assert len(ds1) == len(ds2) == 1 assert len(ds) == 2 assert isinstance(sample['image'], torch.Tensor) @@ -725,7 +726,7 @@ def test_different_res_12_3(self) -> None: ds = (ds1 | ds2) | ds3 sample = ds[ds.bounds] assert ds1.crs == ds2.crs == ds3.crs == ds.crs == CRS.from_epsg(4087) - assert ds1.res == ds2.res == ds3.res == ds.res == 2 + assert ds1.res == ds2.res == ds3.res == ds.res == (2, 2) assert len(ds1) == len(ds2) == len(ds3) == 1 assert len(ds) == 3 assert isinstance(sample['image'], torch.Tensor) @@ -737,7 +738,7 @@ def test_different_res_1_23(self) -> None: ds = ds1 | (ds2 | ds3) sample = ds[ds.bounds] assert ds1.crs == ds2.crs == ds3.crs == ds.crs == CRS.from_epsg(4087) - assert ds1.res == ds2.res == ds3.res == ds.res == 2 + assert ds1.res == ds2.res == ds3.res == ds.res == (2, 2) assert len(ds1) == len(ds2) == len(ds3) == 1 assert len(ds) == 3 assert isinstance(sample['image'], torch.Tensor) diff --git a/tests/datasets/test_kakuma_aerial.py b/tests/datasets/test_kakuma_aerial.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/datasets/test_sentinel.py b/tests/datasets/test_sentinel.py index ee4933b44f7..8fe623d6483 100644 --- a/tests/datasets/test_sentinel.py +++ b/tests/datasets/test_sentinel.py @@ -105,7 +105,7 @@ class TestSentinel2: @pytest.fixture def dataset(self) -> Sentinel2: root = os.path.join('tests', 'data', 'sentinel2') - res = 10 + res = (10.0, 10.0) bands = ['B02', 'B03', 'B04', 'B08'] transforms = nn.Identity() return Sentinel2(root, res=res, bands=bands, transforms=transforms) diff --git a/tests/datasets/test_splits.py b/tests/datasets/test_splits.py index 2977586ddb4..5f783dccdff 100644 --- a/tests/datasets/test_splits.py +++ b/tests/datasets/test_splits.py @@ -41,7 +41,7 @@ def __init__( self, items: list[tuple[BoundingBox, str]] = [(BoundingBox(0, 1, 0, 1, 0, 40), '')], crs: CRS = CRS.from_epsg(3005), - res: float = 1, + res: tuple[float, float] = (1, 1), ) -> None: super().__init__() for box, content in items: diff --git a/tests/samplers/test_batch.py b/tests/samplers/test_batch.py index 199239a0e79..ed44780e8e2 100644 --- a/tests/samplers/test_batch.py +++ b/tests/samplers/test_batch.py @@ -28,7 +28,7 @@ def __len__(self) -> int: class CustomGeoDataset(GeoDataset): - def __init__(self, crs: CRS = CRS.from_epsg(3005), res: float = 10) -> None: + def __init__(self, crs: CRS = CRS.from_epsg(3005), res: tuple[float, float] = (10, 10)) -> None: super().__init__() self._crs = crs self.res = res diff --git a/tests/samplers/test_single.py b/tests/samplers/test_single.py index e2c829f1b9e..2abcc503002 100644 --- a/tests/samplers/test_single.py +++ b/tests/samplers/test_single.py @@ -35,7 +35,7 @@ def __len__(self) -> int: class CustomGeoDataset(GeoDataset): - def __init__(self, crs: CRS = CRS.from_epsg(3005), res: float = 10) -> None: + def __init__(self, crs: CRS = CRS.from_epsg(3005), res: tuple[float, float] = (10, 10)) -> None: super().__init__() self._crs = crs self.res = res diff --git a/torchgeo/datasets/agb_live_woody_density.py b/torchgeo/datasets/agb_live_woody_density.py index aaef8db9751..44bcbba922d 100644 --- a/torchgeo/datasets/agb_live_woody_density.py +++ b/torchgeo/datasets/agb_live_woody_density.py @@ -59,7 +59,7 @@ def __init__( self, paths: Path | Iterable[Path] = 'data', crs: CRS | None = None, - res: float | None = None, + res: tuple[float, float] | None = None, transforms: Callable[[dict[str, Any]], dict[str, Any]] | None = None, download: bool = False, cache: bool = True, diff --git a/torchgeo/datasets/astergdem.py b/torchgeo/datasets/astergdem.py index c4ef23061b8..f7da16e3e79 100644 --- a/torchgeo/datasets/astergdem.py +++ b/torchgeo/datasets/astergdem.py @@ -50,7 +50,7 @@ def __init__( self, paths: Path | list[Path] = 'data', crs: CRS | None = None, - res: float | None = None, + res: tuple[float, float] | None = None, transforms: Callable[[dict[str, Any]], dict[str, Any]] | None = None, cache: bool = True, ) -> None: diff --git a/torchgeo/datasets/cbf.py b/torchgeo/datasets/cbf.py index 3c986eb44c1..2f645ee861d 100644 --- a/torchgeo/datasets/cbf.py +++ b/torchgeo/datasets/cbf.py @@ -64,7 +64,7 @@ def __init__( self, paths: Path | Iterable[Path] = 'data', crs: CRS | None = None, - res: float = 0.00001, + res: tuple[float, float] = (0.00001, 0.00001), transforms: Callable[[dict[str, Any]], dict[str, Any]] | None = None, download: bool = False, checksum: bool = False, diff --git a/torchgeo/datasets/cdl.py b/torchgeo/datasets/cdl.py index 2de5719beb0..1d467240151 100644 --- a/torchgeo/datasets/cdl.py +++ b/torchgeo/datasets/cdl.py @@ -209,7 +209,7 @@ def __init__( self, paths: Path | Iterable[Path] = 'data', crs: CRS | None = None, - res: float | None = None, + res: tuple[float, float] | None = None, years: list[int] = [2023], classes: list[int] = list(cmap.keys()), transforms: Callable[[dict[str, Any]], dict[str, Any]] | None = None, diff --git a/torchgeo/datasets/chesapeake.py b/torchgeo/datasets/chesapeake.py index 459d096043c..991207e610f 100644 --- a/torchgeo/datasets/chesapeake.py +++ b/torchgeo/datasets/chesapeake.py @@ -128,7 +128,7 @@ def __init__( self, paths: Path | Iterable[Path] = 'data', crs: CRS | None = None, - res: float | None = None, + res: tuple[float, float] | None = None, transforms: Callable[[dict[str, Any]], dict[str, Any]] | None = None, cache: bool = True, download: bool = False, @@ -351,7 +351,7 @@ class ChesapeakeCVPR(GeoDataset): } crs = CRS.from_epsg(3857) - res = 1 + res = (1, 1) lc_cmap: ClassVar[dict[int, tuple[int, int, int, int]]] = { 0: (0, 0, 0, 0), diff --git a/torchgeo/datasets/cms_mangrove_canopy.py b/torchgeo/datasets/cms_mangrove_canopy.py index 681d5026f25..c2820b53241 100644 --- a/torchgeo/datasets/cms_mangrove_canopy.py +++ b/torchgeo/datasets/cms_mangrove_canopy.py @@ -171,7 +171,7 @@ def __init__( self, paths: Path | list[Path] = 'data', crs: CRS | None = None, - res: float | None = None, + res: tuple[float, float] | None = None, measurement: str = 'agb', country: str = all_countries[0], transforms: Callable[[dict[str, Any]], dict[str, Any]] | None = None, diff --git a/torchgeo/datasets/eddmaps.py b/torchgeo/datasets/eddmaps.py index d3a046993a1..7345141b97e 100644 --- a/torchgeo/datasets/eddmaps.py +++ b/torchgeo/datasets/eddmaps.py @@ -39,7 +39,7 @@ class EDDMapS(GeoDataset): .. versionadded:: 0.3 """ - res = 0 + res = (0, 0) _crs = CRS.from_epsg(4326) # Lat/Lon def __init__(self, root: Path = 'data') -> None: diff --git a/torchgeo/datasets/enmap.py b/torchgeo/datasets/enmap.py index 1994c5ebb16..df7d3468a15 100644 --- a/torchgeo/datasets/enmap.py +++ b/torchgeo/datasets/enmap.py @@ -301,7 +301,7 @@ def __init__( self, paths: Path | Iterable[Path] = 'data', crs: CRS | None = None, - res: float | None = None, + res: tuple[float, float] | None = None, bands: Sequence[str] | None = None, transforms: Callable[[dict[str, Any]], dict[str, Any]] | None = None, cache: bool = True, diff --git a/torchgeo/datasets/enviroatlas.py b/torchgeo/datasets/enviroatlas.py index b8af4aef70e..31409ce75ae 100644 --- a/torchgeo/datasets/enviroatlas.py +++ b/torchgeo/datasets/enviroatlas.py @@ -52,7 +52,7 @@ class EnviroAtlas(GeoDataset): md5 = 'bfe601be21c7c001315fc6154be8ef14' crs = CRS.from_epsg(3857) - res = 1 + res = (1, 1) valid_prior_layers = ('prior', 'prior_no_osm_no_buildings') diff --git a/torchgeo/datasets/esri2020.py b/torchgeo/datasets/esri2020.py index 197272d6b48..b4a66a36a7f 100644 --- a/torchgeo/datasets/esri2020.py +++ b/torchgeo/datasets/esri2020.py @@ -71,7 +71,7 @@ def __init__( self, paths: Path | Iterable[Path] = 'data', crs: CRS | None = None, - res: float | None = None, + res: tuple[float, float] | None = None, transforms: Callable[[dict[str, Any]], dict[str, Any]] | None = None, cache: bool = True, download: bool = False, diff --git a/torchgeo/datasets/eudem.py b/torchgeo/datasets/eudem.py index 5a9af7f6fa3..ab1f4bac6c7 100644 --- a/torchgeo/datasets/eudem.py +++ b/torchgeo/datasets/eudem.py @@ -77,7 +77,7 @@ def __init__( self, paths: Path | Iterable[Path] = 'data', crs: CRS | None = None, - res: float | None = None, + res: tuple[float, float] | None = None, transforms: Callable[[dict[str, Any]], dict[str, Any]] | None = None, cache: bool = True, checksum: bool = False, diff --git a/torchgeo/datasets/eurocrops.py b/torchgeo/datasets/eurocrops.py index 8832905c2d6..eb26a0abb44 100644 --- a/torchgeo/datasets/eurocrops.py +++ b/torchgeo/datasets/eurocrops.py @@ -87,7 +87,7 @@ def __init__( self, paths: Path | Iterable[Path] = 'data', crs: CRS = CRS.from_epsg(4326), - res: float = 0.00001, + res: tuple[float, float] = (0.00001, 0.00001), classes: list[str] | None = None, transforms: Callable[[dict[str, Any]], dict[str, Any]] | None = None, download: bool = False, diff --git a/torchgeo/datasets/gbif.py b/torchgeo/datasets/gbif.py index 3e8cfb6c883..bb935a2d3c7 100644 --- a/torchgeo/datasets/gbif.py +++ b/torchgeo/datasets/gbif.py @@ -77,7 +77,7 @@ class GBIF(GeoDataset): .. versionadded:: 0.3 """ - res = 0 + res = (0, 0) _crs = CRS.from_epsg(4326) # Lat/Lon def __init__(self, root: Path = 'data') -> None: diff --git a/torchgeo/datasets/geo.py b/torchgeo/datasets/geo.py index 26a035d427d..99f479062f3 100644 --- a/torchgeo/datasets/geo.py +++ b/torchgeo/datasets/geo.py @@ -88,7 +88,7 @@ class GeoDataset(Dataset[dict[str, Any]], abc.ABC): paths: Path | Iterable[Path] _crs = CRS.from_epsg(4326) - _res = 0.0 + _res = (0.0, 0.0) #: Glob expression used to search for files. #: @@ -268,7 +268,7 @@ def crs(self, new_crs: CRS) -> None: self.index = new_index @property - def res(self) -> float: + def res(self) -> tuple[float, float]: """Resolution of the dataset in units of CRS. Returns: @@ -277,7 +277,7 @@ def res(self) -> float: return self._res @res.setter - def res(self, new_res: float) -> None: + def res(self, new_res: tuple[float, float]) -> None: """Change the resolution of a GeoDataset. Args: @@ -416,7 +416,7 @@ def __init__( self, paths: Path | Iterable[Path] = 'data', crs: CRS | None = None, - res: float | None = None, + res: tuple[float, float] | None = None, bands: Sequence[str] | None = None, transforms: Callable[[dict[str, Any]], dict[str, Any]] | None = None, cache: bool = True, @@ -467,7 +467,7 @@ def __init__( with WarpedVRT(src, crs=crs) as vrt: minx, miny, maxx, maxy = vrt.bounds if res is None: - res = vrt.res[0] + res = vrt.res except rasterio.errors.RasterioIOError: # Skip files that rasterio is unable to read continue @@ -505,7 +505,7 @@ def __init__( raise AssertionError(msg) self._crs = cast(CRS, crs) - self._res = cast(float, res) + self._res = cast(tuple[float, float], res) def __getitem__(self, query: BoundingBox) -> dict[str, Any]: """Retrieve image/mask and metadata indexed by query. @@ -655,7 +655,7 @@ def __init__( self, paths: Path | Iterable[Path] = 'data', crs: CRS | None = None, - res: float = 0.0001, + res: tuple[float, float] = (0.0001, 0.0001), transforms: Callable[[dict[str, Any]], dict[str, Any]] | None = None, label_name: str | None = None, ) -> None: @@ -760,8 +760,8 @@ def __getitem__(self, query: BoundingBox) -> dict[str, Any]: shapes.append((shape, label)) # Rasterize geometries - width = (query.maxx - query.minx) / self.res - height = (query.maxy - query.miny) / self.res + width = (query.maxx - query.minx) / self.res[0] + height = (query.maxy - query.miny) / self.res[1] transform = rasterio.transform.from_bounds( query.minx, query.miny, query.maxx, query.maxy, width, height ) @@ -1065,7 +1065,7 @@ def crs(self, new_crs: CRS) -> None: self.datasets[1].crs = new_crs @property - def res(self) -> float: + def res(self) -> tuple[float, float]: """Resolution of both datasets in units of CRS. Returns: @@ -1074,7 +1074,7 @@ def res(self) -> float: return self._res @res.setter - def res(self, new_res: float) -> None: + def res(self, new_res: tuple[float, float]) -> None: """Change the resolution of both datasets. Args: @@ -1220,7 +1220,7 @@ def crs(self, new_crs: CRS) -> None: self.datasets[1].crs = new_crs @property - def res(self) -> float: + def res(self) -> tuple[float, float]: """Resolution of both datasets in units of CRS. Returns: @@ -1229,7 +1229,7 @@ def res(self) -> float: return self._res @res.setter - def res(self, new_res: float) -> None: + def res(self, new_res: tuple[float, float]) -> None: """Change the resolution of both datasets. Args: diff --git a/torchgeo/datasets/globbiomass.py b/torchgeo/datasets/globbiomass.py index c214fbba205..9c9e4d77b9e 100644 --- a/torchgeo/datasets/globbiomass.py +++ b/torchgeo/datasets/globbiomass.py @@ -139,7 +139,7 @@ def __init__( self, paths: Path | Iterable[Path] = 'data', crs: CRS | None = None, - res: float | None = None, + res: tuple[float, float] | None = None, measurement: str = 'agb', transforms: Callable[[dict[str, Any]], dict[str, Any]] | None = None, cache: bool = True, diff --git a/torchgeo/datasets/inaturalist.py b/torchgeo/datasets/inaturalist.py index bb5cfe3c8df..3c1b3f2f900 100644 --- a/torchgeo/datasets/inaturalist.py +++ b/torchgeo/datasets/inaturalist.py @@ -31,7 +31,7 @@ class INaturalist(GeoDataset): .. versionadded:: 0.3 """ - res = 0 + res = (0, 0) _crs = CRS.from_epsg(4326) # Lat/Lon def __init__(self, root: Path = 'data') -> None: diff --git a/torchgeo/datasets/iobench.py b/torchgeo/datasets/iobench.py index 608a9ccc17a..21a1bb52137 100644 --- a/torchgeo/datasets/iobench.py +++ b/torchgeo/datasets/iobench.py @@ -53,7 +53,7 @@ def __init__( root: Path = 'data', split: str = 'preprocessed', crs: CRS | None = None, - res: float | None = None, + res: tuple[float, float] | None = None, bands: Sequence[str] | None = [*Landsat9.default_bands, 'SR_QA_AEROSOL'], classes: list[int] = [0], transforms: Callable[[dict[str, Any]], dict[str, Any]] | None = None, diff --git a/torchgeo/datasets/l7irish.py b/torchgeo/datasets/l7irish.py index d39f225ed75..861ddb7224a 100644 --- a/torchgeo/datasets/l7irish.py +++ b/torchgeo/datasets/l7irish.py @@ -69,7 +69,7 @@ def __init__( self, paths: Path | Iterable[Path] = 'data', crs: CRS | None = None, - res: float | None = None, + res: tuple[float, float] | None = None, bands: Sequence[str] | None = None, transforms: Callable[[dict[str, Any]], dict[str, Any]] | None = None, cache: bool = True, @@ -177,7 +177,7 @@ def __init__( self, paths: Path | Iterable[Path] = 'data', crs: CRS | None = CRS.from_epsg(3857), - res: float | None = None, + res: tuple[float, float] | None = None, bands: Sequence[str] = L7IrishImage.all_bands, transforms: Callable[[dict[str, Any]], dict[str, Any]] | None = None, cache: bool = True, diff --git a/torchgeo/datasets/l8biome.py b/torchgeo/datasets/l8biome.py index e53c403b713..eb61d5e5d56 100644 --- a/torchgeo/datasets/l8biome.py +++ b/torchgeo/datasets/l8biome.py @@ -134,7 +134,7 @@ def __init__( self, paths: Path | Iterable[Path], crs: CRS | None = CRS.from_epsg(3857), - res: float | None = None, + res: tuple[float, float] | None = None, bands: Sequence[str] = L8BiomeImage.all_bands, transforms: Callable[[dict[str, Any]], dict[str, Any]] | None = None, cache: bool = True, diff --git a/torchgeo/datasets/landcoverai.py b/torchgeo/datasets/landcoverai.py index d2c0acf88e7..d21dba494d3 100644 --- a/torchgeo/datasets/landcoverai.py +++ b/torchgeo/datasets/landcoverai.py @@ -206,7 +206,7 @@ def __init__( self, root: Path = 'data', crs: CRS | None = None, - res: float | None = None, + res: tuple[float, float] | None = None, transforms: Callable[[dict[str, Any]], dict[str, Any]] | None = None, cache: bool = True, download: bool = False, diff --git a/torchgeo/datasets/landsat.py b/torchgeo/datasets/landsat.py index acef311712a..465e66818a2 100644 --- a/torchgeo/datasets/landsat.py +++ b/torchgeo/datasets/landsat.py @@ -62,7 +62,7 @@ def __init__( self, paths: Path | Iterable[Path] = 'data', crs: CRS | None = None, - res: float | None = None, + res: tuple[float, float] | None = None, bands: Sequence[str] | None = None, transforms: Callable[[dict[str, Any]], dict[str, Any]] | None = None, cache: bool = True, diff --git a/torchgeo/datasets/mmflood.py b/torchgeo/datasets/mmflood.py index ec975855fb0..0f9812399bd 100644 --- a/torchgeo/datasets/mmflood.py +++ b/torchgeo/datasets/mmflood.py @@ -31,7 +31,7 @@ def __init__( content: Literal['s1_raw', 'DEM', 'hydro', 'mask'], root: Path = 'data', crs: CRS | None = None, - res: float | None = None, + res: tuple[float, float] | None = None, transforms: Callable[[dict[str, Tensor]], dict[str, Tensor]] | None = None, cache: bool = False, ) -> None: @@ -145,7 +145,7 @@ def __init__( self, root: Path = 'data', crs: CRS | None = None, - res: float | None = None, + res: tuple[float, float] | None = None, split: str = 'train', include_dem: bool = False, include_hydro: bool = False, diff --git a/torchgeo/datasets/nccm.py b/torchgeo/datasets/nccm.py index 96633b2e35b..3bf1a2f9e52 100644 --- a/torchgeo/datasets/nccm.py +++ b/torchgeo/datasets/nccm.py @@ -85,7 +85,7 @@ def __init__( self, paths: Path | Iterable[Path] = 'data', crs: CRS | None = None, - res: float | None = None, + res: tuple[float, float] | None = None, years: list[int] = [2019], transforms: Callable[[dict[str, Any]], dict[str, Any]] | None = None, cache: bool = True, diff --git a/torchgeo/datasets/nlcd.py b/torchgeo/datasets/nlcd.py index 681f0e242bc..3a1f560cdeb 100644 --- a/torchgeo/datasets/nlcd.py +++ b/torchgeo/datasets/nlcd.py @@ -134,7 +134,7 @@ def __init__( self, paths: Path | Iterable[Path] = 'data', crs: CRS | None = None, - res: float | None = None, + res: tuple[float, float] | None = None, years: list[int] = [2023], classes: list[int] = list(cmap.keys()), transforms: Callable[[dict[str, Any]], dict[str, Any]] | None = None, diff --git a/torchgeo/datasets/openbuildings.py b/torchgeo/datasets/openbuildings.py index 292dc274c32..9d759d6adae 100644 --- a/torchgeo/datasets/openbuildings.py +++ b/torchgeo/datasets/openbuildings.py @@ -209,7 +209,7 @@ def __init__( self, paths: Path | Iterable[Path] = 'data', crs: CRS | None = None, - res: float = 0.0001, + res: tuple[float, float] = (0.0001, 0.0001), transforms: Callable[[dict[str, Any]], dict[str, Any]] | None = None, checksum: bool = False, ) -> None: @@ -233,7 +233,6 @@ def __init__( self.paths = paths self.res = res self.checksum = checksum - self.res = res self.transforms = transforms self._verify() @@ -314,8 +313,8 @@ def __getitem__(self, query: BoundingBox) -> dict[str, Any]: shapes = self._filter_geometries(query, filepaths) # Rasterize geometries - width = (query.maxx - query.minx) / self.res - height = (query.maxy - query.miny) / self.res + width = (query.maxx - query.minx) / self.res[0] + height = (query.maxy - query.miny) / self.res[1] transform = rasterio.transform.from_bounds( query.minx, query.miny, query.maxx, query.maxy, width, height ) diff --git a/torchgeo/datasets/sentinel.py b/torchgeo/datasets/sentinel.py index 79637931adb..832f1c3f7b9 100644 --- a/torchgeo/datasets/sentinel.py +++ b/torchgeo/datasets/sentinel.py @@ -144,7 +144,7 @@ def __init__( self, paths: Path | list[Path] = 'data', crs: CRS | None = None, - res: float = 10, + res: tuple[float, float] = (10, 10), bands: Sequence[str] = ['VV', 'VH'], transforms: Callable[[dict[str, Any]], dict[str, Any]] | None = None, cache: bool = True, @@ -300,7 +300,7 @@ def __init__( self, paths: Path | Iterable[Path] = 'data', crs: CRS | None = None, - res: float = 10, + res: tuple[float, float] = (10, 10), bands: Sequence[str] | None = None, transforms: Callable[[dict[str, Any]], dict[str, Any]] | None = None, cache: bool = True, @@ -326,7 +326,7 @@ def __init__( """ bands = bands or self.all_bands self.filename_glob = self.filename_glob.format(bands[0]) - self.filename_regex = self.filename_regex.format(res) + self.filename_regex = self.filename_regex.format(res[0]) super().__init__(paths, crs, res, bands, transforms, cache) diff --git a/torchgeo/datasets/south_america_soybean.py b/torchgeo/datasets/south_america_soybean.py index adbde74d6cb..b3037b5dcdc 100644 --- a/torchgeo/datasets/south_america_soybean.py +++ b/torchgeo/datasets/south_america_soybean.py @@ -75,7 +75,7 @@ def __init__( self, paths: Path | Iterable[Path] = 'data', crs: CRS | None = None, - res: float | None = None, + res: tuple[float, float] | None = None, years: list[int] = [2021], transforms: Callable[[dict[str, Any]], dict[str, Any]] | None = None, cache: bool = True, diff --git a/torchgeo/models/scale_mae.py b/torchgeo/models/scale_mae.py index 91caa903c30..38bcc598664 100644 --- a/torchgeo/models/scale_mae.py +++ b/torchgeo/models/scale_mae.py @@ -102,7 +102,7 @@ class ScaleMAE(VisionTransformer): * https://arxiv.org/abs/2212.14532 """ - def __init__(self, res: float = 1.0, *args: Any, **kwargs: Any) -> None: + def __init__(self, res: tuple[float, float] = (1.0, 1.0), *args: Any, **kwargs: Any) -> None: """Initialize a new ScaleMAE model. Args: