BikeDNA(八)外在分析:OSM 与参考数据的比较2

BikeDNA(八)外在分析:OSM 与参考数据的比较2

1.数据完整性

见链接

2.网络拓扑结构

见链接

3.网络组件

本节仔细研究两个数据集的网络组件特征。

断开连接的组件不共享任何元素(节点/边)。 换句话说,不存在可以从一个断开连接的组件通向另一组件的网络路径。 如上所述,大多数现实世界的自行车基础设施网络确实由许多断开连接的组件组成(Natera Orozco et al., 2020) 。 然而,当两个断开的组件彼此非常接近时,这可能是边缘缺失或另一个数字化错误的迹象。

方法

为了比较 OSM 和参考数据中断开组件的数量和模式,将内在分析的所有组件结果并置,并生成两个新图,分别显示 OSM 和参考数据的组件间隙以及组件连接性的差异。

解释

许多自行车网络的分散性使得很难评估断开的组件是否是由于缺乏数据质量或缺乏正确连接的自行车基础设施而导致的问题。 比较两个数据集中的断开组件可以更准确地评估断开组件是数据问题还是规划问题。


3.1 断开的组件

print(
    f"The OSM network in the study area consists of {osm_intrinsic_results['component_analysis']['component_count']} disconnected components."
)
print(
    f"The {reference_name} network in the study area consists of {ref_intrinsic_results['component_analysis']['component_count']} disconnected components."
)
The OSM network in the study area consists of 356 disconnected components.
The GeoDanmark network in the study area consists of 204 disconnected components.
plot_func.plot_saved_maps(
    [
        osm_results_static_maps_fp + "all_components_osm",
        ref_results_static_maps_fp + "all_components_reference",
    ]
)

在这里插入图片描述

3.2 组件长度分布

所有网络组件长度的分布可以在所谓的 Zipf 图 中可视化,该图按等级对每个组件的长度进行排序,在左侧显示最大组件的长度,然后是第二大组件的长度,依此类推,直到 右侧最小组件的长度。 当 Zipf 图遵循 双对数比例 中的直线时,这意味着找到小的不连续组件的机会比传统分布的预期要高得多 (Clauset et al., 2009)。 这可能意味着网络没有合并,只有分段或随机添加 (Szell et al., 2022),或者数据本身存在许多间隙和拓扑错误,导致小的断开组件。

但是,也可能发生最大的连通分量(图中最左边的标记,等级为 1 0 0 10^0 100)是明显的异常值,而图的其余部分则遵循不同的形状。 这可能意味着在基础设施层面,大部分基础设施已连接到一个大型组件,并且数据反映了这一点 - 即数据在很大程度上没有受到间隙和缺失链接的影响。 自行车网络也可能介于两者之间,有几个大型组件作为异常值。

在对同一区域进行比较时,如下所示,如果一个数据集在其最大连通分量中显示出明显的异常值,而另一个数据集则没有,并且如果它也至少同样大,则通常可以解释为 更加完整。

plot_func.plot_saved_maps(
    [
        osm_results_plots_fp + "component_length_distribution_osm",
        ref_results_plots_fp + "component_length_distribution_reference",
    ],
    figsize=pdict["fsmap"]
)

在这里插入图片描述

3.3 最大连通分量

# Read largest cc
osm_largest_cc = gpd.read_file(osm_results_data_fp + "largest_connected_component.gpkg")
ref_largest_cc = gpd.read_file(ref_results_data_fp + "largest_connected_component.gpkg")

print(
    f"The largest connected component in the OSM network contains {osm_intrinsic_results['component_analysis']['largest_cc_pct_size']:.2f}% of the network length."
)
print(
    f"The largest connected component in the {reference_name} network contains {ref_intrinsic_results['component_analysis']['largest_cc_pct_size']:.2f}% of the network length."
)
The largest connected component in the OSM network contains 91.47% of the network length.
The largest connected component in the GeoDanmark network contains 80.04% of the network length.
plot_func.plot_saved_maps(
    [
        osm_results_static_maps_fp + "largest_conn_comp_osm",
        ref_results_static_maps_fp + "largest_conn_comp_reference",
    ]
)

在这里插入图片描述

OSM 和参考网络中最大连接组件的叠加

# Plot

set_renderer(renderer_map)
fig, ax = plt.subplots(1, figsize=pdict["fsmap"])

