I have 25-km raster grid and a point. If I plot the point on the raster, it falls ~on the borderof two adjacent raster cells. I don't how to generate a sample data for this specific case but here's a visualisation of what I am taking about.
Is there any way I can detect for a group of points how many points are cases like this which could like very close to the border of two adjacent raster cells?
You can do that with the function on_border
that I show below.
Its arguments are SpatRaster r
, coordinates x
and y
, and a tolerance
for comparing real numbers.
on_border <- function(r, x, y, tolerance = sqrt(.Machine$double.eps)) {
v <- h <- (x >= xmin(r)) & (x <= xmax(r)) & (y >= ymin(r)) & (y <= ymax(r))
v[v] <- ((x[v] - xmin(r)) %% res(r)[1]) < tolerance
h[h] <- ((y[h] - ymin(r)) %% res(r)[2]) < tolerance
h | v
}
Illustration
library(terra)
r <- rast(nrow=5, ncol=5, xmin=0, xmax=5, ymin=0, ymax=5, vals=1:25)
x <- c(1, 1.5, 2, 3.5, 4.5)
y <- c(1, 1.5, 2.5, 5, 5.2)
on_border(r, x, y)
#[1] TRUE FALSE TRUE TRUE FALSE
plot(r); lines(r); points(x,y, xpd=TRUE, pch=20, cex=1.5)
To get the distance to the nearest border
to_border <- function(r, x, y) {
i <- (x >= xmin(r)) & (x <= xmax(r)) & (y >= ymin(r)) & (y <= ymax(r))
d <- rep(NA, length(i))
d[i] <- (x[i] - xmin(r)) %% res(r)[1]
d[i] <- pmin(d[i], (y[i] - ymin(r)) %% res(r)[2])
d
}
to_border(r, x, y)
#[1] 0.0 0.5 0.0 0.0 NA
In principle, you could also create lines from the raster, and do a relate query like I show below, but that is really inefficient.
pts <- vect(cbind(x, y), crs=crs(r))
rlns <- aggregate(as.lines(r))
relate(pts, rlns, "intersects")
# [,1]
#[1,] TRUE
#[2,] FALSE
#[3,] TRUE
#[4,] TRUE
#[5,] FALSE
But if you wanted the distance to the border, you may need to do something like this.
distance(pts, rlns)
# [,1]
#[1,] 0.0
#[2,] 0.5
#[3,] 0.0
#[4,] 0.0
#[5,] 0.2