# Get the vertices on a LineString either side of a Point

I have a shapely LineString and defined a shapely Point which lies along the LineString.

How can I find the vertices of the LineString which lie either side of the point? (split the line in two).

This is very similar to this blog post by the author: http://sgillies.net/blog/1040/shapely-recipes/

Except, instead of cutting by distance along the line, I want to cut given a point that lies along the line.

• one way is (if shapely supports) linear referencing. this toblerity.org/shapely/manual.html manual gives me impression that it supports it. Commented Jan 28, 2014 at 14:23
• linear referencing refers to a group of methods (at least when referring to shapely). Which method are you referring to? There are only two given in the manual, `interpolate` and `project`, which could be helpful but don't actually solve the problem Commented Jan 28, 2014 at 14:36
• i dont know shapely, but in postgis procedure goes like this. locate closest point on line, interpolate length from start at given point , cut line at that point. In code : SELECT ST_LineSubstring(line_geom,0,ST_LineLocatePoint(line_geom, point_geom)) FROM xxx.. would return you part of line which is before point Commented Jan 29, 2014 at 10:06

``````line = LineString([(0, 0), (2, 2)])
# create a point which lies along the line
point = line.interpolate(1)
line.contains(point)
True
``````

You want the two lines which lie either side of the point ?

``````line1 = LineString([line.coords[0],(point.x, point.y)])
line2 = LineString([(point.x, point.y), line.coords[1]])
``````

### Upgrade 1: with a line with multiple vertices

You need to iterate through the segments of the LineString to find the one that contains the point

The LineString must be iterate as pair to divide the line in segments.

``````def pairs(lst):
for i in range(1, len(lst)):
yield lst[i-1], lst[i]

line = LineString([(0,0),(1,2), (2, 2), (2,3), (4,2),(5,5)])

for pair in pairs(list(line.coords)):
if LineString([pair[0],pair[1]]).contains(point):
print LineString([pair[0],pair[1]])

LINESTRING (2.00 2.00, 2.00 3.00)
``````

And you can use the previous answer: a rapid solution, for example ( this can be done better):

``````line1 = []
line2 = []
cp = False
for pair in pairs(list(line.coords)):
if cp == False:
line1.append(pair[0])
if cp == True:
line2.append(pair[1])
if LineString([pair[0],pair[1]]).contains(point):
line1.append((point.x,point.y))
line2.append((point.x,point.y))
line2.append(pair[1])
cp = True
line1 = LineString(line1)
line2 = LineString(line2)
``````

Result:

• You have given an oversimplified version, which you have solved by visually inspecting the coordinates. Assume that the original linestring you created has any number of points. Let's keep it to 3 for simplicity. You create a point at some distance using interpolation. Now, how to get all the vertices of the original linestring either side of that point as seperate linestrings? Commented Jan 28, 2014 at 14:32
– gene
Commented Jan 28, 2014 at 14:37
• Your edit still doesnt answer the question, as you have still retrieved the indices of the vertices either side of the point by visually inspecting. I have a linestring with multiple vertices and a point at an arbritary distance along the linestring: I don't know between which vertices this point lies Commented Jan 28, 2014 at 14:39
• look at the Shapely User Manual, there is an example of cutting a line at a specified distance.
– gene
Commented Jan 28, 2014 at 14:45
• See my above post, which mentions using that method. However, I want to cut the line given a coordinate along the line, not a specified distance. You could back track to get the distance from the coordinate to the starting point and then employ that method, but it seems pretty inefficient Commented Jan 28, 2014 at 14:47

The best answer I can come up with so far is to use the 'cut' method outlined here:

http://toblerity.org/shapely/manual.html#linear-referencing-methods

But first calculate the distance between the arbitary point and the start of the line. This would have to be the distance along the line.. so it all seems a bit long winded. I'm sure there must be a simpler way...

Edit: I misinterpreted the `project` method thinking it would return the distance to the nearest point on the LineString; it seems like it returns the distance to the start. So, using the `cut` method as above is slightly less clunky than I thought

• I was working on the same thing a bit ago and used "project" to modify Sean's example, which worked well. Commented Jan 29, 2014 at 20:07