osm_largest_cc.plot(ax=ax, linewidth=3.5, color=pdict["osm_base"], label="OSM")
ref_largest_cc.plot(ax=ax, linewidth=1.25, color=pdict["ref_base"], label=reference_name)

ax.set_title(f" {area_name}: largest connected components")
ax.set_axis_off()
ax.legend()
cx.add_basemap(ax=ax, crs=study_crs, source=cx_tile_2)

plot_func.save_fig(fig, compare_results_static_maps_fp + "largest_cc_overlay_compare")

在这里插入图片描述

# Plot again for potential report titlepage

set_renderer(renderer_map)
fig, ax = plt.subplots(1, figsize=pdict["fsmap"])

osm_largest_cc.plot(ax=ax, linewidth=3, color=pdict["osm_base"], label="OSM")
ref_largest_cc.plot(ax=ax, linewidth=1, color=pdict["ref_base"], label=reference_name)
ax.set_axis_off()

plot_func.save_fig(fig, compare_results_static_maps_fp + "titleimage",plot_res="high")
plt.close()

3.4 缺少链接

在组件之间潜在缺失链接的图中,将绘制与另一个组件上的边的指定距离内的所有边。 断开的边缘之间的间隙用标记突出显示。 因此,该地图突出显示了边缘,尽管这些边缘彼此非常接近,但它们是断开连接的,因此不可能在边缘之间的自行车基础设施上骑自行车。

# DEFINE MAX BUFFER DISTANCE BETWEEN COMPONENTS CONSIDERED A GAP/MISSING LINK
component_min_distance = 10

assert isinstance(component_min_distance, int) or isinstance(
    component_min_distance, float
), print("Setting must be integer or float value!")
# Read results with component gaps

osm_cg_edge_ids = pd.read_csv(
    osm_results_data_fp + f"component_gaps_edges_{component_min_distance}.csv"
)["edge_id"].to_list()
osm_component_gaps_edges = osm_edges_simplified.loc[
    osm_edges_simplified.edge_id.isin(osm_cg_edge_ids)
]

ref_cg_edge_ids = pd.read_csv(
    ref_results_data_fp + f"component_gaps_edges_{component_min_distance}.csv"
)["edge_id"].to_list()
ref_component_gaps_edges = ref_edges_simplified.loc[
    ref_edges_simplified.edge_id.isin(ref_cg_edge_ids)
]

osm_component_gaps = gpd.read_file(
    osm_results_data_fp + f"component_gaps_centroids_{component_min_distance}.gpkg"
)
ref_component_gaps = gpd.read_file(
    ref_results_data_fp + f"component_gaps_centroids_{component_min_distance}.gpkg"
)
# Interactive plot of adjacent components

feature_groups = []

if len(osm_component_gaps_edges) > 0:

    # Feature groups for OSM
    osm_edges_simplified_folium = plot_func.make_edgefeaturegroup(
        gdf=osm_edges_simplified,
        mycolor=pdict["osm_base"],
        myweight=pdict["line_base"],
        nametag="OSM network",
        show_edges=True,
    )

    osm_component_gaps_edges_folium = plot_func.make_edgefeaturegroup(
        gdf=osm_component_gaps_edges,
        mycolor=pdict["osm_emp"],
        myweight=pdict["line_emp"],
        nametag="OSM: Adjacent disconnected edges",
        show_edges=True,
    )

    osm_component_gaps_folium = plot_func.make_markerfeaturegroup(
        gdf=osm_component_gaps, nametag="OSM: Component gaps", show_markers=True
    )

    feature_groups.extend(
        [
            osm_edges_simplified_folium,
            osm_component_gaps_edges_folium,
            osm_component_gaps_folium,
        ]
    )

# Feature groups for reference
if len(ref_component_gaps_edges) > 0:

    ref_edges_simplified_folium = plot_func.make_edgefeaturegroup(
        gdf=ref_edges_simplified,
        mycolor=pdict["ref_base"],
        myweight=pdict["line_base"],
        nametag=f"{reference_name} network",
        show_edges=True,
    )

    ref_component_gaps_edges_folium = plot_func.make_edgefeaturegroup(
        gdf=ref_component_gaps_edges,
        mycolor=pdict["ref_emp"],
        myweight=pdict["line_emp"],
        nametag=f"{reference_name}: Adjacent disconnected edges",
        show_edges=True,
    )

    ref_component_gaps_folium = plot_func.make_markerfeaturegroup(
        gdf=ref_component_gaps, nametag=f"{reference_name}: Component gaps", show_markers=True
    )

    feature_groups.extend(
        [
            ref_edges_simplified_folium,
            ref_component_gaps_edges_folium,
            ref_component_gaps_folium,
        ]
    )

