0

I need to split a multilinestring layer by the vertices:

enter image description here

I've been trying to do this and nothing seems to work. I'm sure this is something really simple to do.

Using this example:

# Load required libraries
library(sf)
library(ggplot2)

# Create sample data
line1 <- st_linestring(matrix(c(1,1,2,2,3,3), ncol=2))
line2 <- st_linestring(matrix(c(4,4,5,5,6,6), ncol=2))
multiline <- st_multilinestring(list(line1, line2))

# Combine into a data frame
data <- data.frame(id = 1:2)
row.names(data) <- c("line1", "line2")
data$geometry <- st_sfc(multiline)

# Convert to sf object
multiline_sf <- st_sf(data, crs = st_crs(4326))

# Plot using ggplot2
ggplot() +
  geom_sf(data = multiline_sf, color = "blue", size = 2) +
  theme_minimal()

# Vertices 
Vertices <- multiline_sf %>%
  st_cast("MULTIPOINT")

Vertices <- Vertices %>%
  st_cast("POINT")

ggplot() +
  geom_sf(data = multiline_sf, color = "red") +
  geom_sf(data = Vertices, color = "blue")

I have tried st_intersection, st_difference, st_erase (st_erase = function(x, y) st_difference(x, st_union(st_combine(y))))

Nothing seems to work.

For example, if I do something like:

# Buffer

buffers <- st_buffer(Vertices, dist = 0.1)

diff <- st_difference(multiline_sf, buffers)

The expected output should be a layer with 4 lines, but the output is a layer with 24 lines.

1
  • Splitting is one thing, but you've also constructed an object (multiline_sf) with two copies of the same geometry - did you want that made unique as well?
    – Spacedman
    Mar 21 at 16:19

1 Answer 1

2

I believe you can achieve such a split by utilizing lwgeom::st_split() on the multiline and vertices object.

In raw form it creates duplicates, to get rid of them I remove the original id and add a unique() call. This may be and may not be necessary in your original use case, but gets the job done in the toy example you provided.

library(dplyr)

result <- lwgeom::st_split(multiline_sf, Vertices) %>% 
  st_collection_extract("LINESTRING") %>% 
  # eliminate duplicites / lines vs line id's
  select(-id) %>%
  unique() %>% 
  # a technical id for nicer plot
  mutate(id = 1:n())

ggplot(result) +
  geom_sf(aes(color = as.factor(id)), linewidth = 2) +
  scale_color_brewer("object id", palette = "Set1")

a split multilines plot, viola!

1
  • 1
    You are the man! work lovely in the example, I'll give it a try with the real data. THANKS!
    – Papu
    Mar 21 at 14:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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