I'm trying to split a Shapely LineString at the nearest point to some other coordinate. I can get the closest point on the line using project
and interpolate
but I am unable to split the line at this point as it is not a vertex.
I need to split the line along the edge, not snapped to the nearest vertex, so that the nearest point becomes a new vertex on the line.
Here's what I've done so far:
from shapely.ops import split
from shapely.geometry import Point, LineString
line = LineString([(0, 0), (5,8)])
point = Point(2,3)
# Find coordinate of closest point on line to point
d = line.project(point)
p = line.interpolate(d)
print(p)
# >>> POINT (1.910112359550562 3.056179775280899)
# Split the line at the point
result = split(line, p)
print(result)
# >>> GEOMETRYCOLLECTION (LINESTRING (0 0, 5 8))
Thanks!
As it turns out the answer I was looking for was outlined in the documentation as the cut
method:
def cut(line, distance):
# Cuts a line in two 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)
return [
LineString(coords[:i] + [(cp.x, cp.y)]),
LineString([(cp.x, cp.y)] + coords[i:])]
Now I can use the project
ed distance to cut the LineString
:
...
d = line.project(point)
# print(d) 3.6039927920216237
cut(line, d)
# LINESTRING (0 0, 1.910112359550562 3.056179775280899)
# LINESTRING (1.910112359550562 3.056179775280899, 5 8)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With