[英]Break a shapely Linestring at multiple points
下面的代碼是從我在此處找到的代碼修改而來的,該代碼在沿直線定義的點將勻稱的Linestring分成兩段。 我還檢查了其他問題,但它們沒有直接解決我的查詢。 但是,我想擴展它以將線分成多個段(在多個點),到目前為止,我所做的所有嘗試都失敗了。 如何修改以將字符串分成任意給定數量的段或在多個點上說((4,5),(9,18)和(6,5))。
input:
line = LineString([(1,2),(8,7),(4,5),(2,4),(4,7),(8,5),(9,18),(1,2),(12,7),(4,5),(6,5),(4,9)])
breakPoint = Point(2,4)
from shapely.geometry import Point,LineString
def make_line_segment(line_string, breakPoint):
geoLoc = line_string.coords
j = None
for i in range(len(geoLoc) - 1):
if LineString(geoLoc[i:i + 2]).intersects(breakPoint):
j = i
break
assert j is not None
# Make sure to always include the point in the first group
if Point(geoLoc[j + 1:j + 2]).equals(breakPoint):
return geoLoc[:j + 2], geoLoc[j + 1:]
else:
return geoLoc[:j + 1], geoLoc[j:]
line1,line2 = make_line_segment(line,breakPoint)
line1 = LineString(line1)
line2 = LineString(line2)
print line1, line2
output: `LINESTRING (1 2, 8 7, 4 5, 2 4) LINESTRING (2 4, 4 7, 8 5, 9 18, 1 2, 12 7, 4 5, 6 5, 4 9)`
projection
和interpolate
lineString方法通常可用於此類操作。
from shapely.geometry import Point, LineString
def cut(line, distance):
# Cuts a line in two at a distance from its starting point
# This is taken from shapely manual
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:])]
def split_line_with_points(line, points):
"""Splits a line string in several segments considering a list of points.
The points used to cut the line are assumed to be in the line string
and given in the order of appearance they have in the line string.
>>> line = LineString( [(1,2), (8,7), (4,5), (2,4), (4,7), (8,5), (9,18),
... (1,2),(12,7),(4,5),(6,5),(4,9)] )
>>> points = [Point(2,4), Point(9,18), Point(6,5)]
>>> [str(s) for s in split_line_with_points(line, points)]
['LINESTRING (1 2, 8 7, 4 5, 2 4)', 'LINESTRING (2 4, 4 7, 8 5, 9 18)', 'LINESTRING (9 18, 1 2, 12 7, 4 5, 6 5)', 'LINESTRING (6 5, 4 9)']
"""
segments = []
current_line = line
for p in points:
d = current_line.project(p)
seg, current_line = cut(current_line, d)
segments.append(seg)
segments.append(current_line)
return segments
if __name__ == "__main__":
import doctest
doctest.testmod()
在這種方法中,首先,我在起點處拆分了點列表,並形成了如下的線列表,
# List of coordinates
coords = [(1,2),(8,7),(4,5),(2,4),(4,7),(8,5),(9,18),(1,2),(12,7),(4,5),(6,5),(4,9)]
no_seg = 3 #Number of segments, you need from 'coords'
coords_sub = np.array_split(coords, no_seg)
list_lines = [] # empty list
for i in range(len(X_sub)):
list_lines.append(LineString(X_sub[i]))
list_lines[1] # Displays the second line of the list
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.