Brute force search
Automatic searching and finding of installed GIS software binaries is
done by the find functions. Depending on your operating
system and the number of installed versions you will get a data frame
with the binary and module folders.
# find all SAGA GIS installations at the default search location
require(link2GI)
saga <- link2GI::findSAGA()
sagaSame with GRASS and OTB
require(link2GI)
if (Sys.info()["sysname"] == "Windows") {
grass <- link2GI::findGRASS(searchLocation = "C:/")
otb <- link2GI::findOTB(searchLocation = "C:/")
} else {
grass <- link2GI::findGRASS(searchLocation = "/usr/bin",quiet = FALSE)
otb <- link2GI::findOTB(searchLocation = "~/apps/otb911/",quiet = FALSE)
}
grass
otbThe `find’ functions provide an overview of the installed software. These functions do not create links or change settings.
Setting up project structures
If you are just calling link2GI on the fly, i.e. for a single
temporary operation, there is no need to set up folders and project
structures. If you are working on a more complex project, it might be
helpful to have a fixed structure. The same goes for existing
GRASS projects that need to be in specific mapsets and
locations.
A simple (you can call it dirty) approach is the
initProj function, which creates folder structures (if not
existing) and sets global variables (if desired) containing the paths as
strings.
linkSAGA - Find and set up ‘SAGA’ API bindings
In the past it was quite tedious to link the correct
SAGA GIS version. Since version 1.x.x of RSAGA
things are much better. The new RSAGA::rsaga.env() function
is to get the first RSAGA version in the search path. It is
also possible to pass the version number as shown below. Storing the
result in appropriate variables will even allow you to easily switch
between different SAGA GIS installations.
Find and set up GRASS 7/8 API bindings
Important note: GRASS runtime environment
GRASS GIS relies on a correctly initialized runtime environment (PATH, GISBASE, PROJ, GDAL, Python bindings).
R (or RStudio) must be started from an environment where these
variables are already set. Otherwise, rgrass and GRASS
command-line calls may fail.
Windows (OSGeo4W)
If GRASS is installed via OSGeo4W, R or RStudio must be started from the OSGeo4W Shell.
OSGeo4W initializes required variables such as
OSGEO4W_ROOT, PATH, PROJ_LIB, and
GDAL_DATA.
Linux
On Linux, GRASS environment variables are usually set by system startup scripts or shell profiles.
If GRASS was installed manually, via custom builds, containers, or
non-standard locations, R must be started from the same shell session
where GRASS is available (e.g. after grass --text or
sourcing GRASS startup scripts).
linkGRASS
linkGRASS initializes the session environment and system
paths for easy access to GRASS GIS 7.x./8.x. The correct
setting of spatial and projection parameters is done automatically
either by using an existing and valid raster or
terra, sp or sf object or
manually by providing a list of minimum required parameters. These
properties are used to initialize either a temporary or a permanent
rgrass environment, including the correct
GRASS 7/8 database structure. If you do not specify any of
the above, linkGRASS will create an EPSG:4326 worldwide
site.
The most time consuming part on Windows systems is the search
process. This can easily take 10 minutes or more. To speed up this
process, you can also provide a correct parameter set. The best way to
do this is to call findGRASS manually. Then call
linkGRASS with the returned version arguments of your
choice.
The linkGRASS function tries to find all valid
GRASS GIS binaries by analyzing the GRASS GIS
startup script files. After identifying the GRASS GIS
binaries, all necessary system variables and settings are generated and
passed to a temporary R environment.
If you have more than one valid installation and run
linkGRASS with the arguments
select_ver = TRUE, you will be asked to select one.
Standard full search usage
The most common use of GRASS is for a single call or
algorithm. The user is not interested in setting all the parameters.
linkGRASS/findGRASS does an automatic search
and finds all the GRASS binaries using the
georeferenced-dataset object for spatial referencing and other necessary
settings. NOTE: This is the highly recommended linking
procedure for all on-the-fly invocations of GRASS. Please
also note that if more than one GRASS installation is
found, the one with the highest version number is automatically
selected.
Take a look at the following examples, which show a typical call for
the well-known sp and sf vector data
objects.
Starting with sp.
# get meuse data as sp object and link it temporary to GRASS
require(link2GI)
require(sf)
require(sp)
crs = 28992
# get data
data(meuse)
meuse_sf = st_as_sf(meuse, coords = c("x", "y"), crs = crs, agr = "constant")
# Automatic search and find of GRASS binaries
# using the meuse sp data object for spatial referencing
# This is the highly recommended linking procedure for on the fly jobs
# NOTE: if more than one GRASS installation is found the highest version will be selected
link2GI::linkGRASS(meuse_sf,epsg = crs,quiet = FALSE)Now do the same with sf based data.
require(link2GI)
require(sf)
# get data
nc <- st_read(system.file("shape/nc.shp", package="sf"))
terra::crs(nc)
# Automatic search and find of GRASS binaries
# using the nc sf data object for spatial referencing
# This is the highly recommended linking procedure for on the fly jobs
# NOTE: if more than one GRASS installation is found the highest version will be selected
grass<-linkGRASS(nc,returnPaths = TRUE)The second most common situation is to use an existing
GRASS site and project, either with existing data sets or
manually provided parameters.
require(link2GI)
require(sf)
# proj folders
root_folder<-tempdir()
paths<-link2GI::createFolders(root_folder = root_folder,
folders = c("project1/"))
# get data
nc <- st_read(system.file("shape/nc.shp", package="sf"))
# CREATE and link to a permanent GRASS folder at "root_folder", location named "project1"
linkGRASS(nc, gisdbase = root_folder, location = "project1", quiet = FALSE)
# ONLY LINK to a permanent GRASS folder at "root_folder", location named "project1"
linkGRASS(gisdbase = root_folder, location = "project1", gisdbase_exist = TRUE, quiet = FALSE )
# setting up GRASS manually with spatial parameters of the nc data
epsg = 28992
proj4_string <- sp::CRS(paste0("+init=epsg:",epsg))
linkGRASS(spatial_params = c(178605,329714,181390,333611,proj4_string@projargs),epsg=epsg,quiet = FALSE)
# creating a GRASS gisdbase manually with spatial parameters of the nc data
# additionally using a peramanent directory "root_folder" and the location "nc_spatial_params "
epsg = 4267
proj4_string <- sp::CRS(paste0("+init=epsg:",epsg))@projargs
linkGRASS(gisdbase = root_folder,
location = "nc_spatial_params",
spatial_params = c(-84.32385, 33.88199,-75.45698,36.58965,proj4_string),epsg = epsg)Typical for specified search paths and OS
The full disk search can be tedious, especially on Windows it can
easily take 10 minutes or more. So it is helpful to specify a search
path to narrow down the search. To search for GRASS
installations in the home directory, you can use the following
command.
Manual Linking Linux
# Link the GRASS installation and define the search location
linkGRASS(nc, search_path = "~/apps/otb911")If you already did a full search and kow your installation fo example
using the command findGRASS you can use the result directly
for linking.
instDir version installation_type
1 /usr/lib/grass83 8.3.2 grass
Manual Linking Windows
# Link the GRASS installation and define the search location
linkGRASS(nc, search_path = "C:", quiet = FALSE)If you already did a full search and kow your installation fo example
using the command findGRASS you can use the result directly
for linking.
instDir version installation_type
1 C:/OSGeo4W 8.4.1 osgeo4w
Specific examples
Finally, some more specific examples related to interactive selection or OS-specific settings.
Manual version selection
Manually select the GRASS installation and use the meuse
sf object for spatial referencing. If you only have one
installation it is directly selected.
linkGRASS(nc, ver_select = TRUE)Creating a permanent gisdbase folder
Create and link a permanent GRASS gisdbase (folder
structure) in “~/temp3” with the default mapset “PERMANENT”” and the
location “project1”. Use the sf object for all spatial
attributes.
linkGRASS(x = nc,
gisdbase = "~/temp3",
location = "project1") Using a permanent gisdbase folder
Link to the permanent GRASS gisdbase (folder structure)
in “~/temp3” with the default mapset “PERMANENT” and the location named
“project1”. Use the formerly referencend nc sf object
parameter for all spatial attributes.
linkGRASS(gisdbase = "~/temp3", location = "project1",
gisdbase_exist = TRUE) A typical use case for the Orfeo Toolbox wrapper
link2GI supports the use of the Orfeo Toolbox with a simple list-based wrapper function. Actually, two functions parse the module and function syntax dumps and generate a command list that can be easily modified with the necessary arguments. If you have installed it in a user home directory you need to adrees this:
Usually you have to get the module list first:
# link to the installed OTB Linux HOME directory
otblink<-link2GI::linkOTB(searchLocation = "~/apps/")
# get the list of modules from the linked version
algo<-parseOTBAlgorithms(gili = otblink)
algo <- link2GI::otb_capabilities(gili = otblink)Based on the modules of the current version of `OTB’, you can then select the module(s) you want to use.
## for the example we use the edge detection,
## ------------------------------------------------------------
## 1) Select an OTB algorithm by name pattern
## ------------------------------------------------------------
## grep() returns *all* matching algorithm names as a character vector.
## This is intentional for exploration, but NOT valid for execution.
algoKeyword <- grep("edge", algo, value = TRUE, ignore.case = TRUE)
## Inspect matches (important!)
algoKeyword
length(algoKeyword)
## ------------------------------------------------------------
## 2) Select exactly ONE algorithm (mandatory)
## ------------------------------------------------------------
## Explicitly pick one algorithm from the matches.
## This avoids ambiguity and guarantees a scalar character value.
algo <- algoKeyword[[1]]
## ------------------------------------------------------------
## 3) Read OTB help text (capabilities)
## ------------------------------------------------------------
## This parses the OTB -help output and returns the raw help text.
## This is the *authoritative source* for parameters.
caps <- link2GI::otb_capabilities(algo = algo, gili = otblink)
## Print the help text to understand available parameters
cat(paste(caps$text, collapse = "\n"))
## ------------------------------------------------------------
## 4) Parse parameters into a structured table
## ------------------------------------------------------------
## otb_args_spec() converts the help text into a data.frame
## with keys, types, defaults, and mandatory flags.
spec <- link2GI::otb_args_spec(algo = algo, gili = otblink)
## Inspect the relevant parameter metadata
spec[, c("key", "mandatory", "default", "class")]
## ------------------------------------------------------------
## 5) Build a command template with valid parameters only
## ------------------------------------------------------------
## otb_build_cmd() creates a named list with:
## - required parameters
## - optional parameters with defaults (if requested)
## - no execution yet
cmd <- link2GI::otb_build_cmd(
algo,
gili = otblink,
include_optional = "defaults",
require_output = TRUE
)
## Inspect the command structure
str(cmd)
## ------------------------------------------------------------
## 6) Show the exact CLI command that WOULD be executed
## ------------------------------------------------------------
## retCommand = TRUE prints the full otbApplicationLauncherCommandLine call
## without running it. This is crucial for transparency and debugging.
cat(link2GI::runOTB(cmd, otblink, retCommand = TRUE), "\n")This is a minimal discovery workflow that queries the linked OTB installation and returns the full list of available applications. The result is a plain character vector, so you can filter it (e.g., with grep()) and then inspect parameters for a single application using the introspection helpers.
require(link2GI)
require(terra)
require(listviewer)
# 0) Link OTB
otblink <- link2GI::linkOTB(searchLocation = "~/apps/")
root_folder <- tempdir()
fn <- system.file("ex/elev.tif", package = "terra")
# 1) Choose the application (must be a single character scalar)
algoKeyword <- "EdgeExtraction"
# 2) Create a command template with valid keys (defaults included)
cmd <- link2GI::otb_build_cmd(
algo = algoKeyword,
gili = otblink,
include_optional = "defaults",
require_output = TRUE
)
# 3) Set mandatory arguments (same values as legacy example)
cmd[["in"]] <- fn
cmd[["filter"]] <- "touzi"
cmd[["channel"]] <- "1"
# 4) Set explicit on-disk output (recommended API: otb_set_out)
out_file <- file.path(root_folder, paste0("out", cmd[["filter"]], ".tif"))
cmd <- link2GI::otb_set_out(cmd, gili = otblink, key = "out", path = out_file)
# 5) Run the algorithm and read output as a raster
retStack <- link2GI::runOTB(cmd, gili = otblink, retRaster = TRUE)
# 8) Plot result
plot(retStack)Usecases presented on the GEOSTAT August 2018
Important note
The use cases presented at GEOSTAT (August 2018) are outdated. They reflect the software ecosystem, interfaces, and platform assumptions available at that time and should not be interpreted as representing the current state of
link2GI, GRASS GIS, or related toolchains.
During the GEOSTAT 2018 (see https://opengeohub.org) in Prague some more complex use cases have been presented.
The examples
- Basic usage of
SAGAandOTBcalls - SAGA & OTB basic usecase - Wrapping a GRASS GIS example of Markus Neteler as presented on GEOSTAT 2018 - Analysing the ECA&D climatic data - reloaded
- Performing a
GRASSbased cost analysis on a huge cost raster - Beetle spread over high asia - Deriving a canopy height model using a mixed API approach - Canopy Height Model from UAV derived point clouds
