Get the shortest path for a given trip that requires travel through a set of nodes. Use is like getCosts, but with nodes and order parameters and no from or to.

getPaths(
  region,
  nodes,
  id = "ID",
  order = NULL,
  x = "x",
  y = "y",
  costs = "all",
  polygons = "centroid",
  dir = tempdir(),
  ...
)

Arguments

region

A SpatVector, Spatial* or Raster* representing the area of maximum movement

nodes

One of data.frame, data.table, SpatVector, SpatialPointsDataFrame, or SpatialPolygonsDataFrame representing the node locations. If it is a polygon, the location will be controlled by the polygons parameter.

id

A character string representing the column containing each node location's unique ID.

order

A character vector containing the desired path in order of visited nodes by ID. Required if For example, to visit "A" then "B" then "C" then "A" the vector would be c("A","B","C","A"). If this is not provided, the function assumes that nodes is already sorted in the desired order.

x

A character vector representing the column containing the 'x' coordinates. Required if data is not Spatial*.

y

A character vector representing the column containing the 'y' coordinates. Required if data is not Spatial*.

costs

A character vector containing any combination of the strings of differential values present in the environment (see calculateCosts function; default is costs = c("dt","dW_l","dE_l") anticipating the use of calculateCosts(costFUN = energyCosts).

polygons

One of c('polygon','centroid','center'). Ignored unless nodes are polygons. If polygons = 'centroid' (the default), the destinations are calculated to the centroid of the polygon whether or not it lies within the polygon itself. If polygons = 'center', distances are calculated to the point within the polygon closest to the centroid. If polygons = 'polygons', distances are calculated to *any* point within the polygon---in essence, the polygon acts as a giant node permitting costless movement within its bounds. This is generally not consistent with real-world scenarios and for that reason is not the default.

dir

A filepath to the directory being used as the workspace. Default is tempdir() but unless the analyses will only be performed a few times it is highly recommended to define a permanent workspace.

...

Additional parameters to pass to importWorld.

Value

SpatialVector lines representing least-cost paths. For each cost, each entry within the SpatialLinesDataFrame object represents a single leg of the journey, sorted in the original path order. If length(costs) == 1, only a SpatVector is returned. If length(costs) > 1

a list of SpatVectors with one slot for each cost is returned.

Examples

# Generate a DEM
n <- 5
dem <- expand.grid(list(x = 1:(n * 100),
                        y = 1:(n * 100))) / 100
dem <- as.data.table(dem)
dem[, z := 250 * exp(-(x - n/2)^2) + 
      250 * exp(-(y - n/2)^2)]
#>            x    y         z
#>      1: 0.01 0.01 1.0146139
#>      2: 0.02 0.01 1.0404641
#>      3: 0.03 0.01 1.0675194
#>      4: 0.04 0.01 1.0958300
#>      5: 0.05 0.01 1.1254477
#>     ---                    
#> 249996: 4.96 5.00 1.0711366
#> 249997: 4.97 5.00 1.0428260
#> 249998: 4.98 5.00 1.0157707
#> 249999: 4.99 5.00 0.9899205
#> 250000: 5.00 5.00 0.9652271
dem <- rast(dem)
ext(dem) <- c(10000, 20000, 30000, 40000)
crs(dem) <- "+proj=lcc +lat_1=48 +lat_2=33 +lon_0=-100 +datum=WGS84"

# Export it so it doesn't just exist on the memory
dir <- tempdir()
writeRaster(dem, paste0(dir,"/DEM.tif"),overwrite=TRUE)


# Import raster, get the grid
dem <- rast(paste0(dir,"/DEM.tif"))
grid <- makeGrid(dem = dem, nx = n, ny = n, sources = TRUE)
region <- grid[8, ]

# Select all tiles that exist between x = (12000,16000) and y = (32000,36000)
tiles <- ext(c(12000,16000,32000,36000))
tiles <- as.polygons(tiles)
crs(tiles) <- crs(grid)
tiles <- whichTiles(region = tiles, polys = grid)

# Make a world but limit it to the DEM grid size
calculateCosts(tiles = tiles, dir = dir,
m = 70, v_max = 1.5, BMR = 76, k = 3.5, s = 0.05, l_s = 1,
L = 0.8)

# Generate five random points that fall within the region
points <- data.table(ID = 1:5,
                     x = runif(5, ext(region)[1], ext(region)[2]),
                     y = runif(5, ext(region)[3], ext(region)[4]))
                     
                     
# Calculate the path from 1 -> 2 -> 5 -> 1 -> 4 
pathOrder <- c(1,2,5,1,4)

# Make a world but limit it to the DEM grid size
defineWorld(source = grid, cut_slope = 0.5, 
            res = res(dem), dir = dir, overwrite=TRUE)
            
paths <- getPaths(region = region, nodes = points, order = pathOrder, 
                  costs = 'all', costFUN = energyCosts,
                       m = 70, v_max = 1.5, BMR = 76, k = 3.5, s = 0.05, l_s = 1,
                       L = 0.8)
#> [1] "Cropping Tile SECTOR_01 (1 of 4)"
#> [1] "Cropping Tile SECTOR_02 (2 of 4)"
#> [1] "Cropping Tile SECTOR_06 (3 of 4)"
#> [1] "Cropping Tile SECTOR_07 (4 of 4)"
#> [1] "Cropping Tile SECTOR_03 (1 of 2)"
#> [1] "Cropping Tile SECTOR_08 (2 of 2)"
#> [1] "Cropping Tile SECTOR_11 (1 of 2)"
#> [1] "Cropping Tile SECTOR_12 (2 of 2)"
#> [1] "Cropping Tile SECTOR_13 (1 of 1)"
#> [1] "Cropping Tile SECTOR_16 (1 of 2)"
#> [1] "Cropping Tile SECTOR_17 (2 of 2)"
#> [1] "Cropping Tile SECTOR_18 (1 of 1)"
#> [1] "Cropping Tile SECTOR_09 (1 of 3)"
#> [1] "Cropping Tile SECTOR_14 (2 of 3)"
#> [1] "Cropping Tile SECTOR_19 (3 of 3)"
#> [1] "Cropping Tile SECTOR_21 (1 of 2)"
#> [1] "Cropping Tile SECTOR_22 (2 of 2)"
#> [1] "Cropping Tile SECTOR_23 (1 of 1)"
#> [1] "Cropping Tile SECTOR_24 (1 of 1)"
#> [1] "Cropping Tile SECTOR_04 (1 of 1)"
#> [1] "Cropping Tile SECTOR_05 (1 of 2)"
#> [1] "Cropping Tile SECTOR_10 (2 of 2)"
#> [1] "Cropping Tile SECTOR_15 (1 of 1)"
#> [1] "Cropping Tile SECTOR_20 (1 of 1)"
#> [1] "Cropping Tile SECTOR_25 (1 of 1)"
#> Imported  9  Sectors
#> Warning: C:\Users\andre\AppData\Local\Temp\RtmpU5cHvW\World\costFUN.gz already defined. Ignoring input parameters.
#> Imported  9  Sectors
#> Warning: C:\Users\andre\AppData\Local\Temp\RtmpU5cHvW\World\costFUN.gz already defined. Ignoring input parameters.
#> Imported  9  Sectors
#> Warning: C:\Users\andre\AppData\Local\Temp\RtmpU5cHvW\World\costFUN.gz already defined. Ignoring input parameters.
#> Imported  9  Sectors
                              
## Plot against corridors (not run)                         
#getCosts(region = region, from = points, proj = crs(dem), res = res(dem),
#                        destination = 'all', costs = 'all',
#                        output = 'file', dir = dir)                       
#corridors <- makeCorridor(rasters = dir, order = pathOrder)
#plot(corridors$time)
#plot(paths$time,add=TRUE)