Divide a LINESTRING with a list of LINESTRING

Question:

I’m searching a solution to divide Main Line with more than one overlapped lines. In this example I’ve four lines (I’ve applied an offset on Line 1, Line 2 and Line 3 in this chart to facilitate reading):
enter image description here

Below the lines:

from shapely import wkt

main_line = wkt.loads('LINESTRING (461179.6655721677 4507148.788223281, 461217.56786209624 4507181.537033379, 461236.3280996226 4507194.537878151, 461241.7247760045 4507197.640095252, 461258.8379542616 4507210.660701941, 461261.9432857035 4507219.791508417, 461270.90091201715 4507254.590010401, 461271.56385885156 4507303.918307676, 461273.67536588735 4507318.460376316, 461286.2322009634 4507358.346460313, 461302.55653224624 4507403.197152592, 461365.2492823085 4507485.060388609, 461480.4983426857 4507548.512415529, 461580.7367309019 4507618.493483591)')

line_1 = wkt.loads('LINESTRING (461179.6655721677 4507148.788223281, 461217.56786209624 4507181.537033379, 461236.3280996226 4507194.537878151, 461241.7247760045 4507197.640095252, 461258.8379542616 4507210.660701941, 461261.9432857035 4507219.791508417, 461270.90091201715 4507254.590010401, 461271.56385885156 4507303.918307676, 461273.67536588735 4507318.460376316, 461286.2322009634 4507358.346460313, 461302.55653224624 4507403.197152592)')
line_2 = wkt.loads('LINESTRING (461179.6655721677 4507148.788223281, 461217.56786209624 4507181.537033379, 461236.3280996226 4507194.537878151, 461241.7247760045 4507197.640095252, 461258.8379542616 4507210.660701941, 461261.9432857035 4507219.791508417, 461270.90091201715 4507254.590010401, 461271.56385885156 4507303.918307676, 461273.67536588735 4507318.460376316, 461286.2322009634 4507358.346460313, 461302.55653224624 4507403.197152592, 461365.2492823085 4507485.060388609)')
line_3 = wkt.loads('LINESTRING (461179.6655721677 4507148.788223281, 461217.56786209624 4507181.537033379, 461236.3280996226 4507194.537878151, 461241.7247760045 4507197.640095252, 461258.8379542616 4507210.660701941, 461261.9432857035 4507219.791508417, 461270.90091201715 4507254.590010401, 461271.56385885156 4507303.918307676, 461273.67536588735 4507318.460376316, 461286.2322009634 4507358.346460313, 461302.55653224624 4507403.197152592, 461365.2492823085 4507485.060388609, 461480.4983426857 4507548.512415529)')

I don’t know how many lines I’ve, in staging I will have a list. Looking the image above Main Line will be divided into 4 parts, but I’m little bit confused on how I can do this. I’ve used the code below hoping into a brilliant idea but without fortune.

line_list = [line_1, line_2, line_3]
diff_list = []
first_line_length = line_list[0].length

for line in line_list:
    line_length = line.length

    if line_length != first_line_length:
        diff = main_line.symmetric_difference(line)
        diff_list.append(diff)

fig, ax = plt.subplots(figsize=(10, 10))
ax.set_xlabel('X coordinate', fontsize=15)
ax.set_ylabel('Y coordinate', fontsize=15)

plt.plot(*main_line.xy, label='Main Line', color='blue')

plt.plot(*line_1.parallel_offset(distance=5).xy, label='Line 1', color='green')
plt.plot(*line_2.parallel_offset(distance=10).xy, label='Line 2', color='red')
plt.plot(*line_3.parallel_offset(distance=15).xy, label='Line 3', color='violet')

plt.plot(*diff_list[0].parallel_offset(distance=-5).xy, label='Diff Line 1', color='green')
plt.plot(*diff_list[1].parallel_offset(distance=-10).xy, label='Diff Line 2', color='red')

plt.legend()

plt.show()

In brief, if I have n lines shortest than a main line, I would like to divide that main line in n+1 parts.

Answers:

