def binary_mask(rast, mask, nodata=-9999, invert=False):
'''
Applies an arbitrary, binary mask (data in [0,1]) where pixels with
a value of 1 are pixels to be masked out. Arguments:
rast A gdal.Dataset or a NumPy array
mask A gdal.Dataset or a NumPy array
nodata The NoData value; defaults to -9999.
invert Invert the mask? (tranpose meaning of 0 and 1); defaults to False.
'''
# Can accept either a gdal.Dataset or numpy.array instance
if not isinstance(rast, np.ndarray):
rastr = rast.ReadAsArray()
else:
rastr = rast.copy()
if not isinstance(mask, np.ndarray):
maskr = mask.ReadAsArray()
else:
maskr = mask.copy()
if not np.alltrue(np.equal(rastr.shape[-2:], maskr.shape[-2:])):
raise ValueError('Raster and mask do not have the same shape')
# Convert Boolean arrays to ones and zeros
if maskr.dtype == bool:
maskr = maskr.astype(np.int0)
# Transform into a "1-band" array and apply the mask
if maskr.shape != rastr.shape:
maskr = maskr.reshape((1, maskr.shape[-2], maskr.shape[-1]))\
.repeat(rastr.shape[0], axis=0) # Copy the mask across the "bands"
# TODO Compare to place(), e.g.,
# np.place(rastr, mask.repeat(rastr.shape[0], axis=0), (nodata,))
# Mask out areas that match the mask (==1)
if invert:
rastr[maskr < 1] = nodata
else:
rastr[maskr > 0] = nodata
return rastr
评论列表
文章目录