11

I'm using Shapely in python and I'm given a MultiLineString with a bunch of Linestring objects. I can guarantee that all the LineString objects are simple lines with only 2 vertices and that they are all part of one single line (no branches).

I want to "connect-the-dots" and create a single LineString. Do I need to write a recursive welding method for this or is there a faster way?

17

You can use shapely's ops.linemerge to accomplish this:

from shapely import geometry, ops

# create three lines
line_a = geometry.LineString([[0,0], [1,1]])
line_b = geometry.LineString([[1,1], [1,0]])
line_c = geometry.LineString([[1,0], [2,0]])

# combine them into a multi-linestring
multi_line = geometry.MultiLineString([line_a, line_b, line_c])
print(multi_line)  # prints MULTILINESTRING ((0 0, 1 1), (1 1, 2 2), (2 2, 3 3))

# you can now merge the lines
merged_line = ops.linemerge(multi_line)
print(merged_line)  # prints LINESTRING (0 0, 1 1, 2 2, 3 3)

# if your lines aren't contiguous
line_a = geometry.LineString([[0,0], [1,1]])
line_b = geometry.LineString([[1,1], [1,0]])
line_c = geometry.LineString([[2,0], [3,0]])

# combine them into a multi-linestring
multi_line = geometry.MultiLineString([line_a, line_b, line_c])
print(multi_line)  # prints MULTILINESTRING ((0 0, 1 1), (1 1, 1 0), (2 0, 3 0))

# note that it will now merge only the contiguous portions into a component of a new multi-linestring
merged_line = ops.linemerge(multi_line)
print(merged_line)  # prints MULTILINESTRING ((0 0, 1 1, 1 0), (2 0, 3 0))
  • How can I know which linestring was merged ? I want to receive a list like: merged = [[line_a,line_b],[line_c]] – james Jan 2 '18 at 10:49
  • You could loop through a list of your individual lines and check whether the new merged line contains() the individual lines. Those not contained would not have been merged. e.g. merged_line.contains(line_a) which would return a boolean True or False – songololo Jan 2 '18 at 11:07
  • thanks a lot. How do you check if the line is contained in the merged_lines ? – james Jan 2 '18 at 11:14
  • 1
    ah, I didn't understand that ".contains(line_a)" was a prewritten function. perfect. Thanks a lot ! – james Jan 2 '18 at 11:29
  • 1
    sorry, to bother you again... but do you know who to merge lines which are "close" (within a certain maximum distance from each other) ? I am asking because I am seeing many lines which should be merged, but due to a small gab between them, they are not merged. – james Jan 6 '18 at 8:54
2

I think you could do it with Shapely using shapely.ops.linemerge() method.

It looks like it could take a list of lines as input and merge them. I used the 'polygonize' method before and it does take a list of lines.

Take a look at the doc here: http://toblerity.org/shapely/manual.html#shapely.ops.linemerge

  • 1
    Do you know how to merge lines which are "close" (within a certain maximum distance from each other) ? – james Jan 6 '18 at 16:34
  • polygonize_full works somewhat better, but I got some strange datastructures as a result – danuker Jul 12 at 10:08

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.