diff --git a/CHANGES.md b/CHANGES.md index f6674491e..e01e3f656 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -5,6 +5,7 @@ ### Issues Fixed/Resolved * Fixed [#309](https://github.com/CCI-Tools/cate-core/issues/309) +* Ensure that our tile size matches the expected tile size: resize and fill in background value. ## Changes in version 0.9.0.dev4 diff --git a/cate/util/im/image.py b/cate/util/im/image.py index 62295c123..a3be991d6 100644 --- a/cate/util/im/image.py +++ b/cate/util/im/image.py @@ -654,13 +654,23 @@ def compute_tile(self, tile_x: int, tile_y: int, rectangle: Rectangle2D) -> Tile # We do the resampling to lower resolution after loading the data, which is MUCH faster, see note above. tile = tile[..., ::zoom, ::zoom] - actual_tile_size = tile.shape[-1], tile.shape[-2] - - # TODO (forman): ensure that our tile size is w x h: resize and fill in background value. - # For time being raise error - assert self.tile_size == actual_tile_size, "unexpected tile size: " \ - "expected %s, but got %s" % (self.tile_size, actual_tile_size) + # ensure that our tile size is w x h: resize and fill in background value. + return self.pad_tile(tile, self.tile_size) + @staticmethod + def pad_tile(tile: Tile, target_tile_size: Size2D, fill_value: float = np.nan) -> Tile: + (target_width, target_height) = target_tile_size + tile_width, tile_heigth = tile.shape[-1], tile.shape[-2] + if target_width > tile_width: + # expand in width + h_pad = np.empty((tile_heigth, target_width - tile_width)) + h_pad.fill(fill_value) + tile = np.hstack((tile, h_pad)) + if target_height > tile_heigth: + # expand in height + v_pad = np.empty((target_height - tile_heigth, target_width)) + v_pad.fill(fill_value) + tile = np.vstack((tile, v_pad)) return tile diff --git a/test/util/im/test_image.py b/test/util/im/test_image.py index 54e5b22eb..5f2b0418b 100644 --- a/test/util/im/test_image.py +++ b/test/util/im/test_image.py @@ -124,6 +124,24 @@ def test_force_2d(self): self.assertEqual(target_image.size, (6, 4)) self.assertEqual(target_image.num_tiles, (3, 2)) + def test_pad_tile(self): + a = np.arange(0, 6, dtype=np.float32) + a.shape = 2, 3 + b = FastNdarrayDownsamplingImage.pad_tile(a, (3, 2)) + np.testing.assert_equal(b, np.array([[0., 1., 2.], + [3., 4., 5.]])) + b = FastNdarrayDownsamplingImage.pad_tile(a, (4, 2)) + np.testing.assert_equal(b, np.array([[0., 1., 2., np.nan], + [3., 4., 5., np.nan]])) + b = FastNdarrayDownsamplingImage.pad_tile(a, (3, 3)) + np.testing.assert_equal(b, np.array([[0., 1., 2.], + [3., 4., 5.], + [np.nan, np.nan, np.nan]])) + b = FastNdarrayDownsamplingImage.pad_tile(a, (4, 3)) + np.testing.assert_equal(b, np.array([[0., 1., 2., np.nan], + [3., 4., 5., np.nan], + [np.nan, np.nan, np.nan, np.nan]])) + class ImagePyramidTest(TestCase): def test_create_from_image(self):