Add RRIM, Multi-Hillshade RGB, and Local Dominance visualizations
Three new visualizations complementing existing SVF/openness/LRM/MSRM: - RRIM (Red Relief Image Map): RGB composite combining positive openness (R), inverted slope (G), negative openness (B). Uses ray-tracing to compute both openness values in a single pass. - Multi-Hillshade RGB: 3 azimuths (315°, 135°, 45°) mapped to R/G/B channels with slope blending. Color reveals structure orientation. - Local Dominance: (dem - local_min) / (local_max - local_min) using min/max filters. Measures local height position — complements openness. Also adds: - _compute_openness_both() helper for shared ray-tracing (used by RRIM) - xp_maximum_filter() in gpu.py (GPU/CPU abstraction) - Entries in COLORMAPS, RGB_LEGENDS, VIZ_STEPS, and is_rgb detection - All NaN handling follows existing patterns (nan_mask restoration) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@ -110,6 +110,16 @@ def xp_minimum_filter(arr, footprint=None, size=None):
|
||||
return ndimage.minimum_filter(arr, footprint=footprint, size=size)
|
||||
|
||||
|
||||
def xp_maximum_filter(arr, footprint=None, size=None):
|
||||
"""Maximum filter — uses GPU if array is on GPU, CPU otherwise."""
|
||||
if _cp is not None and isinstance(arr, _cp.ndarray):
|
||||
try:
|
||||
return _cp_ndimage.maximum_filter(arr, footprint=footprint, size=size)
|
||||
except Exception:
|
||||
arr = to_cpu(arr)
|
||||
return ndimage.maximum_filter(arr, footprint=footprint, size=size)
|
||||
|
||||
|
||||
def gpu_cleanup():
|
||||
"""Free GPU memory. Call between visualizations to prevent OOM."""
|
||||
if _cp is not None:
|
||||
|
||||
Reference in New Issue
Block a user