获取LineString上点的两侧顶点

3

我有一个漂亮的LineString,并定义了一个位于LineString上的漂亮的Point

如何找到LineString上位于该点两侧的顶点?(将线段分为两部分)

2个回答

3

较新版本的Shapely (>=1.6.0 (2017-08-21)) 提供了 split 函数,它可以通过一个点将一条线分割成两部分:

from shapely.geometry import LineString, Point
from shapely.ops import split

line = LineString([(0, 0), (1, 1), (2, 1)])
point = Point(1.5, 1)
print(split(line, point))
# GEOMETRYCOLLECTION (LINESTRING (0 0, 1 1, 1.5 1), LINESTRING (1.5 1, 2 1))

需要注意的是,由于精度误差,有时候这并不能正常工作:

line = LineString([(0, 0), (3, 2)])
point = Point(1, 2 / 3)
print(split(line, point))
# GEOMETRYCOLLECTION (LINESTRING (0 0, 3 2))
print(point.distance(line))
# 0.0

应对这种情况的一种方法是构建一个新的LineString,其中包含分割点。

new_line = LineString([line.coords[0], point.coords[0], line.coords[1]])
print(split(new_line, point))
# GEOMETRYCOLLECTION (LINESTRING (0 0, 1 0.6666666666666666), LINESTRING (1 0.6666666666666666, 3 2))

或者如果您不想手动执行:
from itertools import chain

all_points_coords = chain(line.coords, point.coords)
all_points = map(Point, all_points_coords)
new_line = LineString(sorted(all_points, key=line.project))
print(split(new_line, point))
# GEOMETRYCOLLECTION (LINESTRING (0 0, 1 0.6666666666666666), LINESTRING (1 0.6666666666666666, 3 2))

3

定位点所在的线段在LineString中的位置。然后根据此将LineString的顶点分为两组。要定位线段,只需对每个线段应用点/线段交叉测试即可。

from shapely.geometry import Point,LineString

def split(line_string, point):
    coords = line_string.coords
    j = None

    for i in range(len(coords) - 1):
        if LineString(coords[i:i + 2]).intersects(point):
           j = i
           break

    assert j is not None

    # Make sure to always include the point in the first group
    if Point(coords[j + 1:j + 2]).equals(point):
        return coords[:j + 2], coords[j + 1:]
    else:
        return coords[:j + 1], coords[j:]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接