---
name: r.path
description: Traces paths from starting points following input directions.
keywords: [ raster, hydrology, cost surface ]
---

# r.path

Traces paths from starting points following input directions.

=== "Command line"

    **r.path**
    [**-ebcan**]
    **input**=*name*
    **format**=*string*
    [**values**=*name*]
    [**raster_path**=*name*]
    [**vector_path**=*name*]
    [**start_coordinates**=*east,north* [,*east,north*,...]]
    [**start_points**=*name* [,*name*,...]]
    [**--overwrite**]
    [**--verbose**]
    [**--quiet**]
    [**--qq**]
    [**--ui**]

    Example:

    ```sh
    r.path input=name format=auto raster_path=name
    ```

=== "Python (grass.tools)"

    *grass.tools.Tools.r_path*(**input**,
        **format**=*"auto"*,
        **values**=*None*,
        **raster_path**=*None*,
        **vector_path**=*None*,
        **start_coordinates**=*None*,
        **start_points**=*None*,
        **flags**=*None*,
        **overwrite**=*None*,
        **verbose**=*None*,
        **quiet**=*None*,
        **superquiet**=*None*)

    Example:

    ```python
    tools = Tools()
    tools.r_path(input="name", format="auto", raster_path="name")
    ```

    This grass.tools API is experimental in version 8.5 and expected to be stable in version 8.6.

=== "Python (grass.script)"

    *grass.script.run_command*("***r.path***",
        **input**,
        **format**=*"auto"*,
        **values**=*None*,
        **raster_path**=*None*,
        **vector_path**=*None*,
        **start_coordinates**=*None*,
        **start_points**=*None*,
        **flags**=*None*,
        **overwrite**=*None*,
        **verbose**=*None*,
        **quiet**=*None*,
        **superquiet**=*None*)

    Example:

    ```python
    gs.run_command("r.path", input="name", format="auto", raster_path="name")
    ```

## Parameters

=== "Command line"

    **input**=*name* **[required]**  
    &nbsp;&nbsp;&nbsp;&nbsp;Name of input direction  
    &nbsp;&nbsp;&nbsp;&nbsp;Direction in degrees CCW from east, or bitmask encoded  
    **format**=*string* **[required]**  
    &nbsp;&nbsp;&nbsp;&nbsp;Format of the input direction map  
    &nbsp;&nbsp;&nbsp;&nbsp;Allowed values: *auto, degree, 45degree, bitmask*  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *auto*  
    &nbsp;&nbsp;&nbsp;&nbsp;**auto**: auto-detect direction format  
    &nbsp;&nbsp;&nbsp;&nbsp;**degree**: degrees CCW from East  
    &nbsp;&nbsp;&nbsp;&nbsp;**45degree**: degrees CCW from East divided by 45 (e.g. r.watershed directions)  
    &nbsp;&nbsp;&nbsp;&nbsp;**bitmask**: bitmask encoded directions (e.g. r.cost -b)  
    **values**=*name*  
    &nbsp;&nbsp;&nbsp;&nbsp;Name of input raster values to be used for output  
    &nbsp;&nbsp;&nbsp;&nbsp;Name of input raster map  
    **raster_path**=*name*  
    &nbsp;&nbsp;&nbsp;&nbsp;Name for output raster path map  
    &nbsp;&nbsp;&nbsp;&nbsp;Name for output raster map  
    **vector_path**=*name*  
    &nbsp;&nbsp;&nbsp;&nbsp;Name for output vector path map  
    &nbsp;&nbsp;&nbsp;&nbsp;Name for output vector map  
    **start_coordinates**=*east,north* [,*east,north*,...]  
    &nbsp;&nbsp;&nbsp;&nbsp;Coordinates of starting point(s) (E,N)  
    **start_points**=*name* [,*name*,...]  
    &nbsp;&nbsp;&nbsp;&nbsp;Name of starting vector points map(s)  
    &nbsp;&nbsp;&nbsp;&nbsp;Or data source(s) for direct OGR access  
    **-e**  
    &nbsp;&nbsp;&nbsp;&nbsp;Start bitmask encoded directions from East (e.g., r.terraflow)  
    **-b**  
    &nbsp;&nbsp;&nbsp;&nbsp;Do not break lines (faster for single-direction bitmask encoding)  
    **-c**  
    &nbsp;&nbsp;&nbsp;&nbsp;Copy input cell values on output  
    **-a**  
    &nbsp;&nbsp;&nbsp;&nbsp;Accumulate input values along the path  
    **-n**  
    &nbsp;&nbsp;&nbsp;&nbsp;Count cell numbers along the path  
    **--overwrite**  
    &nbsp;&nbsp;&nbsp;&nbsp;Allow output files to overwrite existing files  
    **--help**  
    &nbsp;&nbsp;&nbsp;&nbsp;Print usage summary  
    **--verbose**  
    &nbsp;&nbsp;&nbsp;&nbsp;Verbose module output  
    **--quiet**  
    &nbsp;&nbsp;&nbsp;&nbsp;Quiet module output  
    **--qq**  
    &nbsp;&nbsp;&nbsp;&nbsp;Very quiet module output  
    **--ui**  
    &nbsp;&nbsp;&nbsp;&nbsp;Force launching GUI dialog

