# catalog/operations/raster/reclassify.yaml

id: raster_reclassify
name: Reclassify
description: >
  Remap raster values to new classes based on a classification table.
  Supports manual breaks (value ranges mapped to new values), equal
  interval, quantile, and direct value mapping.
version: 1.0.0
category: raster
type: raster-to-raster
default_implementation: native

inputs:
  - name: raster
    type: raster
    format: geotiff
    description: Input raster to reclassify
    required: true

requires: {}  # structural — operates on any raster

outputs:
  - name: classified
    type: raster
    format: cog
    dtype: float32
    description: Reclassified raster with new class values

params:
  method:
    type: string
    default: manual
    enum: [manual, equal_interval, quantile, value_map]
    description: >
      Classification method:
      - manual: User-defined break points and class values
      - equal_interval: Divide range into N equal-width bins
      - quantile: Divide data into N bins with equal count
      - value_map: Direct value-to-value mapping
  breaks:
    type: number[]
    description: >
      Break points for manual classification. Values <= breaks[0] get
      class_values[0], values in (breaks[i-1], breaks[i]] get class_values[i].
      Required for method=manual.
  class_values:
    type: number[]
    description: >
      Output class values corresponding to each bin. Length must be
      len(breaks) + 1 for manual method, or n_classes for equal_interval
      and quantile methods.
  n_classes:
    type: integer
    default: 5
    description: Number of classes for equal_interval and quantile methods
    min: 2
    max: 100
  value_map:
    type: object
    description: >
      Direct value mapping for method=value_map. Keys are source values
      (as strings), values are target values. Example: {"1": 10, "2": 20}
  labels:
    type: string[]
    description: Optional labels for each class (for metadata/legend)
  nodata_class:
    type: number
    description: >
      Value to assign to nodata pixels (default: keep as nodata)
  crosswalk:
    type: string
    description: >
      Crosswalk ID to resolve from the registry.  Resolved to a value_map
      at execution time via crosswalk_to_value_map().  Implies method=value_map.
      If both crosswalk and value_map are provided, value_map takes precedence.
      Example: "nlcd-to-esa-worldcover"
  include_broad:
    type: boolean
    default: false
    description: >
      When using crosswalk, include broad-predicate mappings in addition
      to exact and close matches (default: only exact + close).

cache_policy:
  ttl_days: 30
  invalidate_on: [source_update, param_change]

# 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:
    handle_function: h_raster_reclassify
  js:
    function: raster_reclassify
  python:
    function: geo.raster.reclassify
    dispatch: folia/compute.py _BUILTIN_OP_MAP

display_hints:
  map:
    renderer: maplibre
    palette: categorical
    opacity: 0.8
  info:
    fields: [class_value, class_label]
    section: Classification

ui:
  icon: grid
  color: "#F59E0B"
