r.cost(1grass)

✨ r.cost β€” the GRASS User's Manual glow-up ✨

okay bestie, buckle up, this is r.cost from the GRASS User's Manual (yes, that's the r.cost(1grass) page you were looking for πŸ’…) β€” the raster module that figures out the cumulative cost of moving around a map. she's long, she's iconic, and she has opinions about heaps.

🏷️ NAME

r.cost β€” creates a raster map showing the cumulative cost of moving between different geographic locations on an input raster map whose cell category values represent cost.

πŸ’– KEYWORDS

raster, cost surface, cumulative costs, cost allocation


🌸 SYNOPSIS

r.cost
r.cost --help
r.cost [-knrib] input=name output=name  [solver=name]   [nearest=name]
[outdir=name]   [start_points=name]   [stop_points=name]
[start_raster=name]   [start_coordinates=east,north[,east,north,...]]
[stop_coordinates=east,north[,east,north,...]]   [max_cost=value]
[null_cost=value]   [memory=memory in MB]   [--overwrite]  [--help]
[--verbose]  [--quiet]  [--ui]

πŸŽ€ Flags:

  • -k β€” use the 'Knight's move'; slower, but more accurate 🐴
  • -n β€” keep null values in output raster map
  • -r β€” start with values in raster map
  • -i β€” print info about disk space and memory requirements and exit
  • -b β€” create bitmask encoded directions
  • --overwrite β€” allow output files to overwrite existing files (she's brave like that)
  • --help β€” print usage summary
  • --verbose β€” verbose module output
  • --quiet β€” quiet module output 🀫
  • --ui β€” force launching GUI dialog

πŸ¦‹ Parameters:

  • input=name [required] β€” name of input raster map containing grid cell cost information
  • output=name [required] β€” name for output raster map
  • solver=name β€” name of input raster map solving equal costs. Helper variable to pick a direction if two directions have equal cumulative costs (smaller is better) ✨
  • nearest=name β€” name for output raster map with nearest start point
  • outdir=name β€” name for output raster map to contain movement directions
  • start_points=name β€” name of starting vector points map. Or data source for direct OGR access
  • stop_points=name β€” name of stopping vector points map. Or data source for direct OGR access
  • start_raster=name β€” name of starting raster points map
  • start_coordinates=east,north[,east,north,...] β€” coordinates of starting point(s) (E,N)
  • stop_coordinates=east,north[,east,north,...] β€” coordinates of stopping point(s) (E,N)
  • max_cost=value β€” maximum cumulative cost. Default: 0
  • null_cost=value β€” cost assigned to null cells. By default, null cells are excluded
  • memory=memory in MB β€” maximum memory to be used (in MB). Cache size for raster rows. Default: 300

πŸ’« DESCRIPTION

So what does r.cost actually do, bestie? She determines the cumulative cost of moving to each cell on a cost surface (that's your input raster map, main character) from other user-specified cell(s) whose locations you specify by their geographic coordinate(s). Every cell in the original cost surface map holds a category value representing the cost of traversing that cell.

Then r.cost serves you not one but TWO outputs, because she's generous:

  1. an output raster map where each cell contains the lowest total cost of traversing the space between each cell and the user-specified points (and yes, diagonal costs get multiplied by a factor that depends on the dimensions of the cell πŸ“), and
  2. a second raster map layer showing the movement direction to the next cell on the path back to the start point (peep the Movement Direction section).

She uses the current geographic region settings, and the output map will be in the same data format as the input map β€” integer or floating point. no cap.


✨ OPTIONS ✨

The input name is the name of a raster map whose category values represent the surface cost. The output name is the name of the resultant raster map of cumulative cost. And the outdir name is the name of the resultant raster map of movement directions (again: see Movement Direction).

r.cost runs with three different methods of identifying the starting point(s), and she's flexible about it:

  • one or more points (geographic coordinate pairs) given as start_coordinates on the command line,
  • a vector points file,
  • or a raster map.

All non-NULL cells are considered to be starting points. πŸ’…

Each x,y start_coordinates pair gives the geographic location of a point from which the transportation cost should be figured. You can enter as many points as your heart desires. These starting points can also be read from a vector points file through the start_points option, or from a raster map through the start_raster option.

r.cost will stop cumulating costs when either max_cost is reached, or one of the stop points given with stop_coordinates is reached. Alternatively, the stop points can be read from a vector points file with the stop_points option. During execution, once the cumulative cost to all stopping points has been determined, processing stops. And heads up: both sites read from a vector points file and those given on the command line will be processed. 🫢

The null cells in the input map can be assigned a (positive floating point) cost with the null_cost option. When input map null cells are given a cost with null_cost, the corresponding cells in the output map are no longer null cells. But if you use the -n flag, the null cells of the input map are retained as null cells in the output map.

As r.cost can run for a very long time, it can be useful to use the --v verbose flag to track progress. (yes, she's a long-haul girlie, pack snacks πŸ“)

The Knight's move (-k flag) may be used to improve the accuracy of the output. In the diagram below, the center location (O) represents a grid cell from which cumulative distances are calculated. Those neighbors marked with an X are always considered for cumulative cost updates. With the -k option, the neighbors marked with a K are also considered.

 . . . . . . . . . . . . . . .
 .   .   . K .   . K .   .   .
 . . . . . . . . . . . . . . .
 .   . K . X . X . X . K .   .
 . . . . . . . . . . . . . . .
 .   .   . X . O . X .   .   .
 . . . . . . . . . . . . . . .
 .   . K . X . X . X . K .   .
 . . . . . . . . . . . . . . .
 .   .   . K .   . K .   .   .
 . . . . . . . . . . . . . . .

Knight's move example:

Flat cost surface without (left pane) and with the knight's move (right pane). The default is to grow the cost outwards in 8 directions. Using the knight's move grows it outwards in 16 directions. 🐴✨

If the nearest output parameter is specified, the module will calculate for each cell its nearest starting point based on the minimized accumulative cost while moving over the cost map.

The solver option helps to select a particular direction in case of multiple directions with equal costs. Sometimes fields with equal cumulative costs exist and multiple paths with equal costs would lead from a start point to a stop point. By default, a path along the edge of such a field would be produced, or multiple paths of equal costs with the -b flag. An additional variable can be supplied with the solver option to help the algorithm pick a particular direction.

Example for solving multiple directions:

A field of equal cumulative costs with multiple paths (black). By default a path along the edge will be selected (red). Path selection can be controlled with the solver option (blue).

Multiple directions can be solved as in the above example with the following steps:

  1. Create multiple directions with r.cost/r.walk using the -b flag
  2. Extract paths using r.path format=bitmask
  3. Calculate the distance from NULL cells to paths using r.grow.distance -n input=<paths from r.path>
  4. Invert the sign of the distances with r.mapcalc because for the solver smaller is better, and here we want to get the center of an area with multiple directions
  5. Use these negative distances as solver for a second pass of r.cost
  6. Extract paths again with r.path to get a geometrically optimized solution

πŸ•³οΈ NULL CELLS

By default, null cells in the input raster map are excluded from the algorithm, and thus retained in the output map.

If one wants r.cost to transparently cross any region of null cells, the null_cost=0.0 option should be used. Then null cells just propagate the adjacent costs. These cells can be retained as null cells in the output map by using the -n flag. 🫧


πŸ“ NOTES

Paths from any point to the nearest starting point of r.cost can be extracted with r.path by using the direction output map of r.cost.

🧠 Algorithm notes

The fundamental approach to calculating minimum travel cost is as follows, bestie, stay with me:

The user generates a raster map indicating the cost of traversing each cell in the north-south and east-west directions. This map, along with a set of starting points, are submitted to r.cost. The starting points are put into a heap of cells from which costs to the adjacent cells are to be calculated. The cell on the heap with the lowest cumulative cost is selected for computing costs to the neighboring cells. Costs are computed and those cells are put on the heap and the originating cell is finalized. This process of selecting the lowest cumulative cost cell, computing costs to the neighbors, putting the neighbors on the heap and removing the originating cell from the heap continues until the heap is empty. πŸ’€ (the heap. it's empty. dramatic.)

The most time consuming aspect of this algorithm is the management of the heap of cells for which cumulative costs have been at least initially computed. r.cost uses a minimum heap for efficiently tracking the next cell with the lowest cumulative costs. iconic efficiency, honestly.

r.cost, like most all GRASS raster programs, is also made to be run on maps larger than can fit in available computer memory. As the algorithm works through the dynamic heap of cells it can move almost randomly around the entire area. r.cost divides the entire area into a number of pieces and swaps these pieces in and out of memory (to and from disk) as needed. This provides a virtual memory approach optimally designed for 2-D raster maps. The amount of memory to be used by r.cost can be controlled with the memory option, default is 300 MB. For systems with less memory this value will have to be set to a lower value. 🧚

πŸ’– EXAMPLES πŸ’–

okay so picture this, bestie. here's the whole vibe in action:

Input:
  COST SURFACE
. . . . . . . . . . . . . . .
. 2 . 2 . 1 . 1 . 5 . 5 . 5 .
. . . . . . . . . . . . . . .
. 2 . 2 . 8 . 8 . 5 . 2 . 1 .
. . . . . . . . . . . . . . .
. 7 . 1 . 1 . 8 . 2 . 2 . 2 .
. . . . . . . . . . . . . . .
. 8 . 7 . 8 . 8 . 8 . 8 . 5 .
. . . . . . . . . . . _____ . .
. 8 . 8 . 1 . 1 . 5 | 3 | 9 .
. . . . . . . . . . |___| . .
. 8 . 1 . 1 . 2 . 5 . 3 . 9 .
. . . . . . . . . . . . . . .

and now the glow-up, side by side so you can see both parallel universes 🌈

   Output (using -k):                Output (not using -k):
      CUMULATIVE COST SURFACE           CUMULATIVE COST SURFACE
    . . . . . . . . . . . . . . .     . . . . * * * * * . . . . . .
    . 21. 21. 20. 19. 17. 15. 14.     . 22. 21* 21* 20* 17. 15. 14.
    . . . . . . . . . . . . . . .     . . . . * * * * * . . . . . .
    . 20. 19. 22. 19. 15. 12. 11.     . 20. 19. 22* 20* 15. 12. 11.
    . . . . . . . . . . . . . . .     . . . . . . * * * * * . . . .
    . 22. 18. 17. 17. 12. 11.  9.     . 22. 18. 17* 18* 13* 11.  9.
    . . . . . . . . . . . . . . .     . . . . . . * * * * * . . . .
    . 21. 14. 13. 12.  8.  6.  6.     . 21. 14. 13. 12.  8.  6.  6.
    . . . . . . . . . .  _____. .     . . . . . . . . . . . . . . .
    . 16. 13.  8.  7.  4 | 0 | 6.     . 16. 13.  8. 7 .  4.  0.  6.
    . . . . . . . . . .  |___|. .     . . . . . . . . . . . . . . .
    . 14.  9.  8.  9.  6.  3.  8.     . 14.  9.  8. 9 .  6.  3.  8.
    . . . . . . . . . . . . . . .     . . . . . . . . . . . . . . .

so the user-provided starting location in that example is the boxed 3 in the input map up there (yes, the little boxed one, she's the main character πŸŽ€). the costs in the output map are the total cost of moving from each box ("cell") to one or more (here, only one) starting location(s). and the cells surrounded by asterisks? those are literally the ones that differ between operations using and not using the Knight's move (-k) option. like, those are the receipts, no cap. πŸ’€


✨ Output analysis ✨

you can view the output map however you want, but lowkey the classic move is to look at it as an elevation model where the starting location(s) is/are the lowest point(s). outputs from r.cost can be fed as inputs to r.path, so you can trace the least-cost path that this model gives you between any given cell and the r.cost starting location(s). the two programs, when they're used together, generate least-cost paths or corridors between any two map locations (cells). it's giving power couple. πŸ’…


🌸 Shortest distance surfaces 🌸

the r.cost module allows for computing the shortest distance of each pixel from raster lines, like determining the shortest distances of households to the nearby road. for this, cost surfaces with cost value 1 are used. the calculation is done with r.cost as follows (example for Spearfish region):

g.region raster=roads -p
r.mapcalc "area.one = 1"
r.cost -k input=area.one output=distance start_raster=roads
d.rast distance
d.rast.num distance
#transform to metric distance from cell distance using the raster resolution:
r.mapcalc "dist_meters = distance * (ewres()+nsres())/2."
d.rast dist_meters

🧭 Movement Direction 🧭

okay so the movement direction surface is created to record the sequence of movements that created the cost accumulation surface. this movement direction surface can be used by r.path to recover a path from an end point back to the start point. the direction of each cell points towards the next cell. the directions are recorded as degrees CCW from East:

       112.5      67.5         i.e. a cell with the value 135
157.5  135   90   45   22.5    means the next cell is to the north-west
       180   x   360
202.5  225  270  315  337.5
       247.5     292.5

like, 135 is north-west coded, x is you, and the whole compass is just vibing in degrees. ⭐


πŸ’« Cost allocation πŸ’«

example: calculation of the cost allocation map "costalloc" and the cumulative cost map "costsurf" for given starting points (map "sources") and given cost raster map "costs":

r.cost input=costs start_raster=sources output=costsurf nearest=costalloc

πŸ¦‹ Find the minimum cost path πŸ¦‹

once r.cost computes the cumulative cost map and an associated movement direction map, r.path can be used to find the minimum cost path. that's it, that's the pipeline, and it ate. πŸ”₯


πŸ‘€ SEE ALSO πŸ‘€

  • r.walk, r.path, r.in.ascii, r.mapcalc, r.out.ascii

πŸ’œ AUTHORS πŸ’œ

  • Antony Awaida, Intelligent Engineering Systems Laboratory, M.I.T.
  • James Westervelt, U.S.Army Construction Engineering Research Laboratory
  • Updated for Grass 5 by Pierre de Mouveaux (pmx@audiovu.com)
  • Markus Metz
  • Multiple path directions sponsored by mundialis

🫢 SOURCE CODE 🫢

available at: r.cost source code (history)

latest change: Monday Feb 09 18:47:00 2026 in commit: 8cec756bc3c21c1086ba7c09dfda94b6a0e82f04

main index | Raster index | Topics index | Keywords index | Graphical index | Full index

Β© 2003-2026 GRASS Development Team, GRASS 8.5.0 Reference Manual


and that's the whole page, bestie β€” this little legend lives in GRASS 8.5.0, Β© 2003–2026 GRASS Development Team, last touched Monday Feb 09 18:47:00 2026 in commit 8cec756bc3c21c1086ba7c09dfda94b6a0e82f04. go compute some cumulative cost surfaces, you absolute icon. πŸ’–βœ¨πŸ‘‘

πŸ“¦ where this page comes from