Friday, 11 October 2019

r - Return end-vertices of an sf linestring


I am trying to return the vertices of a linestring using the sf package. So far I have:


ls  <- st_sfc(st_linestring(rbind(c(0,0),c(0,1))),
st_linestring(rbind(c(0,0),c(10,0))))

get_line_endings <- function(line){


res <- lapply(line, function(x){
pnts <- st_coordinates(x)
pnts <- pnts[c(1, nrow(pnts)),]
data.frame(pnts)
})

res <- do.call("rbind", res)
res <- res[!duplicated(res),]

st_as_sf(res, coords = c("X", "Y"), crs = st_crs(line))

}

pnts <- get_line_endings(ls)

plot(ls)
plot(pnts, add = TRUE)

enter image description here


Is this error prone? Can I rely on st_coordinates being "in order"? Is there a more efficient way of doing this?



Answer




st_cast is what you are looking for.


library(sf)
library(mapview)

ls <- st_sfc(st_linestring(rbind(c(0,0),c(0,1))),
st_linestring(rbind(c(0,0),c(10,0))))

ptns = st_cast(ls, "POINT")

mapview(ls, color = "red") + ptns


You can also cast to MULTIPOINT if you wish.


Edit:


As mentioned by @Spacedman in the comments, this returns 4 points, because 2 separate linestrings with 2 vertices each are cast. If we want only 3 points, we need to set up the line to be a single linestring with 3 vertices:


ls = st_sfc(st_linestring(matrix(c(c(0,1),c(0,0),c(10,0)), 
ncol = 2, byrow = TRUE)))

Then pnts = st_cast(ls, "POINT") will result in 3 points.


Edit 2:


If you only want the endpoints, then st_line_sample is what you are looking for:



ptns = st_line_sample(ls, sample = 1)

where sample is a numeric value between 0 and 1 (0 being the start point and 1 the endpoint).


No comments:

Post a Comment

arcpy - Changing output name when exporting data driven pages to JPG?

Is there a way to save the output JPG, changing the output file name to the page name, instead of page number? I mean changing the script fo...