knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>",
eval = FALSE
)
The Orfeo ToolBox (OTB) provides a collection of command-line
applications for remote sensing and image processing.
link2GI wraps these applications in R with a focus on
reproducibility, transparency, and robustness across OTB
versions.
link2GI supports two layers:
- a legacy wrapper layer (kept for backward compatibility)
- a new Self-describing API (recommended) that
derives parameter metadata from OTB’s own
-helpoutput
Two APIs: legacy vs. Self-describing
Legacy API (parseOTBFunction() /
runOTB())
The legacy layer builds a modifiable R list by parsing the output of:
otbcli <algorithm> -help
Characteristics:
- permissive and convenient
- minimal upfront constraints
- useful for older scripts
Limitations:
- required parameters and defaults are inferred heuristically
- sensitive to OTB help formatting changes
- less suitable for strict, version-stable workflows
Self-describing API (recommended)
The Self-describing API treats the OTB CLI help output as the single source of truth for parameters and their status (mandatory vs. optional). It supports a strict “write-to-disk” workflow and avoids implicit assumptions.
Core functions:
-
otb_capabilities(): retrieve CLI help text (source of truth) -
otb_args_spec(): normalized parameter spec table parsed from-help -
otb_build_cmd(): create arunOTB()-compatible command template (valid keys only) -
otb_set_out(): set file-based outputs safely (including[pixel]outputs)
Minimal workflow (Self-describing)
library(link2GI)
otb <- link2GI::linkOTB(searchLocation = "~/apps/otb911/")
cmd <- link2GI::otb_build_cmd(
"DimensionalityReduction",
otb,
include_optional = "defaults",
require_output = TRUE
)
cmd[["in"]] <- "in.tif"
cmd[["method"]] <- "pca"
cmd[["nbcomp"]] <- "3"
cmd <- link2GI::otb_set_out(cmd, otb, key = "out", path = "out.tif")
str(cmd)Typical transparent workflow (Self-describing)
This example demonstrates a complete workflow:
- link an installed OTB
- read and display the raw
-helpoutput (source of truth) - inspect the parsed parameter table (
spec) - build a command template from valid keys
- set input and explicit output
- run via
runOTB()and verify the output file
NOTE (CRAN/vignette hygiene): this vignette writes outputs into
tempdir().
Example: DimensionalityReduction (PCA)
This example avoids guessing parameter names. The only manual step is
choosing the correct parameter key for “number of components” by reading
the spec table printed from your local
# OTB build (for OTB 9.1.1 this is `nbcomp`).
library(link2GI)
library(terra)
# 0) Link OTB
otb <- link2GI::linkOTB(searchLocation="~/apps/otb911/")
# 1) Choose algorithm
algo <- "DimensionalityReduction"
# 2) Read the OTB help text (source of truth)
caps <- link2GI::otb_capabilities(algo = algo, gili = otb, include_param_help = FALSE)
cat(paste(head(caps$text, 60), collapse = "\n"), "\n")
# 3) Parsed parameter table
spec <- link2GI::otb_args_spec(algo, otb)
print(spec[, c("key", "class", "mandatory", "default")], row.names = FALSE)
# 4) Build a template containing only valid keys (mandatory + defaults)
cmd <- link2GI::otb_build_cmd(
algo,
otb,
include_optional = "defaults",
require_output = TRUE
)
# 5) Identify component-count key by inspecting the spec table (no heuristics)
pca_related <- spec[grepl(r"(^method\.pca\.|^nbcomp$|outdim|comp)", spec$key), ]
print(pca_related[, c("key", "mandatory", "default", "desc")], row.names = FALSE)
# 6) Set PCA method + number of components (OTB 9.1.1: nbcomp)
cmd[["method"]] <- "pca"
cmd[["nbcomp"]] <- "3"
# 7) Input + output (explicit on-disk paths)
infile <- system.file("ex/elev.tif", package = "terra")
out_dir <- file.path(tempdir(), "link2gi_otb_vignette")
dir.create(out_dir, recursive = TRUE, showWarnings = FALSE)
cmd[["in"]] <- infile
cmd[["out"]] <- file.path(out_dir, "pca.tif")
# Show the exact CLI that would be executed
cat(link2GI::runOTB(cmd, otb, retCommand = TRUE), "\n")
# Run (writes to disk)
res <- link2GI::runOTB(cmd, otb, quiet = FALSE)
# Verify output exists
file.exists(cmd[["out"]])Legacy workflow (supported but not recommended)
The legacy workflow builds a command list by parsing
-help output and then executes it. Because the legacy
parser may expose parameter names that vary between OTB versions/apps,
the safe pattern is:
- parse the command list
- inspect
names(cmd)/cmd$help(if present) - set inputs/outputs and required parameters explicitly
- run
library(link2GI)
otb <- link2GI::linkOTB()
algo <- "EdgeExtraction"
cmd <- link2GI::parseOTBFunction(algo = algo, gili = otb)
# inspect keys (legacy API may expose app-specific names)
names(cmd)
# then set required parameters according to the returned structure:
# cmd[["<input_key>"]] <- "in.tif"
# cmd[["<output_key>"]] <- "out.tif"
# cmd[["<other_key>"]] <- "value"
# finally execute
# link2GI::runOTB(cmd, gili = otb, quiet = FALSE)What changed (Self-describing)
The new Self-describing API removes fragile heuristics and centralizes metadata on:
- OTB’s own
Parameters:block emitted by<Algo> -help
Consequences:
-
otb_capabilities()/otb_args_spec()become the source of truth -
otb_build_cmd()prevents invalid keys (reduces “parameter does not exist” failures) -
runOTB()on Linux/macOS uses the OTB launcher plus explicit environment, matching the help/spec stack - Windows isolation is handled by
runOTB_isolated()viaotbenv.ps1/.bat
Compatibility and deprecations
Compatibility
- Existing scripts using
parseOTBFunction()plusrunOTB()should continue to work (best-effort). - The Self-describing API is stable as long as OTB provides a
parseable
Parameters:section.
Deprecations (explicit list)
-
parseOTBFunction()is legacy (supported, but not recommended for new code). -
parseOTBAlgorithms()is legacy (if present in your build; preferotb_capabilities()).
For new projects, prefer:
otb_capabilities() + otb_args_spec() +
otb_build_cmd() + otb_set_out() then
runOTB().
