r.lfp
Calculates the longest flow paths from a flow direction raster map and a outlets vector map using the Memory-Efficient Longest Flow Path (MELFP) OpenMP parallel algorithm by Cho (2025).
r.lfp [-f] direction=name format=string [encoding=string] outlets=name [layer=string] [column=name] [lfp=name] [heads=name] [coordinates=name] [output_column=name] [tss=integer] [nprocs=integer] [--overwrite] [--verbose] [--quiet] [--qq] [--ui]
Example:
r.lfp direction=name format=auto outlets=name lfp=name
grass.script.run_command("r.lfp", direction, format="auto", encoding=None, outlets, layer="1", column="cat", lfp=None, heads=None, coordinates=None, output_column=None, tss=3072, nprocs=0, flags=None, overwrite=None, verbose=None, quiet=None, superquiet=None)
Example:
gs.run_command("r.lfp", direction="name", format="auto", outlets="name", lfp="name")
grass.tools.Tools.r_lfp(direction, format="auto", encoding=None, outlets, layer="1", column="cat", lfp=None, heads=None, coordinates=None, output_column=None, tss=3072, nprocs=0, flags=None, overwrite=None, verbose=None, quiet=None, superquiet=None)
Example:
tools = Tools()
tools.r_lfp(direction="name", format="auto", outlets="name", lfp="name")
This grass.tools API is experimental in version 8.5 and expected to be stable in version 8.6.
Parameters
direction=name [required]
Name of input flow direction raster map
format=string [required]
Format of input flow direction raster map
Allowed values: auto, degree, 45degree, power2, taudem, custom
Default: auto
auto: auto-detect direction format except taudem
degree: degrees CCW from East
45degree: degrees CCW from East divided by 45 (e.g. r.watershed)
power2: powers of 2 CW from East (e.g., r.terraflow, ArcGIS)
taudem: 1-8 for E-SE CCW, not auto-detected (e.g., TauDEM D8FlowDir)
custom: use encoding
encoding=string
Flow direction encoding for custom format
Eight integers for E,SE,S,SW,W,NW,N,NE
outlets=name [required]
Name of input outlets vector map
Or data source for direct OGR access
layer=string
Layer number or name
Vector features can have category values in different layers. This number determines which layer to use. When used with direct OGR access this is the layer name.
Default: 1
column=name
Name of input attribute column for outlet IDs
Using a non-cat column is slower because of database access
Default: cat
lfp=name
Name for output longest flow paths vector map
heads=name
Name for output longest flow path heads vector map
coordinates=name
Name for output longest flow path head coordinates file
output_column=name
Name for output attribute column for outlet IDs
tss=integer
Threshold size of tracing stack for switching to tasking
0: guess using sqrt(cells) / threads
Allowed values: 0-
Default: 3072
nprocs=integer
Number of threads for parallel computing
0: use OpenMP default; >0: use nprocs; <0: use MAX-nprocs
Default: 0
-f
Find full longest flow paths
--overwrite
Allow output files to overwrite existing files
--help
Print usage summary
--verbose
Verbose module output
--quiet
Quiet module output
--qq
Very quiet module output
--ui
Force launching GUI dialog
direction : str, required
Name of input flow direction raster map
Used as: input, raster, name
format : str, required
Format of input flow direction raster map
Allowed values: auto, degree, 45degree, power2, taudem, custom
auto: auto-detect direction format except taudem
degree: degrees CCW from East
45degree: degrees CCW from East divided by 45 (e.g. r.watershed)
power2: powers of 2 CW from East (e.g., r.terraflow, ArcGIS)
taudem: 1-8 for E-SE CCW, not auto-detected (e.g., TauDEM D8FlowDir)
custom: use encoding
Default: auto
encoding : str, optional
Flow direction encoding for custom format
Eight integers for E,SE,S,SW,W,NW,N,NE
outlets : str, required
Name of input outlets vector map
Or data source for direct OGR access
Used as: input, vector, name
layer : str, optional
Layer number or name
Vector features can have category values in different layers. This number determines which layer to use. When used with direct OGR access this is the layer name.
Used as: input, layer
Default: 1
column : str, optional
Name of input attribute column for outlet IDs
Using a non-cat column is slower because of database access
Used as: input, dbcolumn, name
Default: cat
lfp : str, optional
Name for output longest flow paths vector map
Used as: output, vector, name
heads : str, optional
Name for output longest flow path heads vector map
Used as: output, vector, name
coordinates : str, optional
Name for output longest flow path head coordinates file
Used as: output, file, name
output_column : str, optional
Name for output attribute column for outlet IDs
Used as: input, dbcolumn, name
tss : int, optional
Threshold size of tracing stack for switching to tasking
0: guess using sqrt(cells) / threads
Allowed values: 0-
Default: 3072
nprocs : int, optional
Number of threads for parallel computing
0: use OpenMP default; >0: use nprocs; <0: use MAX-nprocs
Default: 0
flags : str, optional
Allowed values: f
f
Find full longest flow paths
overwrite : bool, optional
Allow output files to overwrite existing files
Default: None
verbose : bool, optional
Verbose module output
Default: None
quiet : bool, optional
Quiet module output
Default: None
superquiet : bool, optional
Very quiet module output
Default: None
direction : str | np.ndarray, required
Name of input flow direction raster map
Used as: input, raster, name
format : str, required
Format of input flow direction raster map
Allowed values: auto, degree, 45degree, power2, taudem, custom
auto: auto-detect direction format except taudem
degree: degrees CCW from East
45degree: degrees CCW from East divided by 45 (e.g. r.watershed)
power2: powers of 2 CW from East (e.g., r.terraflow, ArcGIS)
taudem: 1-8 for E-SE CCW, not auto-detected (e.g., TauDEM D8FlowDir)
custom: use encoding
Default: auto
encoding : str, optional
Flow direction encoding for custom format
Eight integers for E,SE,S,SW,W,NW,N,NE
outlets : str, required
Name of input outlets vector map
Or data source for direct OGR access
Used as: input, vector, name
layer : str, optional
Layer number or name
Vector features can have category values in different layers. This number determines which layer to use. When used with direct OGR access this is the layer name.
Used as: input, layer
Default: 1
column : str, optional
Name of input attribute column for outlet IDs
Using a non-cat column is slower because of database access
Used as: input, dbcolumn, name
Default: cat
lfp : str, optional
Name for output longest flow paths vector map
Used as: output, vector, name
heads : str, optional
Name for output longest flow path heads vector map
Used as: output, vector, name
coordinates : str, optional
Name for output longest flow path head coordinates file
Used as: output, file, name
output_column : str, optional
Name for output attribute column for outlet IDs
Used as: input, dbcolumn, name
tss : int, optional
Threshold size of tracing stack for switching to tasking
0: guess using sqrt(cells) / threads
Allowed values: 0-
Default: 3072
nprocs : int, optional
Number of threads for parallel computing
0: use OpenMP default; >0: use nprocs; <0: use MAX-nprocs
Default: 0
flags : str, optional
Allowed values: f
f
Find full longest flow paths
overwrite : bool, optional
Allow output files to overwrite existing files
Default: None
verbose : bool, optional
Verbose module output
Default: None
quiet : bool, optional
Quiet module output
Default: None
superquiet : bool, optional
Very quiet module output
Default: None
Returns:
result : grass.tools.support.ToolResult | None
If the tool produces text as standard output, a ToolResult object will be returned. Otherwise, None
will be returned.
DESCRIPTION
r.lfp calculates the longest flow paths for given outlet points using the Memory-Efficient Longest Flow Path (MELFP) OpenMP parallel algorithm by Cho (2025).
NOTES
r.lfp can automatically recognize the following three different formats of flow directions: degree, 45degree, and power2. The degree format starts just above 0° at East (excluding 0° itself) and goes counterclockwise up to 360°, which also corresponds to East. The 45degree format divides the degree format by 45°. The power2 format starts from 1 at East and doubles clockwise up to Northeast.
r.lfp also supports the taudem format, which is used by TauDEM's D8FlowDir. This format is not auto-detected because it shares the same encoding range of the 45degree format. Additionally, the module can accept any integer encodings with the custom format and encoding option, which uses eight numbers for E, SE, S, SW, W, NW, N, and NE. For example, to encode the 45degree format using this method, one can use format=custom encoding=8,7,6,5,4,3,2,1.
Unless the -f option is specified, r.lfp defaults to computing the longest flow paths within each subwatershed, not crossing through any outlet points. This default behavior will produce longest flow path lines that do not overlap among subwatersheds. However, they can still overlap within a subwatershed if they are of the same length and share common downstream paths within that subwatershed.
With the -f option, the module first computes the longest flow paths at the subwatershed level, then performs a hierarchical analysis to derive potentially longer watershed-level flow paths, and finally eliminates shorter paths from both the subwatershed and hierarchically merged watershed results.
When parallel processing is enabled with the nprocs option, r.lfp uses OpenMP's shared-memory model and the specified number of threads to parallelize the computation per thread initially (implicit tasking through looping) and later switch to explicit tasking for better load balancing as threads start becoming ideal after they finish their allocated implicit tasks. This loop-then-task approach significantly improves computational efficiency along with highly reduced memory usage. In its benchmark experiment, the MELFP algorithm used in this module achieved a 66% reduction in computation time using 79% lower peak memory with 33% higher CPU utilization, enabling faster and larger data processing (Cho, 2025).
EXAMPLES
These examples use the North Carolina sample dataset.
Extract all draining cells (all outlets for the elevation raster), and calculate all watersheds and longest flow paths:
# set computational region
g.region -ap rast=elevation
# calculate drainage directions using r.watershed
r.watershed -s elev=elevation drain=drain
# extract draining cells
r.mapcalc ex="dcells=if(\
(isnull(drain[-1,-1])&&abs(drain)==3)||\
(isnull(drain[-1,0])&&abs(drain)==2)||\
(isnull(drain[-1,1])&&abs(drain)==1)||\
(isnull(drain[0,-1])&&abs(drain)==4)||\
(isnull(drain[0,1])&&abs(drain)==8)||\
(isnull(drain[1,-1])&&abs(drain)==5)||\
(isnull(drain[1,0])&&abs(drain)==6)||\
(isnull(drain[1,1])&&abs(drain)==7),1,null())"
r.to.vect input=dcells type=point output=dcells
# delineate all watersheds using r.hydrobasin
r.hydrobasin dir=drain outlets=dcells output=wsheds nproc=$(nproc)
# calculate all longest flow paths
r.lfp dir=drain outlets=dcells lfp=lfp ocol=outlet_cat nproc=$(nproc)
# or using a custom format for r.watershed drainage (8-1 for E-NE CW)
r.lfp dir=drain format=custom encoding=8,7,6,5,4,3,2,1 outlets=dcells lfp=lfp2 ocol=outlet_cat nproc=$(nproc)
Perform the same analysis using the statewide DEM, elev_state_500m:
# set computational region
g.region -ap rast=elev_state_500m
# calculate drainage directions using r.watershed
r.watershed -s elev=elev_state_500m drain=nc_drain
# extract draining cells
r.mapcalc ex="nc_dcells=if(\
(isnull(nc_drain[-1,-1])&&abs(nc_drain)==3)||\
(isnull(nc_drain[-1,0])&&abs(nc_drain)==2)||\
(isnull(nc_drain[-1,1])&&abs(nc_drain)==1)||\
(isnull(nc_drain[0,-1])&&abs(nc_drain)==4)||\
(isnull(nc_drain[0,1])&&abs(nc_drain)==8)||\
(isnull(nc_drain[1,-1])&&abs(nc_drain)==5)||\
(isnull(nc_drain[1,0])&&abs(nc_drain)==6)||\
(isnull(nc_drain[1,1])&&abs(nc_drain)==7),1,null())"
r.to.vect input=nc_dcells type=point output=nc_dcells
# delineate all watersheds using r.hydrobasin
r.hydrobasin dir=nc_drain outlets=nc_dcells output=nc_wsheds nproc=$(nproc)
# calculate all longest flow paths
r.lfp dir=nc_drain outlets=nc_dcells lfp=nc_lfp ocol=outlet_cat nproc=$(nproc)
# or using a custom format for r.watershed drainage (8-1 for E-NE CW)
r.lfp dir=nc_drain format=custom encoding=8,7,6,5,4,3,2,1 outlets=nc_dcells lfp=nc_lfp2 ocol=outlet_cat nproc=$(nproc)
SEE ALSO
r.hydrobasin, r.flowaccumulation, r.accumulate, r.watershed
REFERENCES
Huidae Cho, September 2025. Loop Then Task: Hybridizing OpenMP Parallelism to Improve Load Balancing and Memory Efficiency in Continental-Scale Longest Flow Path Computation. Environmental Modelling & Software 193, 106630. doi:10.1016/j.envsoft.2025.106630
AUTHOR
Huidae Cho, New Mexico State University
SOURCE CODE
Available at: r.lfp source code
(history)
Latest change: Friday Aug 08 09:55:04 2025 in commit e1f7638