Commit 81ad19a6 authored by Daniel Scheffler's avatar Daniel Scheffler

Merge branch 'enhancement/speed_up_nodatamask' into 'master'

The algorithm to compute the nodata mask is now much faster, especially for...

See merge request !13
parents d3a3700f c4bfb66c
Pipeline #7601 passed with stages
in 9 minutes and 14 seconds
...@@ -681,25 +681,41 @@ class GeoArray(object): ...@@ -681,25 +681,41 @@ class GeoArray(object):
:param overwrite: <bool> whether to overwrite existing nodata mask that has already been calculated :param overwrite: <bool> whether to overwrite existing nodata mask that has already been calculated
:return: :return:
""" """
if self._mask_nodata is None or overwrite: if self._mask_nodata is None or overwrite:
assert self.ndim in [2, 3], "Only 2D or 3D arrays are supported. Got a %sD array." % self.ndim assert self.ndim in [2, 3], "Only 2D or 3D arrays are supported. Got a %sD array." % self.ndim
arr = self[:, :, fromBand] if self.ndim == 3 and fromBand is not None else self[:] arr = self[:, :, fromBand] if self.ndim == 3 and fromBand is not None else self[:]
min_v, max_v = np.min(arr), np.max(arr) if self.nodata is None:
if (min_v == max_v == self.nodata) or (np.isnan(min_v) and np.isnan(max_v) and np.isnan(self.nodata)): mask = np.ones((self.rows, self.cols), np.bool)
self.mask_nodata = np.full(arr.shape[:2], False)
elif np.isnan(self.nodata):
nanmask = np.isnan(arr)
nanbands = np.all(np.all(nanmask, axis=0), axis=0)
if np.all(nanbands):
mask = np.full(arr.shape[:2], False)
elif arr.ndim == 2:
mask = ~np.isnan(arr)
else:
idx_1st_databand = np.argwhere(~nanbands)[0][0]
mask = ~np.isnan(arr[:, :, idx_1st_databand])
mask[~mask] = np.any(~np.isnan(arr[~mask]), axis=1)
else: else:
if self.nodata is None: bandmeans = np.mean(np.mean(arr, axis=0), axis=0)
self.mask_nodata = np.ones((self.rows, self.cols), np.bool)
elif np.isnan(self.nodata): if np.nanmean(bandmeans) == self.nodata:
self.mask_nodata = \ mask = np.full(arr.shape[:2], False)
np.invert(np.isnan(arr)) if arr.ndim == 2 else \ elif arr.ndim == 2:
np.any(np.invert(np.isnan(arr)), axis=2) mask = arr != self.nodata
else: else:
self.mask_nodata = \ idx_1st_databand = np.argwhere(bandmeans != self.nodata)[0][0]
np.ma.masked_not_equal(arr, self.nodata).mask if arr.ndim == 2 else \ mask = np.array(arr[:, :, idx_1st_databand] != self.nodata)
np.any(np.ma.masked_not_equal(arr, self.nodata).mask, axis=2) mask[~mask] = np.any(arr[~mask] != self.nodata, axis=1)
self.mask_nodata = mask
return mask
def find_noDataVal(self, bandIdx=0, sz=3): def find_noDataVal(self, bandIdx=0, sz=3):
"""Tries to derive no data value from homogenious corner pixels within 3x3 windows (by default). """Tries to derive no data value from homogenious corner pixels within 3x3 windows (by default).
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment