2

I don't have a license for any software. So, I want to do it in Python.

How do I split the multiline or any linestring into equal segments by taking the length as input?

This is the code that I am using

import geopandas as gpd    
from shapely.ops import split
from shapely.geometry import LineString, MultiPoint

roads = roads['geometry'] # roads contain a single multiline points = points['geometry'] # points for finding the distance from line segements after segmenting the multiline

plot = roads.iloc[0] # roads.iloc[0] gives a multiline x = plot.length x = int(x/0.2) splitter = MultiPoint([plot.interpolate((i/x), normalized=True) for i in range(1, x)]) #splitter gives the points on multiline at equal distance, but only contains points plot = gpd.GeoSeries(plot) splitter = gpd.GeoSeries(splitter)

PolyGeo
  • 65,136
  • 29
  • 109
  • 338
  • 1
    What did you find or tried because unless you add a Python code attempt your question will be closed – gene Nov 13 '21 at 16:02
  • @gene please check now if there is anything that you can help me with. Thank you – Venkatesh Telu Nov 13 '21 at 17:03
  • 1
    You want to split each line into for example 10 equal length segments, or each line into for example 20 m long segments? It would be alot easier to use QGIS which have got the finished tools for this – BERA Nov 13 '21 at 17:41
  • @BERA I want to split line into segments of 500m each. – Venkatesh Telu Nov 14 '21 at 17:40

1 Answers1

1

There are many questions/answers in gis.stackexchange ans stackoverflow on this subject

Some of them
Splitting line shapefile into segments of equal length using Python
Break a shapely Linestring at multiple points
Shapely: Split LineString at arbitrary point along edge
Split lines at points using Shapely
Splitting line GeoDataFrame basing on given lengths

Example with a single shapely LineString and creation of equidistant points(from How to get equally spaced points on a line in Shapely)

from shapely.geometry import LineString, Point
import numpy as np
line = LineString(([0, 0], [2, 1], [3, 2], [3.5, 1], [5, 2]))
distance_delta = 0.9
# generate the equidistant points
distances = np.arange(0, line.length, distance_delta)
points = MultiPoint([line.interpolate(distance) for distance in distances] + [line.boundary[1]])
print(len(distances), len(points))
8 9

enter image description here

Now, due to floating point issues in Shapely, I use the solution of Jeremiah England with shapely.ops.snap before shapely.ops.split

 from shapely.ops import split,snap
 def split_line_by_point(line, point, tolerance: float=1.0e-12):
     return split(snap(line, point, tolerance), point)
 result = split_line_by_point(line,points)
 print len(result)
 8  # 8 segments

enter image description here

You can also use the solution of Grigory Nevsky based on the function cut(line, distance) in the The Shapely User Manual

 def cut(line, distance, lines):
     # Cuts a line in several segments at a distance from its starting point
     if distance <= 0.0 or distance >= line.length:
         return [LineString(line)]
     coords = list(line.coords)
     for i, p in enumerate(coords):
         pd = line.project(Point(p))
         if pd == distance:
             return [
                 LineString(coords[:i+1]),
                 LineString(coords[i:])
                 ]
         if pd > distance:
             cp = line.interpolate(distance)
             lines.append(LineString(coords[:i] + [(cp.x, cp.y)]))
             line = LineString([(cp.x, cp.y)] + coords[i:])
             if line.length > distance:
                 cut(line, distance, lines)
             else:
                 lines.append(LineString([(cp.x, cp.y)] + coords[i:]))
             return lines

result = cut(line, distance_delta, list()) print len(result) 8 # 8 segments

gene
  • 54,868
  • 3
  • 110
  • 187