=== "Python (grass.tools)"

    **input** : str | np.ndarray, *required*  
    &nbsp;&nbsp;&nbsp;&nbsp;Name of input direction  
    &nbsp;&nbsp;&nbsp;&nbsp;Direction in degrees CCW from east, or bitmask encoded  
    &nbsp;&nbsp;&nbsp;&nbsp;Used as: input, raster, *name*  
    **format** : str, *required*  
    &nbsp;&nbsp;&nbsp;&nbsp;Format of the input direction map  
    &nbsp;&nbsp;&nbsp;&nbsp;Allowed values: *auto, degree, 45degree, bitmask*  
    &nbsp;&nbsp;&nbsp;&nbsp;**auto**: auto-detect direction format  
    &nbsp;&nbsp;&nbsp;&nbsp;**degree**: degrees CCW from East  
    &nbsp;&nbsp;&nbsp;&nbsp;**45degree**: degrees CCW from East divided by 45 (e.g. r.watershed directions)  
    &nbsp;&nbsp;&nbsp;&nbsp;**bitmask**: bitmask encoded directions (e.g. r.cost -b)  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *auto*  
    **values** : str | np.ndarray, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Name of input raster values to be used for output  
    &nbsp;&nbsp;&nbsp;&nbsp;Name of input raster map  
    &nbsp;&nbsp;&nbsp;&nbsp;Used as: input, raster, *name*  
    **raster_path** : str | type(np.ndarray) | type(np.array) | type(gs.array.array), *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Name for output raster path map  
    &nbsp;&nbsp;&nbsp;&nbsp;Name for output raster map  
    &nbsp;&nbsp;&nbsp;&nbsp;Used as: output, raster, *name*  
    **vector_path** : str, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Name for output vector path map  
    &nbsp;&nbsp;&nbsp;&nbsp;Name for output vector map  
    &nbsp;&nbsp;&nbsp;&nbsp;Used as: output, vector, *name*  
    **start_coordinates** : list[tuple[float, float]] | tuple[float, float] | list[float] | str, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Coordinates of starting point(s) (E,N)  
    &nbsp;&nbsp;&nbsp;&nbsp;Used as: input, coords, *east,north*  
    **start_points** : str | list[str], *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Name of starting vector points map(s)  
    &nbsp;&nbsp;&nbsp;&nbsp;Or data source(s) for direct OGR access  
    &nbsp;&nbsp;&nbsp;&nbsp;Used as: input, vector, *name*  
    **flags** : str, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Allowed values: *e*, *b*, *c*, *a*, *n*  
    &nbsp;&nbsp;&nbsp;&nbsp;**e**  
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Start bitmask encoded directions from East (e.g., r.terraflow)  
    &nbsp;&nbsp;&nbsp;&nbsp;**b**  
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Do not break lines (faster for single-direction bitmask encoding)  
    &nbsp;&nbsp;&nbsp;&nbsp;**c**  
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Copy input cell values on output  
    &nbsp;&nbsp;&nbsp;&nbsp;**a**  
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Accumulate input values along the path  
    &nbsp;&nbsp;&nbsp;&nbsp;**n**  
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Count cell numbers along the path  
    **overwrite** : bool, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Allow output files to overwrite existing files  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *None*  
    **verbose** : bool, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Verbose module output  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *None*  
    **quiet** : bool, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Quiet module output  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *None*  
    **superquiet** : bool, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Very quiet module output  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *None*  

    Returns:

    **result** : grass.tools.support.ToolResult | np.ndarray | tuple[np.ndarray] | None  
    If the tool produces text as standard output, a *ToolResult* object will be returned. Otherwise, `None` will be returned. If an array type (e.g., *np.ndarray*) is used for one of the raster outputs, the result will be an array and will have the shape corresponding to the computational region. If an array type is used for more than one raster output, the result will be a tuple of arrays.

    Raises:

    *grass.tools.ToolError*: When the tool ended with an error.

