0

accCost() and costDistance() functions from R gdistance produce different values when going from source coordinate A to destination coordinate B. Shouldn't the cost accumulation value at B be equivalent to the costDistance value from A to B given an equivalent anisotropic transition matrix and that both functions use the Dijkstra algorithm?

If not, then what is the fundamental difference between the calculations? If so, what accounts for the different values derived from the code presented below? In the example, A to B costDistance=0.13 hours and accCost=0.11 hours at point B. My other tests suggest that accCost is consistently less than costDistance and consierably so over long distances. The code is based on the example provided in accCost documentation.

require(gdistance)
r <- raster(system.file("external/maungawhau.grd", package="gdistance"))
altDiff <- function(x){x[2] - x[1]}
hd <- transition(r, altDiff, 8, symm=FALSE)
slope <- geoCorrection(hd)
adj <- adjacent(r, cells=1:ncell(r), pairs=TRUE, directions=8)
speed <- slope
speed[adj] <- 6 * 1000 * exp(-3.5 * abs(slope[adj] + 0.05))#1000 to convert to a common spatial unit of meters
Conductance <- geoCorrection(speed)
A <- matrix(c(2667670, 6479000),ncol=2)
B <- matrix(c(2667800, 6479400),ncol=2)
ca <- accCost(Conductance,fromCoords=A)
extract(ca,B)
costDistance(Conductance,fromCoords=A,toCoords=B)
RandyHaas
  • 3
  • 3

2 Answers2

1

There should be no difference. The current version of accCost has a small bug that arises from a change in the igraph package.

For the moment, please see if this function solves the problem.

setMethod("accCost", signature(x = "TransitionLayer", fromCoords = "Coords"),
 def = function(x, fromCoords)
  {
    fromCoords <- .coordsToMatrix(fromCoords) 
    fromCells <- cellFromXY(x, fromCoords)
    if(!all(!is.na(fromCells))){
        warning("some coordinates not found and omitted")
        fromCells <- fromCells[!is.na(fromCells)]
    }
    tr <- transitionMatrix(x)
    tr <- rBind(tr,rep(0,nrow(tr)))
    tr <- cBind(tr,rep(0,nrow(tr)))

    startNode <- nrow(tr) #extra node to serve as origin
    adjP <- cbind(rep(startNode, times=length(fromCells)), fromCells)

    tr[adjP] <- Inf

    adjacencyGraph <- graph.adjacency(tr, mode="directed", weighted=TRUE)
    E(adjacencyGraph)$weight <- 1/E(adjacencyGraph)$weight      

    shortestPaths <- shortest.paths(adjacencyGraph, v=startNode, mode="out")[-startNode]

    result <- as(x, "RasterLayer")
    result <- setValues(result, shortestPaths)  
    return(result)
  }
)
JacobVanEtten
  • 203
  • 1
  • 7
  • Thank you. I tried this and get the following error: Error in accCost(Conductance, fromCoords = A) : could not find function ".coordsToMatrix" – RandyHaas Apr 13 '16 at 21:19
  • Sorry, this will work only if you get that function from here: https://r-forge.r-project.org/scm/viewvc.php/pkg/gdistance/R/internal-functions.R?view=markup&revision=222&root=gdistance This is a temporary solution only and should be resolved soon. – JacobVanEtten Apr 14 '16 at 02:53
0

This issue has been resolved in gdistance 1.2-1.

JacobVanEtten
  • 203
  • 1
  • 7