Create sf Lines from Start and End Coordinates
As I couldn’t believe it myself, but there’s not a developed function in R that creates a sf object that contains several lines, deriving from the start and end coordinates (latitude and longitude) of each line. For example, I have a simple table with the line id and start and end point coordinates, like this:
Pair_ID | O_Lat | O_Lon | D_Lat | D_Lon |
---|---|---|---|---|
1 | 47.6408 | -122.3359 | 47.6911 | -122.4516 |
2 | 47.6081 | -122.0917 | 47.5152 | -122.2197 |
3 | 47.7023 | -122.2591 | 47.6526 | -122.2096 |
Then, I created a function to convert this table into a single sf object that contains three lines:
library(dplyr)
library(sf)
library(sp)
library(leaflet)
###The table above is imported as "od" here.
od_coords_to_sf <- function(df) {
#prepare the table from wide to long
part1 <-df[,c(1,2,3)] %>%
mutate(shape_pt_sequence =1)%>%
rename(shape_pt_lat=O_Lat,
shape_pt_lon=O_Lon)
part2 <-df[,c(1,4,5)] %>%
mutate(shape_pt_sequence =2)%>%
rename(shape_pt_lat=D_Lat,
shape_pt_lon=D_Lon)
allpart <- rbind(part1, part2)
allpart<-allpart %>% arrange(colnames(df[1]))
m <- as.matrix(allpart[order(allpart$shape_pt_sequence),
c("shape_pt_lon", "shape_pt_lat")])
m <- sf::st_linestring(m)
shape_linestrings <- sf::st_sfc(m, crs = 4326)
shapes_sf <- sf::st_sf(Pair_ID =allpart$Pair_ID, geometry = shape_linestrings)
shapes_sf <-shapes_sf %>% distinct(Pair_ID, .keep_all = TRUE)
return(shapes_sf)
}
#Now run a loop to go through all the pt pairs
#run loop
all_segment <- data.frame()
for (i in 1:nrow(od)){
one_seg <- od[i,] %>% od_coords_to_sf()
all_segment <- rbind(all_segment, one_seg)
}
plot(all_segment)
#map the segments using leaflet
map <- leaflet(data=all_segment)%>% addTiles()%>% addPolylines()
map
And the final results look like:
And, the end, tada!
P.S. I recently came up with this page talking about converting text strings directly to sf. If this works it would be so much simpler than the method above. However, I haven’t been able to successfully run it. Will continue to test this out.