Audit: corrections de bugs identifiés
- rendering.py: colorbar cassée quand NaN mask actif — créer un ScalarMappable avec le cmap sauvegardé au lieu de rely sur l'image RGBA qui n'a plus de cmap - rendering.py: nettoyage du PNG temporaire avec try/finally et missing_ok=True pour éviter les fichiers orphelins - gpu.py: to_gpu() convertit en float32 au lieu de float64 pour réduire la consommation mémoire GPU - dtm.py: utiliser _file_basename() de pipeline.py au lieu de dupliquer la logique d'extraction du basename - pipeline.py: docstring corrigé (18 visualisations, pas 19) - cli.py: --file supporte aussi les noms sans .copc (recherche .copc.laz et .copc.las en plus de .laz et .las) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@ -345,13 +345,19 @@ def tif_to_png(tif_file, vis_dir, resolution):
|
||||
has_nan_mask = nan_mask is not None and not is_rgb_result
|
||||
if has_nan_mask:
|
||||
# data is normalized 0-1 from _apply_colormap; apply cmap to get RGBA
|
||||
cmap_obj = plt.get_cmap(cmap) if isinstance(cmap, str) else cmap
|
||||
rgba = cmap_obj(data) # (H, W, 4) float RGBA
|
||||
# Save the colormap for colorbar before converting to RGBA
|
||||
saved_cmap = plt.get_cmap(cmap) if isinstance(cmap, str) else cmap
|
||||
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
|
||||
rgba[nan_mask, 3] = 0.0 # transparent where no data
|
||||
data = rgba
|
||||
is_rgba = True
|
||||
else:
|
||||
is_rgba = False
|
||||
saved_cmap = None
|
||||
saved_vmin = None
|
||||
saved_vmax = None
|
||||
|
||||
# Create figure — adapt width to data resolution for sharp rendering
|
||||
# At high res (5000+px wide), we need a larger figure to avoid downsampling artifacts
|
||||
@ -375,7 +381,14 @@ def tif_to_png(tif_file, vis_dir, resolution):
|
||||
ax.set_title(f"{title}\n{description}", fontsize=15, fontweight='bold', pad=10)
|
||||
|
||||
if not is_rgb:
|
||||
cbar = plt.colorbar(im, ax=ax, pad=0.02, shrink=0.85, aspect=30)
|
||||
if is_rgba and saved_cmap is not None:
|
||||
# Create a ScalarMappable for the colorbar from the saved colormap
|
||||
sm = plt.cm.ScalarMappable(cmap=saved_cmap,
|
||||
norm=plt.Normalize(vmin=saved_vmin, vmax=saved_vmax))
|
||||
sm.set_array([])
|
||||
cbar = plt.colorbar(sm, ax=ax, pad=0.02, shrink=0.85, aspect=30)
|
||||
else:
|
||||
cbar = plt.colorbar(im, ax=ax, pad=0.02, shrink=0.85, aspect=30)
|
||||
cbar.ax.tick_params(labelsize=9, width=1.5)
|
||||
cbar.outline.set_linewidth(1.5)
|
||||
cbar.set_label(legend_label, fontsize=10, fontweight='bold')
|
||||
@ -486,16 +499,18 @@ def tif_to_png(tif_file, vis_dir, resolution):
|
||||
# Save as PNG then convert to WebP — use higher DPI for large data
|
||||
save_dpi = 200 if width > 3000 else 150
|
||||
png_temp = vis_dir / f"{tif_file.stem}_temp.png"
|
||||
plt.savefig(png_temp, dpi=save_dpi, bbox_inches='tight', pad_inches=0.15,
|
||||
facecolor='white', format='png')
|
||||
plt.close()
|
||||
try:
|
||||
plt.savefig(png_temp, dpi=save_dpi, bbox_inches='tight', pad_inches=0.15,
|
||||
facecolor='white', format='png')
|
||||
finally:
|
||||
plt.close()
|
||||
|
||||
img = PILImage.open(str(png_temp))
|
||||
img.save(str(webp_file), format='WEBP', lossless=True)
|
||||
png_temp.unlink()
|
||||
png_temp.unlink(missing_ok=True)
|
||||
|
||||
# Delete source TIFF
|
||||
tif_file.unlink()
|
||||
tif_file.unlink(missing_ok=True)
|
||||
|
||||
return webp_file
|
||||
|
||||
|
||||
Reference in New Issue
Block a user