2

I have one dataset with POINTS called pts1. I'm connecting them into aLINESTRING and I'm calculating intersection points of that LINESTRING with multiple LINESRINGs from another dataset. The main goal is when the intersection points are calculated I want them to be reinserted into the pts1 dataset in their corresponding place. Maybe there is a function in sf I don't know about or maybe this can be done with several conditions ?

Simplified example below:

# initial dataset
pts1 <- data.frame(id = c(1,1,1,1,1), lon = c(2,4,5,7,8), lat = c(1,4,3,2,5)) %>% 
  st_as_sf(coords = c("lon", "lat"), dim = "XY") %>% st_set_crs(4326)

# make linestring
lns1 <- pts1 %>% group_by(id) %>% 
  summarise(geometry = st_union(geometry), do_union = FALSE) %>% st_cast("LINESTRING")

# second dataset with multiple linestrings
lns2 <- data.frame(mark = c(1,1,2,2), lon = c(3,3,6.5,6.5), lat = c(1,4,1,4)) %>% 
  st_as_sf(coords = c("lon", "lat"), dim = "XY") %>% st_set_crs(4326) %>%
  group_by(mark) %>% summarise(geometry = st_union(geometry), do_union = FALSE) %>% st_cast("LINESTRING")

# intersection points
inters <- st_intersection(lns1, lns2)

# desired output: the intersection points have been reinserted in the first dataset pts1 between the original two points where the lines intersected
desired_df <- data.frame(id = c(1,NA,1,1,NA,1,1), 
               lon = c(2,3,4,5,6.5,7,8), 
               lat = c(1,2.5,4,3,2.25,2,5),
               mark = c(NA,1,NA,NA,2,NA,NA)) %>% 
  st_as_sf(coords = c("lon", "lat"), dim = "XY") %>% st_set_crs(4326)

Current and desired outcome

3

Thanks to Edzer Pebesma the following can be used to answer the question:

library(lwgeom) 
library(sf)
st_split(st_linestring(rbind(c(0,0), c(1,1))), st_linestring(rbind(c(0,1), c(1,0)))) %>%
  st_collection_extract("LINESTRING") %>% 
  st_combine() %>% 
  st_line_merge() 

Further on any ideas on how to keep the attributes of the geometries are welcome

1

You might use st_node to ensure the intersection points are present, and then find the intersection of that with the first object. You'll have to remove the POINT geometries ... and I haven't checked this in more complex situations.

g1 <- st_geometry(lns1)
g2 <- st_geometry(lns2)
d <- st_sf(geometry = c(g1, g2), dataset = rep(c("a", "b"), c(length(g1), length(g2))))

st_intersection(st_node(d), lns1) 
  • this answer did not provide the desired sf dataframe. Instead the output was a simple feature collection. The desired output would be sf dataframe in which the intersection points are inserted, ordered according to where the intersection happenned – adl May 17 '18 at 10:19
  • yes, sorry - I realized later this wasn't right - it must get normalized by the geom engine - still have an idea, and I think I've seen it done – mdsumner May 17 '18 at 13:26
  • First of all thank you for trying. It would be very useful to me personally if there could be a solution to this. It is a major problem on a project I'm working on – adl May 17 '18 at 14:50
  • It's a majorly general useful thing to do ;) We still need the complete union version, but that's probably possible more simply by node and combine plus intersect, this is helpful discussion – mdsumner May 18 '18 at 2:01
  • I agree 100%. The only down side with this solution is that the attributes of the geometries are lost which is really important. On the other hand sf::st_intersection gives the information of which linestring got intersected with which linestring. My background is not in GIS nor in R which is my excuse of not being able to think of a solution. If we can fix that I believe it can be very useful – adl May 18 '18 at 7:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.