Skip to content

Commit

Permalink
rename resampling option in xarrayReader (#673)
Browse files Browse the repository at this point in the history
  • Loading branch information
vincentsarago authored Jan 24, 2024
1 parent 34de1a2 commit 9900547
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 14 deletions.
13 changes: 13 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
# 6.4.0 (2024-01-24)

* deprecate `resampling_method` in `rio_tiler.io.xarray.XarrayReader` method and add `reproject_method` (to match the `rio_tiler.io.Reader` options)

```python
# before
with XarrayReader(data) as dst:
img = dst.tile(0, 0, 1, resampling_method="cubic")

# now
with XarrayReader(data) as dst:
img_cubic = dst.tile(0, 0, 1, reproject_method="cubic")
```

# 6.3.1 (2024-01-22)

Expand Down
4 changes: 2 additions & 2 deletions docs/src/readers.md
Original file line number Diff line number Diff line change
Expand Up @@ -1064,7 +1064,7 @@ from rio_tiler.io import XarrayReader
from rio_tiler.models import ImageData

with XarrayReader(data) as src:
# src.tile(tile_x, tile_y, tile_z, tilesize, resampling_method)
# src.tile(tile_x, tile_y, tile_z, tilesize, reproject_method)
img = src.tile(1, 2, 3)
assert isinstance(img, ImageData)
assert img.crs == WEB_MERCATOR_CRS
Expand All @@ -1077,7 +1077,7 @@ from rio_tiler.io import XarrayReader
from rio_tiler.models import ImageData

with XarrayReader(data) as src:
# src.part((minx, miny, maxx, maxy), dst_crs, bounds_crs, resampling_method)
# src.part((minx, miny, maxx, maxy), dst_crs, bounds_crs, reproject_method)
img = src.part((10, 10, 20, 20))
assert isinstance(img, ImageData)
assert img.crs == WGS84_CRS
Expand Down
49 changes: 40 additions & 9 deletions rio_tiler/io/xarray.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,8 @@ def tile(
tile_y: int,
tile_z: int,
tilesize: int = 256,
resampling_method: WarpResampling = "nearest",
resampling_method: Optional[WarpResampling] = None,
reproject_method: WarpResampling = "nearest",
auto_expand: bool = True,
nodata: Optional[NoData] = None,
) -> ImageData:
Expand All @@ -213,13 +214,22 @@ def tile(
tile_y (int): Tile's vertical index.
tile_z (int): Tile's zoom level index.
tilesize (int, optional): Output image size. Defaults to `256`.
resampling_method (WarpResampling, optional): WarpKernel resampling algorithm. Defaults to `nearest`.
resampling_method (WarpResampling, optional): **DEPRECATED**, WarpKernel resampling algorithm. Defaults to `nearest`.
reproject_method (WarpResampling, optional): WarpKernel resampling algorithm. Defaults to `nearest`.
auto_expand (boolean, optional): When True, rioxarray's clip_box will expand clip search if only 1D raster found with clip. When False, will throw `OneDimensionalRaster` error if only 1 x or y data point is found. Defaults to True.
nodata (int or float, optional): Overwrite dataset internal nodata value.
Returns:
rio_tiler.models.ImageData: ImageData instance with data, mask and tile spatial info.
"""
if resampling_method:
warnings.warn(
"`resampling_method` is deprecated and will be removed in rio-tiler 7.0, please use `reproject_method`",
DeprecationWarning,
)
reproject_method = resampling_method

if not self.tile_exists(tile_x, tile_y, tile_z):
raise TileOutsideBounds(
f"Tile {tile_z}/{tile_x}/{tile_y} is outside bounds"
Expand All @@ -242,7 +252,7 @@ def tile(
dst_crs,
shape=(tilesize, tilesize),
transform=from_bounds(*tile_bounds, height=tilesize, width=tilesize),
resampling=Resampling[resampling_method],
resampling=Resampling[reproject_method],
nodata=nodata,
)

Expand All @@ -268,7 +278,8 @@ def part(
bbox: BBox,
dst_crs: Optional[CRS] = None,
bounds_crs: CRS = WGS84_CRS,
resampling_method: WarpResampling = "nearest",
resampling_method: Optional[WarpResampling] = None,
reproject_method: WarpResampling = "nearest",
auto_expand: bool = True,
nodata: Optional[NoData] = None,
) -> ImageData:
Expand All @@ -278,13 +289,22 @@ def part(
bbox (tuple): Output bounds (left, bottom, right, top) in target crs ("dst_crs").
dst_crs (rasterio.crs.CRS, optional): Overwrite target coordinate reference system.
bounds_crs (rasterio.crs.CRS, optional): Bounds Coordinate Reference System. Defaults to `epsg:4326`.
resampling_method (WarpResampling, optional): WarpKernel resampling algorithm. Defaults to `nearest`.
resampling_method (WarpResampling, optional): **DEPRECATED**, WarpKernel resampling algorithm. Defaults to `nearest`.
reproject_method (WarpResampling, optional): WarpKernel resampling algorithm. Defaults to `nearest`.
auto_expand (boolean, optional): When True, rioxarray's clip_box will expand clip search if only 1D raster found with clip. When False, will throw `OneDimensionalRaster` error if only 1 x or y data point is found. Defaults to True.
nodata (int or float, optional): Overwrite dataset internal nodata value.
Returns:
rio_tiler.models.ImageData: ImageData instance with data, mask and input spatial info.
"""
if resampling_method:
warnings.warn(
"`resampling_method` is deprecated and will be removed in rio-tiler 7.0, please use `reproject_method`",
DeprecationWarning,
)
reproject_method = resampling_method

dst_crs = dst_crs or bounds_crs

ds = self.input
Expand All @@ -309,7 +329,7 @@ def part(
dst_crs,
shape=(h, w),
transform=dst_transform,
resampling=Resampling[resampling_method],
resampling=Resampling[reproject_method],
nodata=nodata,
)

Expand Down Expand Up @@ -362,6 +382,7 @@ def point(
lon (float): Longitude.
lat (float): Latitude.
coord_crs (rasterio.crs.CRS, optional): Coordinate Reference System of the input coords. Defaults to `epsg:4326`.
nodata (int or float, optional): Overwrite dataset internal nodata value.
Returns:
PointData
Expand Down Expand Up @@ -396,7 +417,8 @@ def feature(
shape: Dict,
dst_crs: Optional[CRS] = None,
shape_crs: CRS = WGS84_CRS,
resampling_method: WarpResampling = "nearest",
resampling_method: Optional[WarpResampling] = None,
reproject_method: WarpResampling = "nearest",
nodata: Optional[NoData] = None,
) -> ImageData:
"""Read part of a dataset defined by a geojson feature.
Expand All @@ -405,12 +427,21 @@ def feature(
shape (dict): Valid GeoJSON feature.
dst_crs (rasterio.crs.CRS, optional): Overwrite target coordinate reference system.
shape_crs (rasterio.crs.CRS, optional): Input geojson coordinate reference system. Defaults to `epsg:4326`.
resampling_method (WarpResampling, optional): WarpKernel resampling algorithm. Defaults to `nearest`.
resampling_method (WarpResampling, optional): **DEPRECATED**, WarpKernel resampling algorithm. Defaults to `nearest`.
reproject_method (WarpResampling, optional): WarpKernel resampling algorithm. Defaults to `nearest`.
nodata (int or float, optional): Overwrite dataset internal nodata value.
Returns:
rio_tiler.models.ImageData: ImageData instance with data, mask and input spatial info.
"""
if resampling_method:
warnings.warn(
"`resampling_method` is deprecated and will be removed in rio-tiler 7.0, please use `reproject_method`",
DeprecationWarning,
)
reproject_method = resampling_method

if not dst_crs:
dst_crs = shape_crs

Expand All @@ -434,7 +465,7 @@ def feature(
dst_crs,
shape=(h, w),
transform=dst_transform,
resampling=Resampling[resampling_method],
resampling=Resampling[reproject_method],
nodata=nodata,
)

Expand Down
68 changes: 65 additions & 3 deletions tests/test_io_xarray.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def test_xarray_reader():
assert img.dataset_statistics == ((arr.min(), arr.max()),)

# Tests for auto_expand
## Test that a high-zoom tile will error with auto_expand=False
# Test that a high-zoom tile will error with auto_expand=False
tms = morecantile.tms.get("WebMercatorQuad")
zoom = 10
x, y = tms.xy(-170, -80)
Expand All @@ -58,8 +58,8 @@ def test_xarray_reader():
str(error.value)
== "At least one of the clipped raster x,y coordinates has only one point."
)
##
## Test that a high-zoom tile will succeed with auto_expand=True (and that is the default)

# Test that a high-zoom tile will succeed with auto_expand=True (and that is the default)
img = dst.tile(tile.x, tile.y, zoom)
assert img.count == 1
assert img.width == 256
Expand Down Expand Up @@ -262,3 +262,65 @@ def test_xarray_reader_internal_nodata():
assert not img.mask.all() # not all the mask value are set to 255
assert img.array.mask[0, 0, 0] # the top left pixel should be masked
assert not img.array.mask[0, 50, 100] # pixel 50,100 shouldn't be masked


def test_xarray_reader_resampling():
"""test XarrayReader."""
arr = numpy.arange(0.0, 33 * 35).reshape(1, 33, 35)
data = xarray.DataArray(
arr,
dims=("time", "y", "x"),
coords={
"x": list(range(-170, 180, 10)),
"y": list(range(-80, 85, 5)),
"time": [datetime(2022, 1, 1)],
},
)
data.attrs.update({"valid_min": arr.min(), "valid_max": arr.max()})

data.rio.write_crs("epsg:4326", inplace=True)

with XarrayReader(data) as dst:
# TILE
# default nearest
img = dst.tile(0, 0, 1)
img_cubic = dst.tile(0, 0, 1, reproject_method="cubic")
assert not numpy.array_equal(img.array, img_cubic.array)

with pytest.warns(DeprecationWarning):
_ = dst.tile(0, 0, 1, resampling_method="nearest")

# PART
img = dst.part((-160, -80, 160, 80), dst_crs="epsg:3857")
img_cubic = dst.part(
(-160, -80, 160, 80), dst_crs="epsg:3857", reproject_method="cubic"
)
assert not numpy.array_equal(img.array, img_cubic.array)

with pytest.warns(DeprecationWarning):
_ = dst.part((-160, -80, 160, 80), resampling_method="nearest")

feat = {
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[-180.0, 0],
[-180.0, 85.0511287798066],
[0, 85.0511287798066],
[0, 6.023673383202919e-13],
[-180.0, 0],
]
],
},
"properties": {"title": "XYZ tile (0, 0, 1)"},
}

# FEATURE
img = dst.feature(feat, dst_crs="epsg:3857")
img_cubic = dst.feature(feat, dst_crs="epsg:3857", reproject_method="cubic")
assert not numpy.array_equal(img.array, img_cubic.array)

with pytest.warns(DeprecationWarning):
_ = dst.feature(feat, resampling_method="nearest")

0 comments on commit 9900547

Please sign in to comment.