From 4c831ff4e25912355888bc8428b4c84d9e9a09ab Mon Sep 17 00:00:00 2001 From: Daniel Scheffler Date: Fri, 27 Nov 2020 12:44:03 +0100 Subject: [PATCH] GMS_object.get_subset_obj() now returns None in case the subset contains no data at all. Signed-off-by: Daniel Scheffler --- gms_preprocessing/model/gms_object.py | 17 +++++++++++++---- gms_preprocessing/processing/pipeline.py | 11 +++++++---- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/gms_preprocessing/model/gms_object.py b/gms_preprocessing/model/gms_object.py index 239e8d2..6a05817 100644 --- a/gms_preprocessing/model/gms_object.py +++ b/gms_preprocessing/model/gms_object.py @@ -1277,9 +1277,11 @@ class GMS_object(object): def get_subset_obj(self, imBounds=None, mapBounds=None, mapBounds_prj=None, out_prj=None, logmsg=None, progress=False, v=False): - # type: (tuple, tuple, str, str, str, bool, bool) -> GMS_object - """Returns a subset of the given GMS object, based on the given bounds coordinates. - Array attributes are clipped and relevant metadata keys are updated according to new extent. + # type: (tuple, tuple, str, str, str, bool, bool) -> Union[GMS_object, None] + """Return a subset of the given GMS object, based on the given bounds coordinates. + + Array attributes are clipped and relevant metadata keys are updated according to new extent. In case the subset + does not contain any data but only no-data values, None is returned. :param imBounds: tuple of image coordinates in the form (xmin,xmax,ymin,ymax) :param mapBounds: tuple of map coordinates in the form (xmin,xmax,ymin,ymax) @@ -1347,6 +1349,12 @@ class GMS_object(object): # update array-related attributes of sub_GMS_obj if arrname == 'arr': + # return None in case the subset object contains only nodata + if subArr.min() == subArr.max() and \ + np.std(subArr) == 0 and \ + np.unique(subArr) == subArr.nodata: + return None + sub_GMS_obj.MetaObj.map_info = geotransform2mapinfo(subArr.gt, subArr.prj) sub_GMS_obj.MetaObj.projection = subArr.prj sub_GMS_obj.MetaObj.rows, sub_GMS_obj.MetaObj.cols = subArr.arr.shape[:2] @@ -1724,7 +1732,8 @@ class GMS_object(object): # validate that the MGRS tile truly contains data # -> this may not be the case if get_overlapping_MGRS_tiles() yielded invalid tiles due to inaccurate # self.trueDataCornerLonLat - if True not in list(np.unique(tileObj.arr.mask_nodata)): + if tileObj is None or \ + True not in list(np.unique(tileObj.arr.mask_nodata)): self.logger.info("MGRS tile '%s' has not been skipped because it contains only no data values." % MGRS_tileID) continue diff --git a/gms_preprocessing/processing/pipeline.py b/gms_preprocessing/processing/pipeline.py index d9d8919..3c183b7 100644 --- a/gms_preprocessing/processing/pipeline.py +++ b/gms_preprocessing/processing/pipeline.py @@ -77,7 +77,7 @@ def L1A_map(dataset_dict): # map (scene-wise parallelization) @EXC_H.log_uncaught_exceptions @update_proc_status def L1A_map_1(dataset_dict, block_size=None): # map (scene-wise parallelization) - # type: (dict) -> List[L1A_P.L1A_object] + # type: (dict, tuple) -> List[L1A_P.L1A_object] L1A_obj = L1A_P.L1A_object(**dataset_dict) L1A_obj.block_at_system_overload(max_usage=CFG.critical_mem_usage) @@ -87,8 +87,10 @@ def L1A_map_1(dataset_dict, block_size=None): # map (scene-wise parallelization L1A_obj.apply_nodata_mask_to_ObjAttr('arr') # nodata mask is automatically calculated L1A_obj.add_rasterInfo_to_MetaObj() L1A_obj.reference_data('UTM') - tiles = list(L1A_obj.to_tiles( - block_size if block_size else CFG.tiling_block_size_XY)) # cut (block-wise parallelization) + tiles = [tile for tile in + # cut (block-wise parallelization) + L1A_obj.to_tiles(blocksize=block_size if block_size else CFG.tiling_block_size_XY) + if tile is not None] # None is returned in case the tile contains no data at all return tiles @@ -182,7 +184,7 @@ def L1C_map(L1B_objs): @EXC_H.log_uncaught_exceptions @update_proc_status def L2A_map(L1C_objs, block_size=None, return_tiles=True): - # type: (Union[List[L1C_P.L1C_object], Tuple[L1C_P.L1C_object]]) -> Union[List[L2A_P.L2A_object], L2A_P.L2A_object] + # type: (Union[List[L1C_P.L1C_object], Tuple[L1C_P.L1C_object]], tuple, bool) -> Union[List[L2A_P.L2A_object], L2A_P.L2A_object] # noqa """Geometric homogenization. Performs correction of geometric displacements, resampling to target grid of the usecase and merges multiple @@ -229,6 +231,7 @@ def L2A_map(L1C_objs, block_size=None, return_tiles=True): if return_tiles: L2A_tiles = list(L2A_obj.to_tiles(blocksize=block_size if block_size else CFG.tiling_block_size_XY)) + L2A_tiles = [i for i in L2A_tiles if i is not None] # None is returned in case the tile contains no data at all [L2A_tile.record_mem_usage() for L2A_tile in L2A_tiles] return L2A_tiles else: -- GitLab