Masquer le nodata avant étalonnage colormap et colorbar en unités réelles
This commit is contained in:
@ -189,7 +189,8 @@ for _key, _info in RGB_LEGENDS.items():
|
||||
def _apply_colormap(data, tif_file, resolution=None):
|
||||
"""Apply the registered colormap normalization to data based on filename.
|
||||
|
||||
Returns (data, cmap, title, legend_label, description, is_rgb).
|
||||
Returns (data, cmap, title, legend_label, description, is_rgb, vmin, vmax)
|
||||
où vmin/vmax sont les bornes physiques de la plage rendue (None si sans objet).
|
||||
"""
|
||||
name = str(tif_file).lower()
|
||||
|
||||
@ -197,7 +198,7 @@ def _apply_colormap(data, tif_file, resolution=None):
|
||||
for key in RGB_LEGENDS:
|
||||
if key in name:
|
||||
info = RGB_LEGENDS[key]
|
||||
return data, None, info['title'], info['legend'], info['description'], True
|
||||
return data, None, info['title'], info['legend'], info['description'], True, None, None
|
||||
|
||||
# Find matching colormap — sort by key length descending so 'mslrm' matches before 'lrm'
|
||||
for key in sorted(COLORMAPS.keys(), key=len, reverse=True):
|
||||
@ -208,7 +209,7 @@ def _apply_colormap(data, tif_file, resolution=None):
|
||||
|
||||
if len(valid_data) == 0:
|
||||
logger.warning(f" Aucune donnée valide pour {Path(tif_file).name} — colormap ignorée")
|
||||
return data, 'terrain', Path(tif_file).stem.replace('_', ' ').title(), '', '', False
|
||||
return data, 'terrain', Path(tif_file).stem.replace('_', ' ').title(), '', '', False, None, None
|
||||
|
||||
vmin = vmax = None
|
||||
|
||||
@ -253,7 +254,7 @@ def _apply_colormap(data, tif_file, resolution=None):
|
||||
data = np.clip((data - vmin) / max(vmax - vmin, 0.001), 0, 1)
|
||||
|
||||
legend = info['legend'].format(vmin=vmin or 0, vmax=vmax or 0)
|
||||
return data, info['cmap'], info['title'], legend, info['description'], False
|
||||
return data, info['cmap'], info['title'], legend, info['description'], False, vmin, vmax
|
||||
|
||||
# Default: terrain colormap with percentile stretch
|
||||
valid_data = np.asarray(data.compressed() if hasattr(data, 'compressed') else data.flatten())
|
||||
@ -265,7 +266,7 @@ def _apply_colormap(data, tif_file, resolution=None):
|
||||
span = max(p98 - p2, 1e-6)
|
||||
data = np.clip((data - p2) / span, 0, 1)
|
||||
title = Path(tif_file).stem.replace('_', ' ').title()
|
||||
return data, 'terrain', title, 'Altitude normalisée', '', False
|
||||
return data, 'terrain', title, 'Altitude normalisée', '', False, p2, p98
|
||||
|
||||
|
||||
def _download_location_map(min_x, max_x, min_y, max_y):
|
||||
@ -453,7 +454,7 @@ def tif_to_png(tif_file, vis_dir, resolution, keep_tif=False, source_info=None,
|
||||
nan_mask = nan_mask # keep for later
|
||||
|
||||
# Apply colormap
|
||||
data, cmap, title, legend_label, description, is_rgb_result = _apply_colormap(data, tif_file, resolution=resolution)
|
||||
data, cmap, title, legend_label, description, is_rgb_result, cmap_vmin, cmap_vmax = _apply_colormap(data, tif_file, resolution=resolution)
|
||||
|
||||
# Apply NaN mask: make zones without data transparent
|
||||
has_nan_mask = nan_mask is not None and not is_rgb_result
|
||||
@ -461,6 +462,10 @@ def tif_to_png(tif_file, vis_dir, resolution, keep_tif=False, source_info=None,
|
||||
# data is normalized 0-1 from _apply_colormap; apply cmap to get RGBA
|
||||
# Save the colormap for colorbar before converting to RGBA
|
||||
saved_cmap = plt.get_cmap(cmap) if isinstance(cmap, str) else cmap
|
||||
# Bornes physiques de la colorbar (unités réelles, pas 0-1)
|
||||
if cmap_vmin is not None and cmap_vmax is not None:
|
||||
saved_vmin, saved_vmax = float(cmap_vmin), float(cmap_vmax)
|
||||
else:
|
||||
saved_vmin = float(np.nanmin(data)) if not nan_mask.all() else 0
|
||||
saved_vmax = float(np.nanmax(data)) if not nan_mask.all() else 1
|
||||
rgba = saved_cmap(data) # (H, W, 4) float RGBA
|
||||
@ -806,9 +811,14 @@ def tif_to_crop(tif_file, vis_dir, resolution, keep_tif=False, quality=98, outpu
|
||||
data = np.moveaxis(data, 0, -1)
|
||||
else:
|
||||
data = src.read(1)
|
||||
# Nodata → NaN : sinon les pixels bord (ex. -9999, 3.4e38)
|
||||
# polluent les percentiles d'étalonnage de la colormap
|
||||
if src.nodata is not None:
|
||||
data = data.astype(np.float32, copy=False)
|
||||
data[data == src.nodata] = np.nan
|
||||
|
||||
# Apply colormap normalization
|
||||
data, cmap_name, title, legend_label, description, is_rgb_result = _apply_colormap(data, tif_file, resolution=resolution)
|
||||
data, cmap_name, title, legend_label, description, is_rgb_result, _cvmin, _cvmax = _apply_colormap(data, tif_file, resolution=resolution)
|
||||
|
||||
if not is_rgb_result:
|
||||
data = np.where(np.isnan(data), 0.0, data)
|
||||
|
||||
Reference in New Issue
Block a user