m = plot_func.make_foliumplot(
    feature_groups=feature_groups,
    layers_dict=folium_layers,
    center_gdf=osm_nodes_simplified,
    center_crs=osm_nodes_simplified.crs,
)

bounds = plot_func.compute_folium_bounds(osm_nodes_simplified)
m.fit_bounds(bounds)
m.save(compare_results_inter_maps_fp + "component_gaps_compare.html")

display(m)

在这里插入图片描述

print("Interactive map saved at " + compare_results_inter_maps_fp.lstrip("../") + "component_gaps_compare.html")
Interactive map saved at results/COMPARE/cph_geodk/maps_interactive/component_gaps_compare.html

3.5 每个网格单元的组件

下图显示了与网格单元相交的组件数量。 网格单元中的组件数量过多通常表明网络连接较差 - 要么是由于基础设施分散,要么是因为数据质量问题。

plot_func.plot_saved_maps(
    [
        osm_results_static_maps_fp + "number_of_components_in_grid_cells_osm",
        ref_results_static_maps_fp + "number_of_components_in_grid_cells_reference",
    ]
)

在这里插入图片描述

3.6 组件连接

在这里,我们可视化每个单元格可以到达的单元格数量之间的差异。 该指标是网络连接性的粗略衡量标准,但具有计算成本低的优点,因此能够快速突出网络连接性的明显差异。

在显示到达的细胞百分比差异的图中,正值表示使用参考数据集的连接性较高,而负值表示可以从 OSM 数据中的特定细胞到达更多的细胞。

plot_func.plot_saved_maps(
    [
        osm_results_static_maps_fp + "percent_cells_reachable_grid_osm",
        ref_results_static_maps_fp + "percent_cells_reachable_grid_reference",
    ]
)

在这里插入图片描述

# Compute difference in cell reach percentage (where data for both OSM and REF is available)

grid["cell_reach_pct_diff"] = (
    grid["cells_reached_ref_pct"] - grid["cells_reached_osm_pct"]
)
# Plot

set_renderer(renderer_map)

# norm color bar
cbnorm_diff = colors.Normalize(vmin=-100, vmax=100)

fig, ax = plt.subplots(1, figsize=pdict["fsmap"])
from mpl_toolkits.axes_grid1 import make_axes_locatable
divider = make_axes_locatable(ax)
cax = divider.append_axes("right", size="3.5%", pad="1%")

grid.plot(
    cax=cax,
    ax=ax,
    alpha=pdict["alpha_grid"],
    column="cell_reach_pct_diff",
    cmap=pdict["diff"],
    legend=True,
    norm=cbnorm_diff,
)

# Add no data patches
grid[grid["cell_reach_pct_diff"].isnull()].plot(
    cax=cax,
    ax=ax,
    facecolor=pdict["nodata_face"],
    edgecolor=pdict["nodata_edge"],
    linewidth= pdict["line_nodata"],
    hatch=pdict["nodata_hatch"],
    alpha=pdict["alpha_nodata"],
)

# osm_edges_simplified.plot(ax=ax, color=pdict["osm_base"], alpha=1,linewidth=2)
# ref_edges_simplified.plot(ax=ax, color=pdict["ref_base"], alpha=1,linewidth=1)

ax.legend(handles=[nodata_patch], loc="upper right")

ax.set_title(
    f"{area_name}: {reference_name} difference to OSM in percent of cells reached"
)
ax.set_axis_off()
cx.add_basemap(ax=ax, crs=study_crs, source=cx_tile_2)

plot_func.save_fig(fig, compare_results_static_maps_fp + "percent_cell_reached_diff_compare")

在这里插入图片描述

4.概括

# Load results from intrinsic
osm_intrinsic_df = pd.read_csv(
    osm_results_data_fp + "intrinsic_summary_results.csv",
    index_col=0,
    names=["OSM"],
    header=0,
)

ref_intrinsic_df = pd.read_csv(
    ref_results_data_fp + "intrinsic_summary_results.csv",
    index_col=0,
    names=[reference_name],
    header=0,
)

