无论您是想找到从A地到B地的最佳路线,还是试图分析社区进入超市的情况以识别食物沙漠,以网络的形式构建问题,以街道为边缘,通常都是最简单和最容易解决的方法。
但是,在开始构建街道网络之前,您需要数据。谷歌地图可能是大多数人想到地理信息时的首选,但遗憾的是它的API不是免费的。值得庆幸的是,有一个免费的开源替代方案,其中包含许多相同的数据:OpenStreetMaps(OSM)项目。
但是,在找到数据源之后,浏览OSM的节点、路径和关系数据模型仍然很痛苦。让自己熟悉多个API(它有三个)和下载方法及其相关的查询语言更加困难,而且耗费大量时间。值得庆幸的是,南加州大学Geoff Boeing教授出色的OSMnx项目可以为您完成所有繁重的工作。
OSMnx简介OSMnx是一个开源Python库,允许您通过简单的查询(例如地名或边界框)下载OSM数据。它不仅可以获取这些数据,更重要的是,它还对来自OSM的原始数据执行各种预处理,并将其格式化为易于转换为NetworkX MultiDiGraph的形式。对于那些不熟悉它的人,NetworkX是Python中首屈一指的图形分析和可视化库。因此,它很容易处理许多任务,例如寻找两点之间的最短路径等等。
此外,OSMnx还对NetworkX图形和GeoPandas GeoDataFrame之间的转换提供一流的支持,这是我们都知道和喜爱的Pandas DataFrame的扩展,增加了对以表格格式处理地理空间数据的支持。在这样做的过程中,OSMnx还允许使用GeoPandas地图工具快速轻松地可视化OSM街道网络,并具有额外的辅助功能,以增加对结果地图的自定义。
本教程的其余部分将介绍使用OSMnx完成其中一些任务的示例,以及代码示例。让我们首先下载一些数据。
使用OSMnx下载街道网络您可以通过OSMnx使用几个选项来下拉街道网络,例如地点名称、边界框、与某个经纬度点的距离或地址周围的半径。例如,让我们尝试获取加利福尼亚州旧金山和奥克兰的街道网络。
import osmnx as ox
cities = [
"San Francisco, California",
{
'city': 'Oakland',
'state': 'California',
'country': 'USA'
}
]
sf_oakland = ox.graph_from_place(cities, network_type='drive', simplify=True)
请注意,我们可以将地点指定为字符串(在旧金山的情况下)或更精确地指定区域的字典(就像我们为奥克兰所做的那样)。如上例所示,我们也可以仅在单个地点或地点列表上调用该函数。这是我们刚刚下载的图表的样子:
除了命名地点的字符串外,我们还可以下载距离给定地址一定距离内的所有街道的图表。接下来我们试试,把距离英国首相官邸唐宁街10号2公里范围内的所有道路都拉出
downing = ox.graph_from_address("10 Downing Street, London, UK", dist=2000)
这是图表的样子:
我们可以类似地使用多种类型的参数下载数据。有关所有可能选项的更多详细信息,请参阅osmnx.graph模块的文档。
type(downing)
networkx.classes.multidigraph.MultiDiGraph
另外,请注意,该图存储为NetworkX MultiDiGraph,因此您可以在调用单个函数后直接进入项目的网络分析部分。这是一个非凡的便利程度!
使用OSMnx绘制街道网络到目前为止,我只是向您展示了图表,而没有解释它们是如何制作的。现在让我们看看如何使用OSMnx绘制图形。值得庆幸的是,这就像一个函数调用一样简单:
fig, ax = ox.plot_graph(downing, node_size=2, node_color='r', edge_color='w', edge_linewidth=0.2)
谢天谢地,该ox.plot_graph函数的大多数参数都是不言自明的。让我们快速回顾一下:
- node_size让您指定图中节点的半径
- node_color让您指定图表中节点的颜色
- edge_color允许您指定图形中边缘的颜色
- edge_linewidth允许您指定表示图形中边缘的线条的宽度
重要的是要注意以下几点:
- 上面的“节点”是指两条或多条街道的交叉点。
- 上面的“边缘”是指连接两个(或更多)十字路口的一条街道。
- OSMnx在后台使用GeoPandas的绘图函数,这些函数本身基于Matplotlib。因此,您可以对生成的图像使用许多您习惯使用的Matplotlib操作。例如,fig.savefig("./my_network.png")会将上述可视化文件保存为当前目录中的PNG。
- 由于我们使用的是GeoPandas的绘图工具,您可以看到边缘(道路)以其适当的地理空间形状表示,而不是我们使用NetworkX来可视化图形时看到的直线。
OSMnx最好的事情之一是它非常适合现有的Python GIS生态系统,并且不会试图重新发明轮子。需要做图形分析吗?默认情况下,街道网络将转换为NetworkX图形,并准备好与该库一起使用。
需要以表格格式处理路网以进行更广泛的批量操作?GeoPandas的GeoDataFrame可助您一臂之力,在使用OSMnx时它是一等公民。将街道网络转换为表格格式就像使用OSMnx的一行代码一样简单,并将图拆分为两个数据帧,一个包含节点,一个包含边。
nodes, edges = ox.utils_graph.graph_to_gdfs(downing)
nodes.head()
y
x
street_count
highway
ref
geometry
osmid
101990
51.520573
-0.147701
4
NaN
NaN
POINT (-0.14770 51.52057)
101992
51.521395
-0.149695
4
NaN
NaN
POINT (-0.14970 51.52139)
101993
51.520316
-0.149225
4
NaN
NaN
POINT (-0.14923 51.52032)
101995
51.519974
-0.151786
3
NaN
NaN
POINT (-0.15179 51.51997)
101997
51.519093
-0.148652
4
NaN
NaN
POINT (-0.14865 51.51909)
以表格格式处理这些数据对于大型数据清理操作非常方便。上述节点数据框包含节点的经度和纬度(x和y列),而几何列包含Shapely几何形状,其中包含用于制图的所有相关GIS信息。
edges.iloc[:, :4].head()
osmid
oneway
name
highway
u
v
key
101990
330803151
0
17944925
True
Weymouth Street
tertiary
101998
0
532636970
True
Harley Street
tertiary
101992
1667118178
0
615056689
False
Devonshire Street
unclassified
101993
1685938630
0
17944925
True
Weymouth Street
tertiary
101992
0
4254943
True
Upper Wimpole Street
tertiary
u和v列分别表示边的源节点和目标节点。由于这是一个MultiDiGraph,我们可以拥有具有相同(u, v)值的平行边,这些边通过键来消除歧义。其余列包含有关边缘的各种其他信息,例如街道名称、道路类型等。边数据框还有一个几何列,其中包含有关边的相关GIS信息,但由于表格非常宽,此处将其截断。
然后,您可以使用我们知道并喜欢(有时甚至讨厌)的Pandas语法进行清理、过滤、分组和其他操作的选择,然后再次使用一行代码将网络转换回MultiDiGraph:
downing = ox.utils_graph.graph_from_gdfs(nodes, edges)
现在我们已经可视化了街道网络并在网络上执行了任意数量的任意数据操作,我们可以开始分析网络以解决我们最初的问题(例如路由或识别食物沙漠)。如前所述,OSMnx是一个位置非常优越的库,它不会尝试做其他包已经可以做的事情。
因此,鉴于对NetworkX图的本机支持,您很可能会将进一步的分析转移到NetworkX库及其专门为此目的设计的一系列优秀实用程序。但是,OSMnx确实带有一些用于分析网络的内置函数。让我们看一个使用该basic_stats函数检查连接到该网络中单个节点的平均街道数的快速示例。
ox.basic_stats(downing)['streets_per_node_avg']
2.8493639608309693
总之,OSMnx可以通过下载、清理、可视化街道数据并将其转换为可供分析的NetworkX图,从而显着简化街道网络分析问题的整个ETL过程。它只用几行代码就可以做到这一点,从而为您节省数小时甚至数天的设置时间。它还非常适合现有的Python生态系统,对用于数据操作的GeoPandas和用于网络分析的NetworkX提供了出色的支持,从而使Python中的街道网络分析尽可能易于访问且无摩擦。
本文最初以访客提交的形式出现在ContentLab上。
https://www.codeproject.com/Articles/5328791/Using-OSMnx-for-Graph-Analysis-of-Street-Networks