Skip to content

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.

image-alt

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.

image-alt

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)

image-alt

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)

image-alt

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