=== "Python (grass.script)"

    **input** : str, *required*  
    &nbsp;&nbsp;&nbsp;&nbsp;Name of input direction  
    &nbsp;&nbsp;&nbsp;&nbsp;Direction in degrees CCW from east, or bitmask encoded  
    &nbsp;&nbsp;&nbsp;&nbsp;Used as: input, raster, *name*  
    **format** : str, *required*  
    &nbsp;&nbsp;&nbsp;&nbsp;Format of the input direction map  
    &nbsp;&nbsp;&nbsp;&nbsp;Allowed values: *auto, degree, 45degree, bitmask*  
    &nbsp;&nbsp;&nbsp;&nbsp;**auto**: auto-detect direction format  
    &nbsp;&nbsp;&nbsp;&nbsp;**degree**: degrees CCW from East  
    &nbsp;&nbsp;&nbsp;&nbsp;**45degree**: degrees CCW from East divided by 45 (e.g. r.watershed directions)  
    &nbsp;&nbsp;&nbsp;&nbsp;**bitmask**: bitmask encoded directions (e.g. r.cost -b)  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *auto*  
    **values** : str, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Name of input raster values to be used for output  
    &nbsp;&nbsp;&nbsp;&nbsp;Name of input raster map  
    &nbsp;&nbsp;&nbsp;&nbsp;Used as: input, raster, *name*  
    **raster_path** : str, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Name for output raster path map  
    &nbsp;&nbsp;&nbsp;&nbsp;Name for output raster map  
    &nbsp;&nbsp;&nbsp;&nbsp;Used as: output, raster, *name*  
    **vector_path** : str, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Name for output vector path map  
    &nbsp;&nbsp;&nbsp;&nbsp;Name for output vector map  
    &nbsp;&nbsp;&nbsp;&nbsp;Used as: output, vector, *name*  
    **start_coordinates** : list[tuple[float, float]] | tuple[float, float] | list[float] | str, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Coordinates of starting point(s) (E,N)  
    &nbsp;&nbsp;&nbsp;&nbsp;Used as: input, coords, *east,north*  
    **start_points** : str | list[str], *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Name of starting vector points map(s)  
    &nbsp;&nbsp;&nbsp;&nbsp;Or data source(s) for direct OGR access  
    &nbsp;&nbsp;&nbsp;&nbsp;Used as: input, vector, *name*  
    **flags** : str, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Allowed values: *e*, *b*, *c*, *a*, *n*  
    &nbsp;&nbsp;&nbsp;&nbsp;**e**  
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Start bitmask encoded directions from East (e.g., r.terraflow)  
    &nbsp;&nbsp;&nbsp;&nbsp;**b**  
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Do not break lines (faster for single-direction bitmask encoding)  
    &nbsp;&nbsp;&nbsp;&nbsp;**c**  
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Copy input cell values on output  
    &nbsp;&nbsp;&nbsp;&nbsp;**a**  
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Accumulate input values along the path  
    &nbsp;&nbsp;&nbsp;&nbsp;**n**  
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Count cell numbers along the path  
    **overwrite** : bool, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Allow output files to overwrite existing files  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *None*  
    **verbose** : bool, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Verbose module output  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *None*  
    **quiet** : bool, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Quiet module output  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *None*  
    **superquiet** : bool, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Very quiet module output  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *None*

## DESCRIPTION

*r.path* traces a path from starting points following input directions.
Such a movement direction map can be generated with
*[r.walk](r.walk.md)*, *[r.cost](r.cost.md)*,
*[r.slope.aspect](r.slope.aspect.md)*, *[r.watershed](r.watershed.md)*,
or *[r.fill.dir](r.fill.dir.md)*, provided that the direction is in
degrees, measured counterclockwise from east.

Alternatively, bitmask-encoded directions can be provided where each bit
position corresponds to a specific neighbour. A path will continue to
all neighbours with their bit set. This means a path can split and
merge. Such bitmasked directions can be created with the **-b** flag of
*[r.cost](r.cost.md)* and *[r.walk](r.walk.md)*.

```sh
Direction encoding for neighbors of x

  135  90  45          7 8 1
  180  x  360          6 x 2
  225 270 315          5 4 3

  degrees           bit positions
  CCW from East
```

A path stops when the direction is zero or negative, indicating a stop
point or outlet.

The **output** raster map will show one or more least-cost paths between
each user-provided location(s) and the target points (direction ≤ 0). By
default, the **output** will be an integer CELL map with the id of the
start points along the least cost path, and null cells elsewhere.

With the **-c** (*copy*) flag, the values raster map cell values are
copied verbatim along the path. With the **-a** (*accumulate*) flag, the
accumulated cell value from the starting point up to the current cell is
written on output. With either the **-c** or the **-a** flags, the
**raster_path** map is created with the same cell type as the **values**
raster map (integer, float or double). With the **-n** (*number*) flag,
the cells are numbered consecutively from the starting point to the
final point. The **-c**, **-a**, and **-n** flags are mutually
incompatible.

