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)