Assuming the exercise is as the one presented, (all lines have the same origin), modify your code to do the following:

  1. Order lines in descending length order, from the longest to the shortest (being the main line the longest)
  2. Then iterate the line list and do the symmetric difference only with the line following (main – line1, line1 – line2 and line2- line3).
  3. The segments will be the differences calculated in Step 2 plus line3.

Being Line1 longer than line2 and Line2 longer than line3

from shapely import wkt
from matplotlib import pyplot as plt

main_line = wkt.loads('LINESTRING (461179.6655721677 4507148.788223281, 461217.56786209624 4507181.537033379, 461236.3280996226 4507194.537878151, 461241.7247760045 4507197.640095252, 461258.8379542616 4507210.660701941, 461261.9432857035 4507219.791508417, 461270.90091201715 4507254.590010401, 461271.56385885156 4507303.918307676, 461273.67536588735 4507318.460376316, 461286.2322009634 4507358.346460313, 461302.55653224624 4507403.197152592, 461365.2492823085 4507485.060388609, 461480.4983426857 4507548.512415529, 461580.7367309019 4507618.493483591)')

line_1 = wkt.loads('LINESTRING (461179.6655721677 4507148.788223281, 461217.56786209624 4507181.537033379, 461236.3280996226 4507194.537878151, 461241.7247760045 4507197.640095252, 461258.8379542616 4507210.660701941, 461261.9432857035 4507219.791508417, 461270.90091201715 4507254.590010401, 461271.56385885156 4507303.918307676, 461273.67536588735 4507318.460376316, 461286.2322009634 4507358.346460313, 461302.55653224624 4507403.197152592)')
line_2 = wkt.loads('LINESTRING (461179.6655721677 4507148.788223281, 461217.56786209624 4507181.537033379, 461236.3280996226 4507194.537878151, 461241.7247760045 4507197.640095252, 461258.8379542616 4507210.660701941, 461261.9432857035 4507219.791508417, 461270.90091201715 4507254.590010401, 461271.56385885156 4507303.918307676, 461273.67536588735 4507318.460376316, 461286.2322009634 4507358.346460313, 461302.55653224624 4507403.197152592, 461365.2492823085 4507485.060388609)')
line_3 = wkt.loads('LINESTRING (461179.6655721677 4507148.788223281, 461217.56786209624 4507181.537033379, 461236.3280996226 4507194.537878151, 461241.7247760045 4507197.640095252, 461258.8379542616 4507210.660701941, 461261.9432857035 4507219.791508417, 461270.90091201715 4507254.590010401, 461271.56385885156 4507303.918307676, 461273.67536588735 4507318.460376316, 461286.2322009634 4507358.346460313, 461302.55653224624 4507403.197152592, 461365.2492823085 4507485.060388609, 461480.4983426857 4507548.512415529)')
line_list = [main_line,line_1, line_2, line_3]
line_list.sort(key=lambda x: x.length, reverse=True)
diff_list = []

for ix in range(len(line_list)-1):
#for line in line_list:
    lineA=line_list[ix]
    lineB=line_list[ix+1]
    #line_length = line.length

    #if line_length != first_line_length:
    diff = lineA.symmetric_difference(lineB)
    diff_list.append(diff)

fig, ax = plt.subplots(figsize=(10, 10))
ax.set_xlabel('X coordinate', fontsize=15)
ax.set_ylabel('Y coordinate', fontsize=15)

plt.plot(*main_line.xy, label='Main Line', color='blue')

plt.plot(*line_list[1].parallel_offset(distance=5).xy, label='Line 1', color='green')
plt.plot(*line_list[2].parallel_offset(distance=10).xy, label='Line 2', color='red')
plt.plot(*line_list[3].parallel_offset(distance=15).xy, label='Line 3', color='violet')

plt.plot(*diff_list[0].parallel_offset(distance=-5).xy, label='Diff main - Line 1', color='blue')
plt.plot(*diff_list[1].parallel_offset(distance=-10).xy, label='Diff Line 1 - Line 2', color='green')
plt.plot(*diff_list[2].parallel_offset(distance=-15).xy, label='Diff Line 2 - Line 3', color='red')

plt.legend()

plt.show()

enter image description here

Answered By: wrbp
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.