# catalog/operations/terrain/hillshade.yaml

id: terrain_hillshade
name: Hillshade
description: >
  Generate hillshade visualization from DEM. Simulates illumination from
  a light source at specified azimuth and altitude angles. Output is 8-bit
  grayscale where 0=shadow and 255=full illumination.
version: 1.0.0
category: terrain
type: raster-to-raster
default_implementation: native

inputs:
  - name: dem
    type: raster
    format: cog
    description: Input Digital Elevation Model (GeoTIFF or COG)
    required: true

requires:
  concepts: [elevation]

outputs:
  - name: hillshade
    type: raster
    format: cog
    dtype: uint8
    concept: hillshade
    description: Hillshade raster (0=shadow, 255=bright)

params:
  azimuth:
    type: number
    default: 315
    description: Light source azimuth (degrees clockwise from north)
    min: 0
    max: 360
  altitude:
    type: number
    default: 45
    description: Light source altitude (degrees above horizon)
    min: 0
    max: 90
  z_factor:
    type: number
    default: 1.0
    description: Vertical exaggeration factor
    min: 0.1
    max: 10.0
  algorithm:
    type: enum
    default: horn
    enum: [horn, zevenbergen_thorne]
    description: Algorithm for slope/aspect calculation
  multidirectional:
    type: boolean
    default: false
    description: Use multidirectional lighting for more natural appearance

granularity:
  min_resolution_m: 1
  max_resolution_m: 90
  recommended_resolution_m: 10
  output_resolution: inherit
  suitable_aoi_km2:
    min: 0.01
    max: 100000
  realtime_max_km2: 500
  requires_continuous: true

uncertainty:
  error_model: propagated
  factors:
    - name: dem_vertical_accuracy
      description: "Shadow boundaries shift with DEM errors"
      severity: low
      mitigations:
        - "Use higher-accuracy DEM for shadow-critical analyses"
    - name: lighting_parameters
      description: "Azimuth/altitude choices affect visual interpretation"
      severity: low
      mitigations:
        - "Use multidirectional mode for general visualization"
  limitations:
    - "Purely visual derivative, not suitable for quantitative analysis"
    - "Single light source creates artificial shadow patterns"

execution:
  realtime_max_km2: 500
  cost_per_km2: 0.0005
  time_per_km2_sec: 0.3
  memory_profile: low
  profile:
    cpu: low
    memory: low
    io: medium
  scaling:
    model: linear
    parallelizable: true
    min_chunk_km2: 1

default_input:
  connector: usgs_3dep
  params:
    resolution: 10m

# backends: audited 2026-08-14 (defect 50). A key means a runtime that DISPATCHES this op —
# folia-engine `dispatch_op` (products/sdk/folia-engine/src/lib.rs), a `registerOp`/OP_TABLE
# entry in packages/compute, `_BUILTIN_OP_MAP` in folia/compute.py, or a backend manifest
# (folia/backends/*/backend.yaml).
backends:
  rust-wasm:
    function: terrain_ops::terrain_hillshade
    handle_function: h_terrain_hillshade
  js:
    function: terrain_hillshade
  python:
    function: geo.terrain.hillshade
    dispatch: folia/compute.py _BUILTIN_OP_MAP
  gee:
    function: folia.backends.gee.ops.hillshade
    dispatch: folia/backends/gee/backend.yaml

display_hints:
  map:
    renderer: maplibre
    palette: grayscale
    opacity: 0.7
    rescale: "1,255"
    colormap: gray

cache_policy:
  regional_precompute: [us_national_parks, ski_areas]
  ttl_days: 365
  invalidate_on: [source_update]