# Drop rows from OSM results not available for reference
osm_intrinsic_df.drop(
    ["Incompatible tag combinations", "Missing intersection nodes"],
    axis=0,
    inplace=True,
)

# Save new results
osm_intrinsic_df.at["Alpha", "OSM"] = osm_alpha
osm_intrinsic_df.at["Beta", "OSM"] = osm_beta
osm_intrinsic_df.at["Gamma", "OSM"] = osm_gamma

ref_intrinsic_df.at["Alpha", reference_name] = ref_alpha
ref_intrinsic_df.at["Beta", reference_name] = ref_beta
ref_intrinsic_df.at["Gamma", reference_name] = ref_gamma

# Combine
extrinsic_df = osm_intrinsic_df.join(ref_intrinsic_df)
assert len(extrinsic_df) == len(osm_intrinsic_df) == len(ref_intrinsic_df)
extrinsic_df.style.pipe(format_extrinsic_style)
Extrinsic Quality Comparison
 OSMGeoDanmark
Total infrastructure length (km)1,056626
Protected bicycle infrastructure density (m/km2)5,3422,999
Unprotected bicycle infrastructure density (m/km2)427455
Mixed protection bicycle infrastructure density (m/km2)550
Bicycle infrastructure density (m/km2)5,8253,454
Nodes5,0164,125
Dangling nodes1,828870
Nodes per km22823
Dangling nodes per km2105
Overshoots821
Undershoots1811
Components356204
Length of largest component (km)747501
Largest component's share of network length91%80%
Component gaps7852
Alpha0.110.10
Beta1.151.14
Gamma0.380.38

5.保存结果

extrinsic_df.to_csv(
    compare_results_data_fp + "extrinsic_summary_results.csv", index=True
)

with open(
    compare_results_data_fp + f"grid_results_extrinsic.pickle", "wb"
) as f:
    pickle.dump(grid, f)

from time import strftime
print("Time of analysis: " + strftime("%a, %d %b %Y %H:%M:%S"))
Time of analysis: Mon, 18 Dec 2023 20:25:24

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/316306.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MES生产执行系统在生产车间的主要作用

MES生产执行系统提供从生产订单下达到产品完成全流程的优化管理。实现现场设备、执行系统及管理系统的集成,实时监控生产管理各项绩效指标。 如果说ERP是上层决策,生产车间是下层执行,那么MES就是连接管理软件和一线生产的中间桥梁。 MES也…

c++静态数据成员

目录 静态成员变量 1. 问:这是为什么呢? (以下结束均为个人理解,如有问题,请指教) 2. 使用场景(举一个例子) 代码中需要注意的点: 3.总结: 静态成员函数 使用场景: 静态成员函数中没有…

大模型核心技术原理: Transformer架构详解

在大模型发展历程中,有两个比较重要点:第一,Transformer 架构。它是模型的底座,但 Transformer 不等于大模型,但大模型的架构可以基于 Transformer;第二,GPT。严格意义上讲,GPT 可能…

Linux 内核如何根据设备树文件来匹配内核

一. 简介 上一篇文章学习了 Linux内核如何确定是否支持此设备,如果支持,设备就会启动 Linux 内核。 文章地址如下: 设备树根节点下的compatile属性的作用-CSDN博客 本文继上面文章的学习。这里简单看一下, Linux 内核是如何根…

odoo17 | 模型之间的交互

前言 在前一章中,我们使用继承来修改模块的行为。在我们的房地产场景中,我们希望更进一步,能够为我们的客户生成发票。Odoo提供了一个发票(Invoicing)模块,所以直接从我们的房地产模块创建一个发票会很简洁…

VS报错:error:LNK2005 _main 已经在 *.obj 中定义

应该是重定义了,但是又解决不了,看似又没有重定义啊,就在一个文件定义了啊?怎么会出现这种情况呢?关键是,编译报错,程序运行不了了。 这里提一下我的前期操作,是因为将一个头文件和…

图像监视:在 Visual Studio 调试器中查看内存中图像

先决条件 本教程假定您具有以下可用项: 安装了 Update 1 的 Visual Studio 2012 Professional(或更高版本)。更新 1 可在此处下载。在 Windows 计算机上安装 OpenCV(教程:在 Windows 中安装)。能够在 Visua…

