下面的代码是根据我在这里找到的代码进行修改的,该代码将形状优美的线串在沿线定义的点处分成两段。我还检查了其他问题,但他们没有直接解决我的问题。然而,我想扩展它以将线分成多个段(在多个点),到目前为止我所有的尝试都失败了。如何修改它以将字符串拆分为任意给定数量的段或在多个点((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)`
Run Code Online (Sandbox Code Playgroud)
和lineString 方法对于此类操作通常很方便projection。interpolate
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()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5535 次 |
| 最近记录: |