I would like to extract the coordinates of a point at a known distance along the linestring, starting from one end of the linestring.
For example:
library(sf)
path <- st_as_sfc('LINESTRING(10 20, 11 21, 12 21, 13 22)')
start_point <- st_as_sfc('POINT(10 20)')
nodes <- st_as_sfc('MULTIPOINT(10 20, 11 21, 12 21, 13 22)')
plot(st_geometry(path))
plot(st_geometry(nodes), add = T, pch = 16, col = 'grey')
plot(st_geometry(start_point), add = T, pch = 16, col = 'red')
In the example code/image we have a linestring (nodes in grey) and the starting point (in this example the linestring starting coordinates) in red.
Example of desired output:
distance_line <- st_as_sfc('LINESTRING(10 20, 11 21, 11.5 21)')
point_wanted <- st_as_sfc('POINT(11.5 21)')
plot(st_geometry(distance_line), col = 'green', lwd = 4, add = T)
plot(st_geometry(point_wanted), add = T, pch = 16, col = 'blue')
Ultimately, I'm wanting to extract the coordinates (e.g. using st_coordinates) of the point at distance X along the linestring from the starting point. This feels like a common enough desire, so apologies if I have missed an obvious solution.
The only method I can see is to sample, using sf::st_line_sample, at a high resolution and extract the nearest value. This seems inefficient as I have many thousand linestrings with each only needing one distance coordinates. Ideally, the proposed method would be sf compatible.
Updated with more realistic data
path <- st_as_sf(data.frame(X = c(444618, 444640, 444661), Y = c(216561, 216556, 216550), L1 = 1), coords = c('X', 'Y'), crs = 27700) %>%
group_by(L1) %>%
summarise(do_union = F) %>%
st_cast('LINESTRING')
nodes <- st_as_sf(data.frame(X = c(444618, 444640, 444661), Y = c(216561, 216556, 216550), L1 = 1), coords = c('X', 'Y'), crs = 27700)
Testing method proposed by @agila:
st_distance(nodes)[1,]
Units: [m]
[1] 0.00000 22.56103 44.38468
Testing with point 2 and 3.
pt1 <- path %>% st_startpoint()
desired_distance <- units::set_units(22.56103, "m")
ratio <- desired_distance / st_length(path)
pt2 <- st_linesubstring(path, from = 0, to = ratio) %>% st_endpoint()
desired_distance <- units::set_units(44.38468, "m")
ratio <- desired_distance / st_length(path)
pt3 <- st_linesubstring(path, from = 0, to = ratio) %>% st_endpoint()
(st_distance(pt1, pt2))
Units: [m]
[,1]
[1,] 22.56103
(st_distance(pt1, pt3))
Units: [m]
[,1]
[1,] 44.36801
I don't know why the accuracy of this method appears to scale with the distance but this error is acceptable for my task.


