I would like to snap a point to the closest point on a road segment using sf::st_snap
. However, the function seems to return the wrong result, it\'s snapping my poi
I don't know why st_snap
returns the start/end point of the linestring. Maybe that is something for an issue at https://github.com/r-spatial/sf.
Here's a workaround that seems to identify the correct point. Note that st_nearest_points
was only introduced recently, so you may need to install sf from github.
nrst = st_nearest_points(point1, roads)
new_point2 = st_cast(nrst, "POINT")[2]
mapView(point1, color="red") + st_buffer(point1, dist = cut_dist) + new_point2 + roads
Wrapping this is a function to return a new geometry set with snapped points below a certain max_dist
:
library(sf)
library(mapview)
st_snap_points = function(x, y, max_dist = 1000) {
if (inherits(x, "sf")) n = nrow(x)
if (inherits(x, "sfc")) n = length(x)
out = do.call(c,
lapply(seq(n), function(i) {
nrst = st_nearest_points(st_geometry(x)[i], y)
nrst_len = st_length(nrst)
nrst_mn = which.min(nrst_len)
if (as.vector(nrst_len[nrst_mn]) > max_dist) return(st_geometry(x)[i])
return(st_cast(nrst[nrst_mn], "POINT")[2])
})
)
return(out)
}
brew = st_transform(breweries, st_crs(trails))
tst = st_snap_points(brew, trails, 500)
mapview(breweries) + mapview(tst, col.regions = "red") + trails