First reported in https://github.com/cogeotiff/rio-cogeo/issues/115
Since rasterio >= 1.1.2 rasterio._io.DatasetReaderBase. dataset_mask is returning data array as int64 when using internal nodata.
The problem is then when we want to write this array back to a dataset, we will get rasterio._shim.io_band KeyError: 'int64' because int64 is not a supported data type (in rasterio nor GDAL).
import rasterio
print(rasterio.__version__)
with rasterio.open("https://raw.githubusercontent.com/cogeotiff/rio-cogeo/master/tests/fixtures/image_missing_nodata.tif") as src_dst:
print(f"Dataset type: {src_dst.dtypes}")
arr = src_dst.read()
print(f"Data type: {arr.dtype}")
mask = src_dst.dataset_mask()
print(f"Mask type: {mask.dtype}")
1.1.2
Dataset type: ('int16',)
Data type: int16
Mask type: int64
cc @sgillies
Confirmed.
My understanding is that in https://github.com/mapbox/rasterio/blob/0027034d9eebe012e140260e2cc18acd4123939d/rasterio/_io.pyx#L806 when doing 255 * numpy is translating 255 to numpy.array(255) which is then in int64 dtype.
import rasterio
import numpy
with rasterio.open("https://raw.githubusercontent.com/cogeotiff/rio-cogeo/master/tests/fixtures/image_missing_nodata.tif") as src_dst:
r = 255 * numpy.logical_or.reduce(src_dst.read_masks(1))
print(r.dtype)
print(numpy.array(255).dtype)
int64
int64
@sgillies I think the quick fix is to cast out to uint8 datatype:
out = 255 * np.logical_or.reduce(self.read_masks(**kwargs))
return out.astype("uint8")
Resolved by 07d47ef.