匀称延伸的线条特征

AJG*_*519 5 python shapely

我在 Shapely 中有一个 Polygon 和一个 MultiLineString。我想扩展未到达多边形边界的 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)])
Run Code Online (Sandbox Code Playgroud)

多边形和折线

egu*_*aio 6

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

(我不明白为什么当您应该使用简单的 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()
Run Code Online (Sandbox Code Playgroud)

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

  1. 注意EXTRAPOL_RATIO常量。根据多边形的复杂性或尺寸,它可能会使线与多边形边界相交于多个点,或者根本不与点相交。
  2. 您依赖于知道这是您想要延伸的线的最后一段。

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

  • `getExtrapoledLine` 也可以使用 Shapely 的 [`scale`](https://shapely.readthedocs.io/en/latest/manual.html#shapely.affinity.scale) 函数来实现。 (7认同)
  • @Oleg如果“LineString”有多个段,并且您只想推断最后一个段,则必须先提取它(“last_segment = LineString(line.coords[-2:])”),然后使用倒数第二个段对其进行缩放点作为原点 (`scaled_last_segment = scale(last_segment, xfact=10, yfact=10, origin=last_segment.boundary[0])`),然后使用新的外推线段重建初始 `LineString` (`new_line = LineString ([*line.coords[:-2], *scaled_last_segment.coords])`)。 (2认同)