pandas OSMnx等时线

t40tm48m  于 2023-01-28  发布在  其他
关注(0)|答案(2)|浏览(141)

我有一个位置(lat,lon)的大型数据(10k行),我想使用OSMnx计算从每个点开始的10分钟步行等时线。(我尝试使用 openrouteservice,但有一些限制)。https://github.com/gboeing/osmnx-examples/blob/v0.13.0/notebooks/13-isolines-isochrones.ipynb

import pandas as pd
import geopandas as gpd
from shapely.geometry import Point, Polygon
import networkx as nx
import osmnx as ox
ox.config(log_console=True, use_cache=True)

def get_isochrone(lon, lat, walk_time=10, speed=4.5):
    loc = (lat, lon)
    G = ox.graph_from_point(loc, simplify=True, network_type='walk')
    gdf_nodes = ox.graph_to_gdfs(G, edges=False)
    x, y = gdf_nodes['geometry'].unary_union.centroid.xy
    center_node = ox.get_nearest_node(G, (y[0], x[0]))
    meters_per_minute = speed * 1000 / 60 #km per hour to m per minute
    for u, v, k, data in G.edges(data=True, keys=True):
        data['time'] = data['length'] / meters_per_minute
    subgraph = nx.ego_graph(G, center_node, radius=walk_time, distance='time')
    node_points = [Point(data['x'], data['y']) for node, data in subgraph.nodes(data=True)]
    polys = gpd.GeoSeries(node_points).unary_union.convex_hull
    return polys

然后把它应用到我的Pandas数据框上:

df.apply(lambda x: get_isochrone(x.lon, x.lat), axis=1)

但是花了这么多的时间。100行大约是3分钟的运行时间。有没有其他的方法,包来达到这个目标?与一个合理的运行时间?
最后一个问题,OSMnx请求的限制是什么,特别是对于大数据?谢谢

mbskvtky

mbskvtky1#

这是一个非常缓慢的过程。如果你有10,000个位置,而且它们彼此相距甚远,那么你需要下载并建模10,000个本地街道网络,以计算每个点周围的可达性。这意味着10,000次服务器调用、数据下载、图形构建和拓扑清理等。
因此,3分钟内完成100行对我来说似乎相当快,特别是考虑到这意味着您可以在大约300分钟(即5个小时)内完成所有10,000行。只需在睡觉前启动该过程,当您醒来时它就会完成。这里假设这是一次性计算,不需要频繁地重新计算。
另一种选择是将其并行化,比如将其划分为10个容器或流程,每个处理1,000个位置。根据您的估计时间,这将在30分钟内完成。
最后一个问题,OSMnx请求的限制是什么,特别是对于大数据?
使用OSMnx处理大规模网络模型的限制是计算机上的RAM量。

vfh0ocws

vfh0ocws2#

你可以通过删除函数中的for循环来减少时间,因为你创建了一个变量time data['time'] = data['length'] / meters_per_minute,在这个例子中walk_time=10, speed=4.5相当于每分钟走75米,或者总共走750米,所以不用创建变量time,只需要使用变量length,从中心节点走750米。
此外,get_nearest_node现在已弃用,因此现在必须使用nearest_nodes
修改的代码:

import pandas as pd
import geopandas as gpd
from shapely.geometry import Point, Polygon
import networkx as nx
import osmnx as ox
ox.config(log_console=True, use_cache=True)

def get_isochrone(lon, lat, walk_time=10, speed=4.5):
    loc = (lat, lon)
    G = ox.graph_from_point(loc, simplify=True, network_type='walk')
    #G = ox.project_graph(G, to_crs="4483") # Use this line if the coordinates sistem returned from polys is changed from the original (check which crs you are using)
    gdf_nodes = ox.graph_to_gdfs(G, edges=False)
    x, y = gdf_nodes['geometry'].unary_union.centroid.xy
    center_node = ox.nearest_nodes(G, Y = y[0], X= x[0])
    walking_meters = walk_time * speed * 1000 / 60 #km per hour to m per minute times the minutes to walk
    subgraph = nx.ego_graph(G, center_node, radius=walking_meters, distance='length')
    node_points = [Point(data['x'], data['y']) for node, data in subgraph.nodes(data=True)]
    polys = gpd.GeoSeries(node_points).unary_union.convex_hull
    return polys

相关问题