adl
adl

Reputation: 1441

r-Split linestring into multilinestring with sf

I`m trying to split 2 lines in "LINESTRING" sf format in a dataframe, with 2 circles in "MULTIPOLYGON" sf format in another dataframe.

# make data frame with sf points 
lndf <- data.frame(
  x = c(40, 55, 60, 70),
  y = c(5, 20, 30, 35),
  attr_data = c(10,10,10,10),
  var = c("abc", "abc", "bac", "bac")
) %>% # convert longitude and latitude into sf points with crs
  st_as_sf(coords = c("x","y"), dim = "XY") %>% 
  st_set_crs(4326)

# convert sf points to sf lines -> first dataframe
lndf <- lndf %>% 
  group_by(var) %>% 
  summarize(a = sum(attr_data)) %>%         
  st_cast("LINESTRING")

# make data frame with sf points
cidf <- data.frame(
  x = c(40, 55, 60, 70),
  y = c(5, 20, 30, 35),
  attr_data = c(10,10,10,10),
  gr = c("abc", "abc", "bac", "bac")
) %>% # convert longitude and latitude into sf points with crs
  st_as_sf(coords = c("x","y"), dim = "XY") %>% 
  st_set_crs(4326)

# convert sf points to sf circle polygons 
cidf <- st_buffer(cidf, 1)   

# convert sf circle polygons to sf multilinestring  -> second dataframe
mls_cidf <- cidf %>% 
  group_by(gr) %>% 
  summarize(a = sum(attr_data)) %>%     
  st_cast("MULTILINESTRING", group_or_split = FALSE) %>% 
  st_set_crs(4326)

# Calculating intersection points between lines and circle polygons
inters <- st_intersection(lndf$geometry, mls_cidf)

# Calculating small circles around intersection points
buffer <- st_buffer(inters, dist = 1e-12)

# split linestring into multilinestring
difference <- st_difference(lndf, buffer) 

Here I was expecting sf dataframe with two rows in which there are two multilinestrings, instead I get sf dataframe with 4 rows (having 4 geometries). I`m only interested in how the small circle polygons from the n row of mls_cidf cut the linestring from the n row of lndf, and not all of the combinations between all rows in both dataframes. After getting the two multilinestrings I want to separate them in linestrings with:

 lnstrngs <- st_cast(difference, "LINESTRING") 

I`m very grateful for any opinions. Desired output: OUTPUTS

Upvotes: 2

Views: 2254

Answers (1)

adl
adl

Reputation: 1441

seems the answer includes using purrr::map2

# split linestring into multilinestring  
mls_to_ls <- function(ls, pl) {
  st_difference(ls, st_buffer(st_intersection(ls, pl), dist = 1e-12))
}
# iterate over rows of lndf and mls_cidf
map2(lndf$geometry, mls_cidf$geometry, mls_to_ls)

but the answer is a list of multilinestrings which I cannot convert to an sf dataframe. Any opinions are welcome

Upvotes: 1

Related Questions