v4.0 -> v5.0
rio-tiler
version 5.0 introduced many breaking changes. This
document aims to help with migrating your code to use rio-tiler
5.0.
PER_DATASET -> PER_BAND mask¶
When we started to work on rio-tiler we chose to use PER_DATASET
mask, a 2D (height, width)
array which represent the masked array for the whole dataset, as Alpha
or Mask
bands are designed for.
The PER_DATASET
model suffers precision when dealing with datasets that use nodata
value because combining all band nodata mask
will exclude good data (see github.com/cogeotiff/rio-tiler/issues/579#issuecomment-1455223893).
To support the PER_BAND
model, we updated the ImageData
class to use numpy.ma.MaskedArray
which will hold both the data and the mask with the same shape. The image data
is now hosted in .array
ImageData/PointData attribute.
# before
with COGReader("cog.tif") as src:
img = src.preview(width=128, height=128, max_size=None)
assert isinstance(img.data, numpy.ndarray)
assert img.data.shape == (3, 128, 128)
assert isinstance(img.mask, numpy.ndarray)
assert img.mask.shape == (128, 128)
# now
with COGReader("cog.tif") as src:
img = src.preview(width=128, height=128, max_size=None)
assert isinstance(img.array, numpy.ma.MaskedArray)
assert img.array.data.shape == (3, 128, 128)
assert img.array.mask.shape == (3, 128, 128)
For compatibility reason we kept data
and mask
as properties in the ImageData
class. ImageData().mask
will represent the PER_DATASET
mask.
with COGReader("cog.tif") as src:
img = src.preview(width=128, height=128, max_size=None)
assert isinstance(img.array, numpy.ma.MaskedArray)
assert img.data.shape == (3, 128, 128)
assert img.mask.shape == (128, 128)
ImageData/PointData¶
As explained, the ImageData
and PointData
classes now use MaskedArray
as input.
# before
arr = numpy.zeros((1, 256, 256))
mask = numpy.zeros((256, 256), dtype="uint8")
im = ImageData(arr, mask)
# now
arr = numpy.ma.MaskedArray(numpy.zeros((1, 256, 256)))
arr.mask = False
im = ImageData(arr)
post_process callback¶
Introduced in 2.0
, rio-tiler
's low level reader (rio_tiler.reader.read
) accept a post_process
option which should be a Callable that take some data as input and returns modified data. Because of the changes in ImageData input type (now as MaskedArray), the post_process
callback should be design to be of type Callable[[numpy.ma.MaskedArray], numpy.ma.MaskedArray]
.
# before
def callback(data: numpy.ndarray, mask: numpy.ndarray) -> Tuple[numpy.ndarray, numpy.ndarray]:
mask.fill(255)
data = data * 2
return data, mask
with Reader("cog.tif") as src:
im = src.preview(post_process=callback)
# now
def callback(data: numpy.ma.MaskedArray) -> numpy.ma.MaskedArray:
data = data * 2
return data
with Reader("cog.tif") as src:
im = src.preview(post_process=callback)
MosaicMethod¶
The .data
property of rio-tiler
's MosaicMethods should now return numpy.ma.MaskedArray
. This change should be almost non-breaking because the MosaicMethod where designed using MaskedArrays.
# before
def data(self) -> Tuple[Optional[numpy.ndarray], Optional[numpy.ndarray]]:
"""Return data and mask."""
if self.tile is not None:
data = numpy.ma.getdata(self.tile)
mask = ~numpy.logical_or.reduce(numpy.ma.getmaskarray(self.tile)) # create PER_DATASET Mask
return (data, mask * numpy.uint8(255))
else:
return None, None
# now
@property
def data(self) -> Optional[numpy.ma.MaskedArray]:
"""Return data."""
return self.mosaic # `tile` has been renamed `array`
Reprojection and Resizing resampling methods¶
With rio-tiler >=5.0
, you can now select with resampling method to use for the reprojection
and resizing
processes independently by using the reproject_method
and resampling_method
options in rio_tiler.reader
's function.
The resampling_method
option will control the IO
resampling (e.g resizing) while the reproject_method
will be using in the WarpedVRT
for the reprojection.
# before
with Reader("cog.tif") as src:
im = src.preview(
dst_crs="epsg:4326",
resampling_method="bilinear", # use `bilinear` for both resizing and reprojection
)
# now
with Reader("cog.tif") as src:
im = src.preview(
dst_crs="epsg:4326",
resampling_method="cubic", # use `cubic` for resizing
reproject_method="bilinear", # use `bilinear` for reprojection
)
Important
In the XarrayReader
we are still using only one resampling_method
option because we are using rioxarray
for read and reprojection processes and it does not have both options available.
Boto3 Optional dependency¶
When needing to access STAC items using s3://
urls, you'll need to have boto3
installed in your python environment.
python -m pip install rio-tiler["s3"] # or python -m pip install rio-tiler rasterio["s3"]
Note: if you want to access s3://
raster dataset you'll also need boto3
in your environment (rasterio
's dependency).
changes in method/function/variable names¶
Some function or method names have changed in rio-tiler
V5
-
rio_tiler.mosaic.methods.LastBandHigh
->rio_tiler.mosaic.methods.LastBandHighMethod
-
rio_tiler.mosaic.methods.LastBandLow
->rio_tiler.mosaic.methods.LastBandLowMethod
-
in the
MosaicMethodBase
the variabletile
has been renamedmosaic
-
rio_tiler.utils.aws_get_object
->rio_tiler.io.stac.aws_get_object
-
In
ImageData
/PointData
objects the pixel values are stored in a variable namedarray
(it wasdata
previously). A.data
property has been added for compatibility. -
In
ImageData
/PointData
the.mask
attribute has been replaced by a.mask
property