Skip to content

Commit 9141c17

Browse files
committed
Dynamically determine nodata index based on multiple heuristics
1 parent f6c9d66 commit 9141c17

File tree

3 files changed

+43
-23
lines changed

3 files changed

+43
-23
lines changed

hybig/browse.py

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
from hybig.browse_utility import get_harmony_message_from_params
2424
from hybig.color_utility import (
2525
NODATA_IDX,
26-
NODATA_RGBA,
2726
OPAQUE,
2827
TRANSPARENT,
2928
ColorMap,
@@ -40,6 +39,8 @@
4039
get_target_grid_parameters,
4140
)
4241

42+
DST_NODATA = NODATA_IDX
43+
4344

4445
def create_browse(
4546
source_tiff: str,
@@ -311,7 +312,7 @@ def scale_grey_1band(data_array: DataArray) -> tuple[ndarray, ColorMap]:
311312
normalized_data = norm(band) * 254.0
312313

313314
# Set any missing to missing
314-
normalized_data[np.isnan(normalized_data)] = NODATA_IDX
315+
normalized_data[np.isnan(normalized_data)] = DST_NODATA
315316

316317
grey_colormap = greyscale_colormap()
317318
raster_data = np.expand_dims(np.round(normalized_data).data, 0)
@@ -362,7 +363,7 @@ def scale_paletted_1band_to_rgb(
362363
norm = matplotlib.colors.BoundaryNorm(levels, len(levels) - 1)
363364

364365
# handle palette no data value
365-
nodata_color = (0, 0, 0, 0)
366+
nodata_color = (0, 0, 0)
366367
if palette.ndv is not None:
367368
nodata_color = palette.color_to_color_entry(palette.ndv, with_alpha=True)
368369

@@ -399,6 +400,7 @@ def scale_paletted_1band(
399400
the correct levels indexed from 0-255 return the scaled array along side of
400401
a colormap corresponding to the new levels.
401402
"""
403+
global DST_NODATA
402404
band = data_array[0, :, :]
403405
levels = list(palette.pal.keys())
404406
colors = [
@@ -411,14 +413,31 @@ def scale_paletted_1band(
411413
nodata_color = (0, 0, 0, 0)
412414
if palette.ndv is not None:
413415
nodata_color = palette.color_to_color_entry(palette.ndv, with_alpha=True)
414-
415-
colors = [*colors, nodata_color]
416+
color_list = list(palette.pal.values())
417+
try:
418+
DST_NODATA = color_list.index(palette.ndv)
419+
# ndv is included in the list of colors, so no need to add nodata_color
420+
# to the list
421+
except ValueError:
422+
# ndv is not an index in the color palette, therefore it should be
423+
# index 0, which is the default for a ColorPalette when using
424+
# palette.get_all_keys()
425+
DST_NODATA = 0
426+
colors = [nodata_color, *colors]
427+
else:
428+
# if there is no ndv, add one to the end of the colormap
429+
colors = [*colors, nodata_color]
430+
DST_NODATA = len(colors) - 1
416431

417432
scaled_band = norm(band)
433+
if DST_NODATA == 0:
434+
# boundary norm indexes [0, levels) by default, so if the NODATA index is 0,
435+
# all the palette indices need to be incremented by 1.
436+
scaled_band += 1
418437

419-
# Set underflow and nan values to nodata
420-
scaled_band[scaled_band == -1] = len(colors) - 1
421-
scaled_band[np.isnan(band)] = len(colors) - 1
438+
# Set underflow and nan values to nodata index
439+
scaled_band[scaled_band == -1] = DST_NODATA
440+
scaled_band[np.isnan(band)] = DST_NODATA
422441

423442
color_map = colormap_from_colors(colors)
424443
raster_data = np.expand_dims(scaled_band.data, 0)
@@ -427,7 +446,7 @@ def scale_paletted_1band(
427446

428447
def image_driver(mime: str) -> str:
429448
"""Return requested rasterio driver for output image."""
430-
if re.search('jpeg', mime, re.I):
449+
if re.search('jpeg', mime, re.I) or re.search('jpg', mime, re.I):
431450
return 'JPEG'
432451
return 'PNG'
433452

@@ -527,11 +546,12 @@ def write_georaster_as_browse(
527546
n_bands = raster.shape[0]
528547

529548
if color_map is not None:
530-
dst_nodata = NODATA_IDX
531-
color_map[dst_nodata] = NODATA_RGBA
549+
# DST_NODATA is a global that was set earlier in scale_grey_1band or
550+
# scale_paletted_1band
551+
dst_nodata = DST_NODATA
532552
else:
533-
# for banded data set the each band's destination nodata to zero (TRANSPARENT).
534-
dst_nodata = TRANSPARENT
553+
# for banded data set each band's destination nodata to zero (TRANSPARENT).
554+
dst_nodata = int(TRANSPARENT)
535555

536556
creation_options = {
537557
**grid_parameters,

hybig/color_utility.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ def get_color_palette(
9898
# (usually the only one)
9999
ds_cmap['nv'] = ds_cmap[ndv_tuple[0]]
100100
# then remove the value associated with the ndv key
101-
ds_cmap.pop(ndv_tuple[0])
101+
# ds_cmap.pop(ndv_tuple[0])
102102
return convert_colormap_to_palette(ds_cmap)
103103
except ValueError:
104104
return None

tests/unit/test_browse.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -348,20 +348,20 @@ def test_convert_singleband_to_raster_with_colormap_and_bad_data(self):
348348
expected_raster = np.array(
349349
[
350350
[ # singleband paletted
351-
[4, 1, 2, 3],
352-
[0, 1, 2, 3],
353-
[0, 1, 2, 3],
354-
[0, 1, 2, 3],
351+
[0, 2, 3, 4],
352+
[1, 2, 3, 4],
353+
[1, 2, 3, 4],
354+
[1, 2, 3, 4],
355355
],
356356
],
357357
dtype='uint8',
358358
)
359359
expected_palette = {
360-
0: (255, 0, 0, 255), # red
361-
1: (255, 255, 0, 255), # yellow
362-
2: (0, 255, 0, 255), # green
363-
3: (0, 0, 255, 255), # blue
364-
4: (10, 20, 30, 40), # nv
360+
0: (10, 20, 30, 40), # nv
361+
1: (255, 0, 0, 255), # red
362+
2: (255, 255, 0, 255), # yellow
363+
3: (0, 255, 0, 255), # green
364+
4: (0, 0, 255, 255), # blue
365365
}
366366

367367
colormap = {**self.colormap, 'nv': nv_color}

0 commit comments

Comments
 (0)