【发布时间】:2018-02-20 13:45:51
【问题描述】:
我有一个城市的简化地图,其中街道作为线串,地址作为点。我需要找到从每个点到任何街道线的最近路径。我有一个可以执行此操作的工作脚本,但它在多项式时间内运行,因为它嵌套了 for 循环。对于 150 000 行(shapely LineString)和 10 000 个点(shapely Point),在 8 GB Ram 计算机上需要 10 个小时才能完成。
函数看起来像这样(抱歉不能完全重现):
import pandas as pd
import shapely
from shapely import Point, LineString
def connect_nodes_to_closest_edges(edges_df , nodes_df,
edges_geom,
nodes_geom):
"""Finds closest line to points and returns 2 dataframes:
edges_df
nodes_df
"""
for i in range(len(nodes_df)):
point = nodes_df.loc[i,nodes_geom]
shortest_distance = 100000
for j in range(len(edges_df)):
line = edges_df.loc[j,edges_geom]
if line.distance(point) < shortest_distance:
shortest_distance = line.distance(point)
closest_street_index = j
closest_line = line
...
然后我将结果作为新列保存在表格中,将点到线的最短路径添加为新列。
有没有办法通过添加一些功能使其更快?
例如,如果我可以过滤掉 50m 左右以外的每个点的线,这将有助于加快每次迭代?
有没有办法使用 rtree 包来加快速度?我能够找到一个答案,使用于查找多边形交集的脚本更快,但我似乎无法使其适用于最近的点到线。
Faster way of polygon intersection with shapely
https://pypi.python.org/pypi/Rtree/
对不起,如果这个问题已经回答了,但我在这里和 gis.stackexchange 上都没有找到答案
谢谢你的建议!
【问题讨论】:
-
您可以尝试this question 中的代码,看看通过过滤掉远处的链接可以提高多少速度。您可以尝试的另一种方法是获取线串的中心点(使用“shapely interpolate”),然后使用 rtree 查找候选链接(点对点搜索),然后计算距离。
-
@boardrider 感谢您的链接,我编辑了代码。不幸的是,在这里很难重现如此大的数据集。
-
这就是minimal reproducible example 中的Minimal 发挥作用的地方。我查看了代码,它仍然不像一个可验证的示例
-
您还需要这方面的帮助吗?如果是这样,我们将需要一些有关数据的信息。 1) 每个 LineString 大约有多少个点? 2) 这是您需要执行一次的计算,还是您需要一个适用于新输入点和 LineStrings 的解决方案?我要做的是构建自己的“rtree-like”数据结构,但不是在(可能很长的)LineStrings 上构建它,而是使用所有 LineStrings 的段。您还可以通过支付一些额外的计算直接使用 rtree 库。
标签: python pandas gis shapely r-tree