相关文章推荐
发财的青椒  ·  javascript - ...·  1 年前    · 
斯文的紫菜汤  ·  android - how to ...·  1 年前    · 

一、OSMnx

OSMnx,简称ox,是Python拓展包,OSMnx 建立在 GeoPandas、NetworkX 和 matplotlib 之上,并与 OpenStreetMap 的 API 交互,可用于:
1.下载街道网络(驾车/步行/骑行网络)或其他基础设施,并对其进行建模(方位和方向)。将地点边界、建筑物覆盖区或兴趣点下载为GeoDataFrame。
2.将网络另存为shapefile,geopackage和GraphML等格式;
3.计算和可视化最短路径,以最小化距离,旅行时间,海拔等。

官方文档地址
官方文档的大致介绍

1.该包的大致使用逻辑

目前我使用的这个包的功能逻辑包括下面这些:

  1. 路网下载,使用osmnx.graph module进行路网下载,并会自动帮助整理成networkx的格式,且依然保留经纬度信息。
  2. 投影转换,在进行节点的聚合或可视化过程中,都可能需要投影转换,这就用到了osmnx.projection module模块。
  3. 可视化,osmnx.plot module这个模块是进行拓扑可视化,但是没有地图,osmnx.folium module这个模块是借助folium进行可视化,有地图底图。
  4. 进行拓扑简化处理,osmnx.simplification module主要进行路网拓扑简化,比如进行节点聚合。
  5. 一些其他的基于拓扑的分析,目前使用到的主要是osmnx.distance module,主要是用来计算关于距离的一些拓扑特性或关系。
  6. 其他的一些模块目前还没用到,比如进行特定路网区域选取等等,官方文档写的也比较清楚了。

二、使用方法

1.引入库并下载路网

这里下载萧山区范围的路网作为实例
代码如下:

# 爬取萧山的路网拓扑结果并形成networkx的数据结构
import osmnx as ox
G = ox.graph_from_bbox(30.255904285611525,30.141649815003344,120.2972282472983, 120.2239798312058, network_type='drive')
# 形成路网图
G = ox.projection.project_graph(G)
plt.rcParams['figure.dpi'] = 400
fig=plt.figure(figsize=(10,6)) #设置画布大小
ax = plt.gca()
ox.plot.plot_graph(G,ax=ax,figsize=(8*4),bgcolor='white',node_color='blue',edge_color='grey',show=True,edge_linewidth=0.3,node_size=5,node_alpha=0.5)
# 以openstreetmap底图为背景绘图
G_84 = ox.projection.project_graph(G , to_crs='EPSG:4326')
ox.folium.plot_graph_folium(G_84, tiles='openstreetmap',kwargs={'width':0.1})

在这里插入图片描述
局部放大图
在这里插入图片描述
OSMnx中的道路类型分为未分隔道路与双向分隔道路(divided roads)。一条双向分隔道路(divided road)与另一条双向分隔道路(divided road)的交叉点将会创建4 个节点。如果要将同一个交叉口的所有节点合并,可用以下代码实现,这里需要注意一点,在进行合并时,一个比较重要的参数是tolerance,这个也就是说对将这个范围内的node进行合并,因此在进行这一步之前需要进行投影变换,变换为单位为m的投影,也就是墨卡托投影,G = ox.projection.project_graph(G),这行代码就是实现这个效果,没有设置转化为什么投影就默认是到墨卡托投影,墨卡托投影就是以m为单位:

# 将同一个交叉口的所有nodes合并
G = ox.simplification.consolidate_intersections(G,tolerance=25, rebuild_graph=True, dead_ends=False, reconnect_edges=True)

合并后的局部放大图
在这里插入图片描述
此局部放大图中,建设一路与市心北路交叉口由原来的四个节点合并为四个节点质心处的一个节点,reconnect_edges参数为True时,可以根据新节点重建拓扑。在合并之后的shp文件中,原来的四个节点也会减少为一个节点。
在这里插入图片描述

2.进行节点映射

这个是实现了这样一个需求,也就是已经知道了一系列电警,要把这些电警和交叉口联结起来,联系匹配的方式是根据距离,将电警和距离它距离最小的交叉口联结起来,因此要实现这个就需要得到每个电警与距离它最近的交叉口的编号。要实现这样一个功能,只需要一行代码,调用下下面的函数就行了。
在这里插入图片描述

