From a37da62e0e2293aee863ca05bf0d77b12b065642 Mon Sep 17 00:00:00 2001 From: vincentsarago Date: Mon, 11 Dec 2023 22:09:39 +0100 Subject: [PATCH 1/2] force discrete colormap when cmap does not have 256 values --- CHANGES.md | 4 ++++ rio_tiler/colormap.py | 4 ++-- tests/test_cmap.py | 3 +++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 4f9d67cc..e5afc31c 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,4 +1,8 @@ +# 6.2.8 (2023-12-11) + +* apply `discrete` colormap when the provided colormap does not have 256 values + # 6.2.7 (2023-11-29) * Adjusting dataset latitude for WarpedVRT parameters calculation when EPSG:4326 dataset latitudes overflows EPSG:3857 min/max latitude (https://github.com/cogeotiff/rio-tiler/pull/660) diff --git a/rio_tiler/colormap.py b/rio_tiler/colormap.py index 437676d0..8c0fa7af 100644 --- a/rio_tiler/colormap.py +++ b/rio_tiler/colormap.py @@ -103,11 +103,11 @@ def apply_cmap(data: numpy.ndarray, colormap: ColorMapType) -> DataMaskType: if isinstance(colormap, Sequence): return apply_intervals_cmap(data, colormap) - # if colormap has more than 256 values OR its `max` key >= 256 we can't use + # if colormap has less or more than 256 values OR its `max` key >= 256 we can't use # rio_tiler.colormap.make_lut, because we don't want to create a `lookup table` # with more than 256 entries (256 x 4) array. In this case we use `apply_discrete_cmap` # which can work with arbitrary colormap dict. - if len(colormap) > 256 or max(colormap) >= 256 or min(colormap) < 0: + if len(colormap) != 256 or max(colormap) >= 256 or min(colormap) < 0: return apply_discrete_cmap(data, colormap) lookup_table = make_lut(colormap) diff --git a/tests/test_cmap.py b/tests/test_cmap.py index 56a2f322..f21ba33f 100644 --- a/tests/test_cmap.py +++ b/tests/test_cmap.py @@ -151,6 +151,9 @@ def test_apply_discrete_cmap(): mask[2:5, 2:5] = 255 mask[5:, 5:] = 255 numpy.testing.assert_array_equal(m, mask) + dd, mm = colormap.apply_cmap(data, cm) + numpy.testing.assert_array_equal(dd, d) + numpy.testing.assert_array_equal(mm, m) data = data.astype("uint16") d, m = colormap.apply_discrete_cmap(data, cm) From 45da9229741d6053110764827d97ddf66373295b Mon Sep 17 00:00:00 2001 From: vincentsarago Date: Mon, 11 Dec 2023 22:18:45 +0100 Subject: [PATCH 2/2] add more tests --- tests/test_cmap.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/tests/test_cmap.py b/tests/test_cmap.py index f21ba33f..a2050c78 100644 --- a/tests/test_cmap.py +++ b/tests/test_cmap.py @@ -254,3 +254,31 @@ def test_parse_color_bad(): with pytest.raises(InvalidColorFormat): colormap.parse_color([0, 0, 0, 0, 0]) + + +def test_discrete_float(): + """test for titiler issue 738.""" + cm = { + 0: (0, 255, 255, 255), + 1: (83, 151, 145, 255), + 2: (87, 194, 23, 255), + 3: (93, 69, 255, 255), + 4: (98, 217, 137, 255), + 5: (140, 255, 41, 255), + 6: (150, 110, 255, 255), + 7: (179, 207, 100, 255), + 8: (214, 130, 156, 255), + 9: (232, 170, 108, 255), + 10: (255, 225, 128, 255), + 11: (255, 184, 180, 255), + 12: (255, 255, 140, 255), + 13: (255, 180, 196, 255), + 14: (255, 0, 0, 255), + 15: (255, 218, 218, 255), + } + + data = numpy.round(numpy.random.random_sample((1, 256, 256)) * 15) + d, m = colormap.apply_cmap(data.copy(), cm) + dd, mm = colormap.apply_discrete_cmap(data.copy(), cm) + assert d.dtype == numpy.uint8 + assert m.dtype == numpy.uint8