diff --git a/rio_tiler/io/xarray.py b/rio_tiler/io/xarray.py index 7541458c..d8916d62 100644 --- a/rio_tiler/io/xarray.py +++ b/rio_tiler/io/xarray.py @@ -83,11 +83,14 @@ def __attrs_post_init__(self): "Dataset doesn't have CRS information, please add it before using rio-tiler (e.g. `ds.rio.write_crs('epsg:4326', inplace=True)`)" ) + # adds half x/y resolution on each values + # https://github.com/corteva/rioxarray/issues/645#issuecomment-1461070634 + xres, yres = map(abs, self.input.rio.resolution()) if self.crs == WGS84_CRS and ( - round(self.bounds[0]) < -180 - or round(self.bounds[1]) < -90 - or round(self.bounds[2]) > 180 - or round(self.bounds[3]) > 90 + self.bounds[0] + xres / 2 < -180 + or self.bounds[1] + yres / 2 < -90 + or self.bounds[2] - xres / 2 > 180 + or self.bounds[3] - yres / 2 > 90 ): raise InvalidGeographicBounds( f"Invalid geographic bounds: {self.bounds}. Must be within (-180, -90, 180, 90)." @@ -116,12 +119,16 @@ def maxzoom(self): @property def band_names(self) -> List[str]: """Return list of `band names` in DataArray.""" - return [str(band) for d in self._dims for band in self.input[d].values] + return [str(band) for d in self._dims for band in self.input[d].values] or [ + "value" + ] def info(self) -> Info: """Return xarray.DataArray info.""" - bands = [str(band) for d in self._dims for band in self.input[d].values] - metadata = [band.attrs for d in self._dims for band in self.input[d]] + bands = [str(band) for d in self._dims for band in self.input[d].values] or [ + "value" + ] + metadata = [band.attrs for d in self._dims for band in self.input[d]] or [{}] meta = { "bounds": self.bounds, diff --git a/tests/test_io_xarray.py b/tests/test_io_xarray.py index b6b907f4..85c999b4 100644 --- a/tests/test_io_xarray.py +++ b/tests/test_io_xarray.py @@ -485,3 +485,43 @@ def test_xarray_reader_invalid_bounds_crs(): data.rio.write_crs("epsg:4326", inplace=True) with XarrayReader(data): pass + + +def test_xarray_reader_no_dims(): + """test XarrayReader with 2D dataset.""" + arr = numpy.arange(0.0, 33 * 35).reshape(33, 35) + data = xarray.DataArray( + arr, + dims=("y", "x"), + coords={ + "x": numpy.arange(-170, 180, 10), + "y": numpy.arange(-80, 85, 5), + }, + ) + data.attrs.update({"valid_min": arr.min(), "valid_max": arr.max()}) + + data.rio.write_crs("epsg:4326", inplace=True) + with XarrayReader(data) as dst: + assert dst.minzoom == dst.maxzoom == 0 + info = dst.info() + assert info.bounds == dst.bounds + crs = info.crs + assert rioCRS.from_user_input(crs) == dst.crs + assert info.band_metadata == [("b1", {})] + assert info.band_descriptions == [("b1", "value")] + assert info.height == 33 + assert info.width == 35 + assert info.count == 1 + assert info.attrs + + with XarrayReader(data) as dst: + stats = dst.statistics() + assert stats["value"] + assert stats["value"].min == 0.0 + + img = dst.tile(0, 0, 0) + assert img.count == 1 + assert img.width == 256 + assert img.height == 256 + assert img.band_names == ["value"] + assert img.dataset_statistics == ((arr.min(), arr.max()),)