三、实操案例和代码获取

我们的这篇论文是用这个包来爬取路网并做复杂网络分析的,并且已经开源源代码,需要的同学可以自取。用了相应的方法和代码可以考虑引用哦

OSMnx工具箱,该工具箱可从OpenStreetMap自动下载,建模和可视化空间数据。可以通过该工具可视化方法(括地物图和极坐标直方图)以计算方式探索世界各地街道网络和建筑物中的模式和配置,这些方法有助于将城市复杂性压缩成可理解的人工产物,以反映人类对建筑环境的体验。无处不在的城市数据和计算可以从定量和定性的角度开辟新的城市形态分析。(参考:https://geoffboeing.com/) 二、安装osmnx ​conda install -c conda-forge osmnx
官方解释: OSMnx是一个Python软件,支持从OpenStreetMap下载地理空间数据,并对现实世界的街道网络和任何其他地理空间几何图形进行建模、投影、可视化和分析。通过一行代码即可下载城市网络(walkable, drivable, or bikeable urban networks)并对齐建模,然后轻松进行分析和可视化;也可以轻松下载并使用其他基础设施类型(设施/兴趣点、建筑物占地面积、高度数据、街道方位/方向、速度/行驶时间)。 若使用osmnx,别忘了引用以下文章哦: Boeing,
一个关于用户运动轨迹的项目,接触到OSM及OSMnx。 OSM是Open Street Map开源地图数据库,Geoff Boeing的博客提供了OSMnx的PythonOSMnx,简称ox。其中主要分为两种地图模型,一种是区块数据(gdf_from_place),另外一种是道路模型(graph_from_place)。
之前在openstreetmap下载了杭州的路网结构,但是吧,文件打开了真的一时不知道怎么处理。恰好看到了osmnx的python,但是这个吧,真的是有点让人头大。必须写个博客排雷。 我安装了python3.7,也装了anaconda3。为了方便之后的处理,所以用的anaconda3的环境中装的osmnx。安装操作很简单。 conda install -c conda-forge o...
无论您是想找到从A地到B地的最佳路线,还是试图分析社区进入超市的情况以识别食物沙漠,以网络的形式构建问题,以街道为边缘,通常都是最简单和最容易解决的方法。 但是,在开始构建街道网络之前,您需要数据。谷歌地图可能是大多数人想到地理信息时的首选,但遗憾的是它的API不是免费的。值得庆幸的是,有一个免费的开源替代方案,其中含许多相同的数据:OpenStreetMaps(OSM)项目。
- 项目用的mapbox-gl+echarts的前端展示,mapbox-gl数据源为osm在线地图。 - 但是需要部署在内网(mapbox和地图服务),则无法使用在线地图,第一方案是下载osm的瓦片到本地用tomcat部署 - 使用Maperitive下载地图瓦片,但是在线的地图用此工具下载瓦片很慢,于是解决方案就是使用Maperitive所提供的加载osm的地图数据
使用 OSMnx 进行地图分析时,可以通过以下步骤访问节点: 1. 使用 `ox.graph_from_place` 或 `ox.graph_from_address` 函数获取地图的图形数据。 2. 使用 `ox.plot_graph` 函数将图形数据可视化,以便更好地理解图形。 3. 使用 `G.nodes` 属性获取地图上的所有节点。这将返回一个字典,其中键是节点的 ID,值是一个字典,含节点的经度、纬度和其他属性。 4. 使用节点 ID 访问特定节点的属性。例如,可以使用 `G.nodes[node_id]['x']` 和 `G.nodes[node_id]['y']` 访问节点的经度和纬度。 下面是一个示例代码,用于获取地图上的所有节点并输出前 10 个节点的经度和纬度: ```python import osmnx as ox # 获取地图的图形数据 G = ox.graph_from_place('Piedmont, California, USA', network_type='drive') # 可视化地图 ox.plot_graph(G) # 获取所有节点 nodes = G.nodes # 输出前10个节点的经度和纬度 for node_id in list(nodes)[:10]: print("Node ID: ", node_id) print("Longitude: ", nodes[node_id]['x']) print("Latitude: ", nodes[node_id]['y']) 注意:在访问节点属性时,请确保节点 ID 存在于节点字典中。