【Spring 篇】深入探索:Spring集成Web环境的奇妙世界

嗨,亲爱的小白们!欢迎来到这篇有关Spring集成Web环境的博客。如果你曾对如何在Spring中构建强大的Web应用程序感到好奇,那么这里将为你揭示Web开发的神秘面纱。我们将用情感丰富、语句通顺的文字,以小白友好的方式,一探…

survey和surveyCV:如何用R语言进行复杂抽样设计、权重计算和10折交叉验证?

一、引言 在实际调查和研究中,我们往往面临着样本选择的复杂性。复杂抽样设计能够更好地反映真实情况,提高数据的代表性和可靠性。例如,多阶段抽样可以有效地解决大规模调查的问题,整群抽样能够在保证样本的随机性的同时减少资源消…

D25XB100-ASEMI家用电器整流桥D25XB100

编辑:ll D25XB100-ASEMI家用电器整流桥D25XB100 型号:D25XB100 品牌:ASEMI 封装:GBJ-5(带康铜丝) 平均正向整流电流(Id):25A 最大反向击穿电压(VRM&…

thinkphp递归实现无限级子分类合并上级children

//设别分类列表public function getCategoryList(){$list = Db::name(categorys)->select(

玩转Mysql 七 (索引的创建与设计原则)

一、索引的创建与使用 1、索引的分类 MySQL的索引包括普通索引、唯一性索引、全文索引、单列索引、多列索引和空间索引等。 (1)从 功能逻辑 上说,索引主要有 4 种,分别是普通索引、唯一索引、主键索引、全文索引。 (…

20_GC垃圾回收机制

文章目录 GC如何确定垃圾如何回收垃圾回收垃圾的时机 GC 如何确定垃圾 引用计数算法 给对象添加一个引用计数器,每当一个地方引用它时,计数器加1,每当引用失效时,计数器减少1,当计数器的数值为0时,也就是对…

Django教程|数据统计图表(echarts、highchart)

前言 highchart,国外。 echarts,国内。 本项目集成 hightchart和echarts图表库实现数据统计功能。 包括:折线图,柱状图,饼图和数据集图。 效果图 echats Highcharts 源代码 编写模板(Template&#x…

Docker安装Atlassian全家桶

文章目录 省流:1.docker-compose文件2.其他服务都正常启动,唯独Bitbucket不行。日志错误刚启动时候重启后查询分析原因再针对第一点排查看样子是安装的bitbucket和系统环境有冲突问题? 结论: 省流: bitbucket 只能安装…

idea使用ssh连接docker,并通过Dockerfile文件,直接在idea中启动docker应用,并进行远程debug

idea使用ssh连接docker,并通过Dockerfile文件,直接在idea中启动docker应用,并进行远程debug 第一步: idea通过ssh连接docker第二步:使用Dockerfile文件在远程启动应用第三步: 远程debug 容器运行的好处是减轻本地运行的负担(本地电…

数据结构初探:揭开数据结构奥秘

🌈个人主页:聆风吟 🔥系列专栏:数据结构、算法模板、汇编语言 🔖少年有梦不应止于心动,更要付诸行动。 文章目录 📋前言一. 数组结构起源二. 基本概念和术语2.1 数据2.2 数据元素2.3 数据项2.4 …

Rust-语句和表达式

if-else Rust中if-else表达式的作用是实现条件分支。if-else表达式的构成方式为:以if关键字开头,后面跟上条件表达式,后续是结果语句块,最后是可选的else块。条件表达式的类型必须是bool。 if-else结构还可以当表达式使用 loop …

苹果手机怎么恢复备份?详细攻略为你整理好了!

随着智能手机和互联网的普及,手机中存储的个人信息、照片、视频、聊天记录等数据会变得越来越多。一旦手机丢失、损坏或系统出现问题,我们很可能会面临数据丢失的风险。因此,越来越多的人开始意识到保护手机数据的重要性。 当苹果手机数据丢…

Mnajora 使用deb包安装软件

说明 Mnajora 安装deb软件包主要有两种方式 可以使用dpkg 直接安装也可是使用debtap将deb软件包转换成 使用dpkg sudo pacman -S dpkg #安装dpkgsudo dpkg -i ###.deb #使用dpkg安装deb软件包和在ubuntu上是一样的 安装成功 使用debtap debtap是一个用于将.deb包转换为A…