I wrote a wrapper for rasterio.mask.mask that accepts numpy arrays as inputs.
def mask_raster_with_geometry(raster, transform, shapes, **kwargs):
"""Wrapper for rasterio.mask.mask to allow for in-memory processing.
Docs: https://rasterio.readthedocs.io/en/latest/api/rasterio.mask.html
Args:
raster (numpy.ndarray): raster to be masked with dim: [H, W]
transform (affine.Affine): the transform of the raster
shapes, **kwargs: passed to rasterio.mask.mask
Returns:
masked: numpy.ndarray or numpy.ma.MaskedArray with dim: [H, W]
"""
with rasterio.io.MemoryFile() as memfile:
with memfile.open(
driver='GTiff',
height=raster.shape[0],
width=raster.shape[1],
count=1,
dtype=raster.dtype,
transform=transform,
) as dataset:
dataset.write(raster, 1)
with memfile.open() as dataset:
output, _ = rasterio.mask.mask(dataset, shapes, **kwargs)
return output.squeeze(0)
This is done via first writing to memfile and then reading from it before the function call to rasterio.mask.mask(). The MemoryFile will be discarded after exiting the with statement.
Unit test:
@pytest.mark.parametrize(
'raster,transform,shapes,expected',
[
pytest.param(
# the raster is positioned between x in (5, 8) and y in (-14, -10)
np.ones((4, 3), dtype=np.float32),
rasterio.transform.Affine(1, 0, 5, 0, -1, -10),
# mask out two pixels
# box params: xmin, ymin, xmax, ymax
[shapely.geometry.box(6.1, -12.9, 6.9, -11.1)],
np.array([
[0, 0, 0],
[0, 1, 0],
[0, 1, 0],
[0, 0, 0],
], dtype=np.float32),
),
],
)
def test_mask_raster_with_geometry(raster, transform, shapes, expected):
np.testing.assert_array_equal(
mask_raster_with_geometry(raster, transform, shapes),
expected)