4040
4141LOG = logging .getLogger (__name__ )
4242
43+ BILINEAR_REDUCTION_HALO = 1
44+
4345
4446def _get_area_resolution (area ):
4547 """Attempt to retrieve resolution from AreaDefinition."""
@@ -60,6 +62,13 @@ def _aggregate_data_array(data_array, func, **coarsen_kwargs):
6062 return out
6163
6264
65+ def _expand_slice (slc : slice , size : int , padding : int ):
66+ """Expand a slice by a symmetric padding within array bounds."""
67+ start = 0 if slc .start is None else max (0 , slc .start - padding )
68+ stop = size if slc .stop is None else min (size , slc .stop + padding )
69+ return slice (start , stop , slc .step )
70+
71+
6372class DelayedGeneration (KeyError ):
6473 """Mark that a dataset can't be generated without further modification."""
6574
@@ -873,6 +882,7 @@ def _resampled_scene(self, new_scn, destination_area, reduce_data=True,
873882 new_datasets = {}
874883 datasets = list (new_scn ._datasets .values ())
875884 destination_area = self ._get_finalized_destination_area (destination_area , new_scn )
885+ resampler_kwargs = self ._get_resampler_kwargs (resample_kwargs )
876886
877887 resamplers = {}
878888 reductions = {}
@@ -896,8 +906,8 @@ def _resampled_scene(self, new_scn, destination_area, reduce_data=True,
896906 source_area = dataset .attrs ["area" ]
897907 dataset , source_area = self ._reduce_data (dataset , source_area , destination_area ,
898908 reduce_data , reductions , resample_kwargs )
899- self ._prepare_resampler (source_area , destination_area , resamplers , resample_kwargs )
900- kwargs = resample_kwargs .copy ()
909+ self ._prepare_resampler (source_area , destination_area , resamplers , resampler_kwargs )
910+ kwargs = resampler_kwargs .copy ()
901911 kwargs ["resampler" ] = resamplers [source_area ]
902912 res = resample_dataset (dataset , destination_area , ** kwargs )
903913 new_datasets [ds_id ] = res
@@ -927,23 +937,48 @@ def _prepare_resampler(self, source_area, destination_area, resamplers, resample
927937 resamplers [source_area ] = resampler
928938 self ._resamplers [key ] = resampler
929939
940+ @staticmethod
941+ def _uses_bilinear_resampler (resampler : Any ):
942+ if resampler == "bilinear" :
943+ return True
944+ try :
945+ from satpy .resample .kdtree import BilinearResampler
946+ except ImportError :
947+ return False
948+ if isinstance (resampler , BilinearResampler ):
949+ return True
950+ if isinstance (resampler , type ):
951+ return issubclass (resampler , BilinearResampler )
952+ return False
953+
954+ def _get_resampler_kwargs (self , resample_kwargs : dict [str , Any ]):
955+ resampler_kwargs = resample_kwargs .copy ()
956+ if self ._uses_bilinear_resampler (resampler_kwargs .get ("resampler" )):
957+ resampler_kwargs ["reduce_data" ] = False
958+ return resampler_kwargs
959+
960+ def _get_area_slice_kwargs (self , resample_kwargs : dict [str , Any ]):
961+ if resample_kwargs .get ("resampler" ) == "gradient_search" :
962+ return {"shape_divisible_by" : resample_kwargs .get ("shape_divisible_by" , 2 )}
963+ return {}
964+
965+ def _pad_reduce_data_slices (self , source_area , slice_x , slice_y , resample_kwargs ):
966+ if self ._uses_bilinear_resampler (resample_kwargs .get ("resampler" )):
967+ slice_x = _expand_slice (slice_x , source_area .width , BILINEAR_REDUCTION_HALO )
968+ slice_y = _expand_slice (slice_y , source_area .height , BILINEAR_REDUCTION_HALO )
969+ return slice_x , slice_y
970+
930971 def _reduce_data (self , dataset , source_area , destination_area , reduce_data , reductions , resample_kwargs ):
931972 try :
932973 if reduce_data :
933974 key = source_area
934975 try :
935976 (slice_x , slice_y ), source_area = reductions [key ]
936977 except KeyError :
937- if resample_kwargs .get ("resampler" ) == "gradient_search" :
938- factor = resample_kwargs .get ("shape_divisible_by" , 2 )
939- else :
940- factor = None
941- try :
942- slice_x , slice_y = source_area .get_area_slices (
943- destination_area , shape_divisible_by = factor )
944- except TypeError :
945- slice_x , slice_y = source_area .get_area_slices (
946- destination_area )
978+ slice_kwargs = self ._get_area_slice_kwargs (resample_kwargs )
979+ slice_x , slice_y = source_area .get_area_slices (destination_area , ** slice_kwargs )
980+ slice_x , slice_y = self ._pad_reduce_data_slices (
981+ source_area , slice_x , slice_y , resample_kwargs )
947982 source_area = source_area [slice_y , slice_x ]
948983 reductions [key ] = (slice_x , slice_y ), source_area
949984 dataset = self ._slice_data (source_area , (slice_x , slice_y ), dataset )
0 commit comments