形状延伸的线特征

Shapely extending line feature

我在 Shapely 中有一个多边形和一个多线串。我想扩展未到达多边形边界的 LineString 段,以便它确实到达多边形边界。如果它延伸过去也没关系,因为我可以轻松地将它剪到边界。

理想情况下,它会以相同的角度继续,但我认为这比直接向上延伸到边界要困难得多。

有人对我如何着手做这件事有什么建议吗?

我使用以下代码生成了几何图形(作为我实际需要做的简化示例):

import shapely
from shapely.geometry import *
Line=MultiLineString([((3,0),(3,5)),((3,5),(7,9.5))])
Box=Polygon([(0,0),(0,10),(10,10),(10,0)])

在示例中,您可以只进行数学计算并找到线段(MultiLineString 最后一段和多边形边界的线段)生成的线之间的交点,而无需依赖任何形状库计算。

(我不明白为什么你应该使用简单的 LineString 而使用 MultiLineString,因为所有线段都是连续的)。

更通用的解决方案如下:

from shapely.geometry import *

def getExtrapoledLine(p1,p2):
    'Creates a line extrapoled in p1->p2 direction'
    EXTRAPOL_RATIO = 10
    a = p1
    b = (p1[0]+EXTRAPOL_RATIO*(p2[0]-p1[0]), p1[1]+EXTRAPOL_RATIO*(p2[1]-p1[1]) )
    return LineString([a,b])

line=LineString([(3,0),(3,5),(7,9.5)])
box=Polygon([(0,0),(0,10),(10,10),(10,0)])

box_ext = LinearRing(box.exterior.coords) #we only care about the boundary intersection
l_coords = list(line.coords)
long_line = getExtrapoledLine(*l_coords[-2:]) #we use the last two points

if box_ext.intersects(long_line):
    intersection_points = box_ext.intersection(long_line)
    new_point_coords = list(intersection_points.coords)[0] #
else:
    raise Exception("Something went really wrong")

l_coords.append(new_point_coords)
new_extended_line = LineString(l_coords) 

# To see the problem:
import pylab
x, y = box.exterior.xy
pylab.plot(x,y)
l_coords = list(line.coords)
x = [p[0] for p in l_coords]
y = [p[1] for p in l_coords]
pylab.plot(x,y)
longl_coords = list(long_line.coords)
x = [p[0] for p in longl_coords]
y = [p[1] for p in longl_coords]
pylab.plot(x,y)
pylab.plot(new_point_coords[0], new_point_coords[1], 'o')
pylab.show()

# To see the solution:
x, y = box.exterior.xy
pylab.plot(x,y)
l_coords = list(new_extended_line.coords)
x = [p[0] for p in l_coords]
y = [p[1] for p in l_coords]
pylab.plot(x,y)
pylab.show()

在此解决方案中,我们外推 Line 的最后一段并将其与多边形的边界线相交以获得交点。 几点说明:

  1. 注意 EXTRAPOL_RATIO 常量。根据多边形的复杂性或尺寸,它可以使线与多边形边界相交不止一点,或者根本不相交。
  2. 你要知道这是你要延长的线的最后一段。

我认为这个问题有很多解决方案。根据您想要的解决方案的通用性,它可能会变得非常复杂。我想您可以使代码适应更通用的设置。