如何在Shapely中获得等间距点线?

7

我正在尝试将线段的点大致等间距地分布到预定义的距离上。

在距离之间有一些容差是可以接受的,但尽可能接近最好。

我知道我可以手动遍历线段中的每个点,并检查P1与P2之间的距离,如果需要,添加更多的点。

但我想知道是否有一种方法可以使用shapely实现这一目标,因为我已经在一个LineString中有了坐标。

enter image description here

2个回答

20

一种方法是使用interpolate方法,该方法返回沿着线指定距离的点。您只需要先以某种方式生成一个距离列表即可。从Roy2012的答案中使用输入线条示例:

import numpy as np
from shapely.geometry import LineString
from shapely.ops import unary_union

line = LineString(([0, 0], [2, 1], [3, 2], [3.5, 1], [5, 2]))

输入图像描述

在指定距离处分割:

distance_delta = 0.9
distances = np.arange(0, line.length, distance_delta)
# or alternatively without NumPy:
# points_count = int(line.length // distance_delta) + 1
# distances = (distance_delta * i for i in range(points_count))
points = [line.interpolate(distance) for distance in distances] + [line.boundary[1]]
multipoint = unary_union(points)  # or new_line = LineString(points)

输入图像描述
请注意,由于距离是固定的,您可能会在行末遇到问题,如图所示。根据您的需要,您可以包括/排除添加线条终点的[line.boundary[1]]部分,或者使用distances = np.arange(0,line.length,distance_delta)[:-1]来排除倒数第二个点。

此外,请注意我正在使用的unary_union应该比在循环内调用object.union(other)更有效率,如另一个回答中所示。

将其分割成固定数量的点:

n = 7
# or to get the distances closest to the desired one:
# n = round(line.length / desired_distance_delta)
distances = np.linspace(0, line.length, n)
# or alternatively without NumPy:
# distances = (line.length * i / (n - 1) for i in range(n))
points = [line.interpolate(distance) for distance in distances]
multipoint = unary_union(points)  # or new_line = LineString(points)

在此输入图片描述


哇,太完美了。 - Lewis Morris
我刚意识到 points = [line.interpolate(distance) for distance in distances] + [line.boundary[1]] 翻转了轴。我认为你需要使用 boundary[0] - Lewis Morris
1
@LewisMorris,“翻转轴”是什么意思?我无法通过所给示例复现此问题。我也不确定将“boundary [1]”更改为“boundary [0]”如何解决问题,因为“boundary [0]”应已包含在内,因为“distances”的第一个值为零。 - Georgy

4
您可以使用 shapelysubstring 操作:
from shapely.geometry import LineString
from shapely.ops import substring

line = LineString(([0, 0], [2, 1], [3,2], [3.5, 1], [5, 2]))

mp = shapely.geometry.MultiPoint()
for i in np.arange(0, line.length, 0.2):
    s = substring(line, i, i+0.2)
    mp = mp.union(s.boundary)

这些数据的结果如下所示。每个圆圈代表一个点。

enter image description here


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