0
votes

I am trying to calculate the distance from a spatial point to a raster cell of a particular value/type. In my data each point represents a tree and I want to know how far away that point is from different categories of raster cells (grass, forest, impervious surface etc). I tried distanceFromPoints but that returns a distance raster and what I'm interested in is a data frame with distances to the nearest raster cell of each land cover type from each point.

#example raster
library(raster)
r <- raster(nrow=100, ncol=100)
r[] <- round(runif(ncell(r),1,4),0)
plot(r)

#example points
x <- c(-110, -50, 25, 150)
y <- c(50, -25, 70, 2)
df <- data.frame(cbind(x,y))
df$n <- c("pt1","pt2","pt3","pt4")

library(sp)
sp <- SpatialPoints(c, proj4string = CRS("+proj=longlat +datum=WGS84 +no_defs"))
plot(sp, add=TRUE)

The output I want is something like this:

    x   y   n   dist.cat1 dist.cat2 dist.cat3 dist.cat4
1 -110  50 pt1        12         3         5         9
2  -50 -25 pt2         1         2         1        27
3   25  70 pt3         4        14        29         5
4  150   2 pt4        23         2        15         2

Where dist.cat1 represents the distance from a point (n) to the nearest raster cell that has the category 1 value.

1

1 Answers

0
votes

It is not pretty, but you could do something like this.

library(terra)
# simulate raster
r <- raster(nrow=100, ncol=100)
r[] <- round(runif(ncell(r),1,4),0)
# simulate coordinates
x <- c(-110, -50, 25, 150)
y <- c(50, -25, 70, 2)

xy <- cbind(x, y)
out <- list()
for (i in 1:nrow(xy)) {
    d <- distanceFromPoints(r, xy[i,,drop=F])
    out[[i]] <- zonal(d, r, min)[,2]
}
a <- do.call(rbind, out)

b <- cbind(x, y, id=1:4, a)
colnames(b)[4:7] <- paste0("dcat", 1:4)
#        x   y id     dcat1    dcat2     dcat3    dcat4
#[1,] -110  50  1 145303.98 252442.9 331242.16 102200.3
#[2,]  -50 -25  2  57449.51 186127.4 136371.57 138753.8
#[3,]   25  70  3 280556.71 235822.1 110116.94 342537.4
#[4,]  150   2  4 279410.53 161549.5  99779.32 473517.4

These are distances (in m) from the points to the nearest cell center for a class. So there are no zeros unless a point is in the center of cell. You can fix that if you want.

You can also start at the cell centers like this

xy <- cbind(x, y)
out <- list()
for (i in 1:nrow(xy)) {
    d <- rasterize(xy[i,,drop=F], r)
    d <- distance(d)
    out[[i]] <- zonal(d, r, min)[,2]
}
a <- do.call(rbind, out)
a 
#         [,1]     [,2]     [,3]     [,4]
#[1,] 200226.1 413979.1 249315.6      0.0
#[2,]      0.0 199349.5 200816.0 199035.8
#[3,] 324904.0 365442.0 142051.4 400308.1
#[4,] 260746.8      0.0      0.0 398093.3