In R, I have a collection of points (~15,000) within a polygon.

For every point, I want to calculate the location on the polygon boundary nearest to the point's location. I'm not bothered about the point's distance from the boundary (i.e. gDistance etc.).

I have a method that works (below). I used nearestPointOnLine from maptools but this only works for 1 point. I wrapped it up in apply but with my spdf being very large, this is taking a while;


# create a dummy polygon: coordinates, promote to Polygons and SpatialPolygons
coordsPol = cbind(c(1,2,3,4,4),c(3,2,2,1,3))
verts <- rbind(coordsPol, coordsPol[1, ])
pol <- SpatialPolygons(list(Polygons(list(Polygon(verts)), ID="a")))

# create spatialpointsdataframe (they all fall inside the polygon)
p = data.frame(x=c(1.5,2.5,3,3.5,3.8),y=c(2.75,2.25,2.55,2.9,1.6),ID=c("a","b","c","d","e"))
coordinates(p) <- ~x+y

# Extract the point on the polygon boundary that is nearest to each spdf point.
# The polygon needs to be a matrix (ggplot::fortify) and maptools::nearestPointOnLine
# only works 1 point at a time so requires apply

v2.x <- apply(p@coords,1,function(x) nearestPointOnLine(as.matrix(fortify(pol)[,c(1,2)]),x))[1,]
v2.y <- apply(p@coords,1,function(x) nearestPointOnLine(as.matrix(fortify(pol)[,c(1,2)]),x))[2,]

# The output from nearestpointOnLine can be converted to a SpatialPoints object
v2m <- matrix(cbind(v2.x,v2.y),ncol=2)
v2p <- SpatialPoints(v2m)
  • Are there any functions (i thought rgdal would have one) that take a polygon and many points and give resulting nearest location points on a boundary (instead of apply and nearestPointOnLine)?
  • There's a lot of questions here, and it might be better if you can post it as separate questions, each with sample data. You see, I might know how to do one of these things but I won't answer because I can't provide a complete solution.
    – Spacedman
    Commented Feb 12, 2018 at 15:48
  • The third one is quite easy - if you know the total perimeter of the loop. If the clockwise distance is greater than half the perimeter, then the anticlockwise distance is shorter and is "perimeter minus clockwise distance"
    – Spacedman
    Commented Feb 12, 2018 at 15:54
  • thank you, of course it is. i shall separate the two other main issues out into 2 qu's
    – Sam
    Commented Feb 12, 2018 at 15:55


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.