下面的代码是从我发现的here修改而来的,它将形状上的线串分割成沿线定义的两个线段。我还检查了其他问题,但他们没有直接解决我的问题。但是我想扩展它以将线分成多个段(在多个点),到目前为止我所做的所有尝试都失败了。如何修改以将字符串拆分为任何给定数量的段或多个点(例如(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)`
答案 0 :(得分:2)
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()
答案 1 :(得分:0)
在这种方法中,首先我在开头分割点列表并形成如下行的列表,
# 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