I'm new to using Shapely, and I have some question. I have a LineString and I wish to split it based on intersections of other LineStrings.

If the intersection turns out to be a single point, then we can simply use the following code to obtain a GeometryCollection of LineStrings split at that intersection point:

ip = ls.intersection(other_ls) # assuming ip here is a single Point()
ops.split(ls, ip)

Kind of like this, where our observed LineString is the blue one and the other LineString that splits it is red: enter image description here

However, if the intersection of two LineStrings is also another LineString (i.e., a shared path), then running the following code:

ops.split(ls, other_ls) # assuming that the intersection is also a LineString

returns an error:

ValueError: Input geometry segment overlaps with the splitter.

The picture I would like to present here is this: enter image description here

where again, the blue LineString is our observed and the red LineString is the one to split the blue one. The resultant would be a GeometryCollection of three LineStrings but of course it is also possible to obtain a GeometryCollection of two LineStrings as a result just depending on where the red LineString is situated. I wish to be able to do this, but using ops.split() does not seem to work.

But ultimately, I wish to generalize this as there can be many other LineStrings that overlap (i.e., intersect on many LineStrings), such as the following picture: enter image description here

But I am not exactly sure how to do it correctly. Here is a rough pseudocode that I came up with but I am not sure if it is right or whether it would be efficient when it is implemented. I'm not really looking for a top-notch solution when it comes to runtime. But at least something that works.

ls = observed_linestring
other_linestrings = list_consisting_of_other_linestrings
for ol in other_linestrings:
    intersections = ol.intersection(ls)
    point_intersections = [x for x in intersections if x is a Point]
    for point in point_intersections:
        splits = ops.split(ls, point)
return splits

1 Answer 1


Use unary_union (Planar Graph)

LineStrings will get fully dissolved and noded. Duplicate Points will get merged.

Original 4 lines

enter image description here

from shapely.ops import unary_union
lines = [line1,line2,line3,line4]
result = unary_union(lines)

The result is a MuliLineString with 13 lines

enter image description here

  • Thanks for the response. Actually, I just figured an algorithm without unary_union. The problem if I use that is that I will get extra unneeded linestrings from the MultiLineString. In the picture I drew, I only need linestrings belonging to the blue one. Here's how I did it: (1) Find all intersection pts between blue linestring and all other linestrings. (2) Find all intersection pts between any 2 linestrings that also intersect with the blue linestring (pairwise). (3) Create a MultiPoint of such pts, & use it a splitter for ops.split(blue,mp). I'll get a GeometryCollection of linestrings.
    – M. Fire
    Commented Oct 10, 2022 at 2:20

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.