The **start_coordinates** parameter consists of map E and N grid
coordinates of a starting point. Each x,y pair is the easting and
northing (respectively) of a starting point from which a path will be
traced following **input** directions. The **start_points** parameter
can take multiple vector maps containing additional starting points.

## NOTES

The directions are recorded as degrees CCW from East, the Knight's move
of r.cost and r.walk is considered:

```sh
       112.5     67.5
157.5  135   90  45   22.5
       180   x   0
202.5  225  270  315  337.5
       247.5     292.5
```

i.e. a cell with the value 135 means the next cell is to the North-West,
and a cell with the value 157.5 means that the next cell is to the
West-North-West.

## EXAMPLES

### Hydrological path

We are using the full North Carolina sample dataset. First we create the
two points from a text file using *[v.in.ascii](v.in.ascii.md)* module
(here the text file is CSV and we are using unix here-file syntax with
EOF, in GUI just enter the values directly for the parameter input):

```sh
v.in.ascii input=- output=start format=point separator=comma <<EOF
638667.15686275,220610.29411765
638610.78431373,220223.03921569
EOF
```

We need to supply a direction raster map to the *r.path* module. To get
these directions, we use the *[r.watershed](r.watershed.md)* module:

```sh
r.watershed elevation=elev_lid792_1m accumulation=accum drainage=drain_dir
```

The directions are categorical and we convert them to degrees using
raster algebra:

```sh
r.mapcalc "drain_deg = if(drain_dir != 0, 45. * abs(drain_dir), null())"
```

Now we are ready to extract the drainage paths starting at the two
points.

```sh
r.path input=drain_deg raster_path=drain_path vector_path=drain_path start_points=start
```

Before we visualize the result, we set a color table for the elevation
we are using and create a shaded relief map:

```sh
r.colors map=elev_lid792_1m color=elevation
r.relief input=elev_lid792_1m output=relief
```

We visualize the input and output data:

```sh
d.shade shade=relief color=elev_lid792_1m
d.vect map=drain_path color=0:0:61 width=4 legend_label="drainage paths"
d.vect map=start color=none fill_color=224:0:0 icon=basic/circle size=15 legend_label=origins
d.legend.vect -b
```

![drainage using r.watershed](r_path_with_r_watershed_direction.png)  
*Figure: Drainage paths from two points where directions from
r.watershed were used*

### Least-cost path

We compute bitmask encoded movement directions using *r.walk:*

```sh
g.region swwake_30m -p

# create friction map based on land cover
r.recode input=landclass96 output=friction rules=- << EOF
1:3:0.1:0.1
4:5:10.:10.
6:6:1000.0:1000.0
7:7:0.3:0.3
EOF

# without Knight's move
r.walk -b elevation=elev_ned_30m friction=friction output=walkcost \
    outdir=walkdir start_coordinates=635576,216485

r.path input=walkdir start_coordinates=640206,222795 \
    raster_path=walkpath vector_path=walkpath

# with Knight's move
r.walk -b -k elevation=elev_ned_30m friction=friction output=walkcost_k \
    outdir=walkdir_k start_coordinates=635576,216485

r.path input=walkdir_k start_coordinates=640206,222795 \
    raster_path=walkpath_k vector_path=walkpath_k

# without Knight's move and without bitmask encoding (single direction)
r.walk elevation=elev_ned_30m friction=friction output=walkcost_s \
    outdir=walkdir_s start_coordinates=635576,216485

r.path input=walkdir_s start_coordinates=640206,222795 \
    raster_path=walkpath_s vector_path=walkpath_s
```

The extracted least-cost path splits and merges on the way from the
start point to the stop point (start point for r.walk). Note the gaps in
the raster path when using the Knight's move.

```sh

```

![least cost path using bitmask](r_path_with_bitmask.png)  
*Figure: Comparison of shortest paths using single directions and
multiple bitmask encoded directions without and with Knight's move*

## SEE ALSO

*[g.region](g.region.md), [r.basins.fill](r.basins.fill.md),
[r.cost](r.cost.md), [r.fill.dir](r.fill.dir.md),
[r.mapcalc](r.mapcalc.md), [r.recode](r.recode.md),
[r.terraflow](r.terraflow.md), [r.walk](r.walk.md),
[r.watershed](r.watershed.md)*

## AUTHOR

Markus Metz  
Multiple path directions sponsored by
[mundialis](https://www.mundialis.de)

## SOURCE CODE

Available at: [r.path source code](https://github.com/OSGeo/grass/tree/main/raster/r.path)
([history](https://github.com/OSGeo/grass/commits/main/raster/r.path))  
Latest change: Friday Jan 02 21:25:59 2026 in commit [83362df](https://github.com/OSGeo/grass/commit/83362df5af36c1e7d95fad93dff0a57b4dfde476)
