淘寶美工與網(wǎng)站開(kāi)發(fā)搜索引擎優(yōu)化seo論文
BikeDNA(七)外在分析:OSM 與參考數(shù)據(jù)的比較1
該筆記本將提供的參考自行車(chē)基礎(chǔ)設(shè)施數(shù)據(jù)集與同一區(qū)域的 OSM 數(shù)據(jù)進(jìn)行所謂的外部質(zhì)量評(píng)估進(jìn)行比較。 為了運(yùn)行這部分分析,必須有一個(gè)參考數(shù)據(jù)集可用于比較。
該分析基于將參考數(shù)據(jù)集與 OSM 進(jìn)行比較,并突出顯示它們的不同之處,包括自行車(chē)基礎(chǔ)設(shè)施在兩個(gè)數(shù)據(jù)集中映射的“程度”以及基礎(chǔ)設(shè)施“如何”映射,從而查明差異 在網(wǎng)絡(luò)結(jié)構(gòu)中。
所有差異都是針對(duì)與 OSM 相關(guān)的參考數(shù)據(jù)計(jì)算的,以 OSM 數(shù)據(jù)為基線。 例如,網(wǎng)絡(luò)密度的差異是通過(guò)計(jì)算參考密度減去 OSM 密度來(lái)計(jì)算的。 因此,正差值(大于0)表示參考值高出多少; 負(fù)差值(低于 0)表示參考值低了多少。 因此,如果差異以百分比形式給出,則 OSM 值將被視為總值 (100%)。
雖然分析是基于比較,但它沒(méi)有對(duì)哪個(gè)數(shù)據(jù)集更好做出先驗(yàn)假設(shè)。 對(duì)于識(shí)別出的差異也是如此:BikeDNA 不允許自動(dòng)得出哪個(gè)數(shù)據(jù)集質(zhì)量更好的結(jié)論,而是要求用戶解釋發(fā)現(xiàn)的差異的含義,例如,不同的特征是否是遺漏錯(cuò)誤的結(jié)果 或傭金,以及哪個(gè)數(shù)據(jù)集更正確。 然而,許多低值可能表明參考數(shù)據(jù)的完整性低于 OSM 數(shù)據(jù)。
目標(biāo)是確定的差異可用于評(píng)估參考數(shù)據(jù)集和 OSM 數(shù)據(jù)集的質(zhì)量,并支持決定應(yīng)使用哪個(gè)數(shù)據(jù)集進(jìn)行進(jìn)一步分析。
外部比較幾乎完全基于筆記本 2a 和 2b 的結(jié)果,并期望使用先前筆記本中使用的文件路徑來(lái)存儲(chǔ)結(jié)果和繪圖。 筆記本 1a、2a、1b 和 2b 必須成功運(yùn)行才能使用此筆記本。 應(yīng)用概念和指標(biāo)的詳細(xì)解釋可以在內(nèi)在分析筆記本(2a 和 2b)中找到。
為了正確解釋一些空間數(shù)據(jù)質(zhì)量指標(biāo),需要對(duì)該區(qū)域有一定的了解。
# Load libraries, settings and dataimport json
import pickle
import warnings
from collections import Counterimport contextily as cx
import folium
import geopandas as gpd
import matplotlib as mpl
import matplotlib.colors as colors
import matplotlib.pyplot as plt
import numpy as np
import osmnx as ox
import pandas as pd
import yaml
from matplotlib import cm
from collections import Counterfrom src import evaluation_functions as eval_func
from src import graph_functions as graph_func
from src import plotting_functions as plot_func# Read in dictionaries with settings
%run ../settings/yaml_variables.py
%run ../settings/plotting.py
%run ../settings/tiledict.py
%run ../settings/df_styler.py# Load data
%run ../settings/load_osmdata.py
%run ../settings/load_refdata.py
%run ../settings/load_results.pywarnings.filterwarnings("ignore")
d:\work\miniconda3\envs\bikeDNA\Lib\site-packages\tqdm\auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.htmlfrom .autonotebook import tqdm as notebook_tqdm
D:\tmp_resource\BikeDNA-main\BikeDNA-main\scripts\settings\plotting.py:49: MatplotlibDeprecationWarning: The get_cmap function was deprecated in Matplotlib 3.7 and will be removed two minor releases later. Use ``matplotlib.colormaps[name]`` or ``matplotlib.colormaps.get_cmap(obj)`` instead.cmap = cm.get_cmap(cmap_name, n)
D:\tmp_resource\BikeDNA-main\BikeDNA-main\scripts\settings\plotting.py:46: MatplotlibDeprecationWarning: The get_cmap function was deprecated in Matplotlib 3.7 and will be removed two minor releases later. Use ``matplotlib.colormaps[name]`` or ``matplotlib.colormaps.get_cmap(obj)`` instead.cmap = cm.get_cmap(cmap_name)
<string>:49: MatplotlibDeprecationWarning: The get_cmap function was deprecated in Matplotlib 3.7 and will be removed two minor releases later. Use ``matplotlib.colormaps[name]`` or ``matplotlib.colormaps.get_cmap(obj)`` instead.
<string>:46: MatplotlibDeprecationWarning: The get_cmap function was deprecated in Matplotlib 3.7 and will be removed two minor releases later. Use ``matplotlib.colormaps[name]`` or ``matplotlib.colormaps.get_cmap(obj)`` instead.OSM graphs loaded successfully!
OSM data loaded successfully!
Reference graphs loaded successfully!
Reference data loaded successfully!
Results from intrinsic analyses loaded successfully!
OSM versus reference network
plot_func.plot_saved_maps([osm_results_static_maps_fp + "area_network_osm",ref_results_static_maps_fp + "area_network_reference",]
)
1.數(shù)據(jù)完整性
本節(jié)從數(shù)據(jù)完整性方面比較 OSM 和參考數(shù)據(jù)集。 目標(biāo)是確定一個(gè)數(shù)據(jù)集是否比另一個(gè)數(shù)據(jù)集映射了更多的自行車(chē)基礎(chǔ)設(shè)施,如果是,這些差異是否集中在某些區(qū)域。
本節(jié)首先比較兩個(gè)數(shù)據(jù)集中基礎(chǔ)設(shè)施的總長(zhǎng)度。 然后,首先在全局(研究區(qū)域)和局部(網(wǎng)格單元)級(jí)別比較基礎(chǔ)設(shè)施、節(jié)點(diǎn)和懸空節(jié)點(diǎn)密度(即每平方公里基礎(chǔ)設(shè)施/節(jié)點(diǎn)的長(zhǎng)度)。 最后,分別比較受保護(hù)和未受保護(hù)的自行車(chē)基礎(chǔ)設(shè)施的密度差異。
計(jì)算網(wǎng)格局部密度差異作為數(shù)據(jù)質(zhì)量的度量也已被例如應(yīng)用。 Haklay (2010)。
方法
為了考慮自行車(chē)基礎(chǔ)設(shè)施映射方式的差異,網(wǎng)絡(luò)長(zhǎng)度和密度的計(jì)算基于基礎(chǔ)設(shè)施長(zhǎng)度,而不是網(wǎng)絡(luò)邊緣的幾何長(zhǎng)度。 例如,一條 100 米長(zhǎng)的雙向路徑(幾何長(zhǎng)度:100m)貢獻(xiàn)了 200 米的自行車(chē)基礎(chǔ)設(shè)施(基礎(chǔ)設(shè)施長(zhǎng)度:200m)。
解釋
密度差異可能表明數(shù)據(jù)不完整。 例如,如果網(wǎng)格單元在 OSM 中的邊緣密度明顯高于參考數(shù)據(jù)集中的邊緣密度,則這可能表明參考數(shù)據(jù)集中未映射、缺失的特征,或者街道在 OSM 中被錯(cuò)誤地標(biāo)記為自行車(chē)基礎(chǔ)設(shè)施。
1.1 網(wǎng)絡(luò)長(zhǎng)度
plot_func.compare_print_network_length(osm_edges_simplified.infrastructure_length.sum(),ref_edges_simplified.infrastructure_length.sum(),
)
Length of the OSM data set: 1056.49 km
Length of the reference data set: 626.48 kmThe reference data set is 430.01 km shorter than the OSM data set.
The reference data set is 40.70% shorter than the OSM data set.
# Plot length comparisonset_renderer(renderer_plot)bar_labels = ["OSM", reference_name]
x_positions = [1, 2]
bar_colors = [pdict["osm_base"], pdict["ref_base"]]# Infrastructure length density
data = [osm_edges_simplified.infrastructure_length.sum()/1000,ref_edges_simplified.infrastructure_length.sum()/1000]
y_label = "Network edge lengths [km]"
filepath = compare_results_plots_fp + "network_length_compare"
title = area_nameplot = plot_func.make_bar_plot(data=data,bar_labels=bar_labels,y_label=y_label,x_positions=x_positions,title=title,bar_colors=bar_colors,filepath=filepath,figsize=pdict["fsbar_small"]
)
1.2 網(wǎng)絡(luò)密度
全球網(wǎng)絡(luò)密度
plot_func.print_network_densities(osm_intrinsic_results, "OSM")
plot_func.print_network_densities(ref_intrinsic_results, "reference")
In the OSM data, there are:- 5824.58 meters of cycling infrastructure per km2.- 27.65 nodes in the cycling network per km2.- 10.08 dangling nodes in the cycling network per km2.In the reference data, there are:- 3453.85 meters of cycling infrastructure per km2.- 22.74 nodes in the cycling network per km2.- 4.80 dangling nodes in the cycling network per km2.
全球網(wǎng)絡(luò)密度(每平方公里)
# Plot global differenceset_renderer(renderer_plot)# Infrastructure length density
subplotdata = [(osm_intrinsic_results["network_density"]["edge_density_m_sqkm"],ref_intrinsic_results["network_density"]["edge_density_m_sqkm"],),(osm_intrinsic_results["network_density"]["node_density_count_sqkm"],ref_intrinsic_results["network_density"]["node_density_count_sqkm"],),(osm_intrinsic_results["network_density"]["dangling_node_density_count_sqkm"],ref_intrinsic_results["network_density"]["dangling_node_density_count_sqkm"],),
]
subplotx_positions = [[1,2] for j in range(3)]
subplotbar_labels = ["Infrastructure length (m/km2)","Total node density (1/km2)","Dangling node density (1/km2)",
]
filepath = compare_results_plots_fp + "network_densities_compare"
subplottitle = ["Avg infrastructure length per km2","Avg nodes per km2","Avg dangling nodes per km2",
]plot = plot_func.make_bar_subplots(subplot_data=subplotdata,nrows=1,ncols=3,bar_labels=[["OSM", reference_name] for j in range(3)],y_label=subplotbar_labels,x_positions=subplotx_positions,title=subplottitle,bar_colors=[pdict["osm_base"], pdict["ref_base"]],filepath=filepath,wspace=0.4
)
本地網(wǎng)絡(luò)密度
### Plot density comparisonsset_renderer(renderer_map)# Edge density
plot_cols = ["osm_edge_density", "ref_edge_density"]
plot_func.plot_multiple_grid_results(grid=grid,plot_cols=plot_cols,plot_titles=["OSM edge density", f"{reference_name} edge density"],filepath=compare_results_static_maps_fp + "density_edge_compare",cmap=pdict["pos"],alpha=pdict["alpha_grid"],cx_tile=cx_tile_2,no_data_cols=["count_osm_edges", "count_ref_edges"],use_norm=True,norm_min=0,norm_max = max(grid[plot_cols].max()),figsize = pdict["fsmap"],legend = False,
)# Node density
plot_cols = ["osm_node_density", "ref_node_density"]
plot_func.plot_multiple_grid_results(grid=grid,plot_cols=plot_cols,plot_titles=["OSM node density", f"{reference_name} node density"],filepath=compare_results_static_maps_fp + "density_node_compare",cmap=pdict["pos"],alpha=pdict["alpha_grid"],cx_tile=cx_tile_2,no_data_cols=["count_osm_nodes", "count_ref_nodes"],use_norm=True,norm_min=0,norm_max = max(grid[plot_cols].max()),figsize = pdict["fsmap"],legend = False,
)# Dangling node density
plot_cols = ["osm_dangling_node_density", "ref_dangling_node_density"]
plot_func.plot_multiple_grid_results(grid=grid,plot_cols=plot_cols,plot_titles=["OSM dangling node density", f"{reference_name} dangling node density"],filepath=compare_results_static_maps_fp + "density_danglingnode_compare",cmap=pdict["pos"],alpha=pdict["alpha_grid"],cx_tile=cx_tile_2,no_data_cols=["count_osm_nodes", "count_ref_nodes"],use_norm=True,norm_min=0,norm_max = max(grid[plot_cols].max()),figsize = pdict["fsmap"],legend = False,
)
網(wǎng)絡(luò)密度的局部差異
以O(shè)SM數(shù)據(jù)中的密度作為比較基線,絕對(duì)差值計(jì)算為“參考值”-“OSM值”。 因此,正值表示基礎(chǔ)設(shè)施類(lèi)型的參考密度高于 OSM 密度; 負(fù)值表示參考密度低于 OSM 密度。
grid["edge_density_diff"] = grid.ref_edge_density.fillna(0
) - grid.osm_edge_density.fillna(0)grid["node_density_diff"] = grid.ref_node_density.fillna(0
) - grid.osm_node_density.fillna(0)grid["dangling_node_density_diff"] = grid.ref_dangling_node_density.fillna(0
) - grid.osm_dangling_node_density.fillna(0)
# Network density grid plotsset_renderer(renderer_map)plot_cols = ["edge_density_diff", "node_density_diff", "dangling_node_density_diff"]
plot_titles = [area_name + f": {reference_name} edge density differences to OSM (m/km2)",area_name + f": {reference_name} node density differences to OSM (m/km2)",area_name + f": {reference_name} dangling node density differences to OSM (m/km2)"
]
filepaths = [compare_results_static_maps_fp + "edge_density_compare",compare_results_static_maps_fp + "node_density_compare",compare_results_static_maps_fp + "dangling_node_density_compare",
]cmaps = [pdict["diff"]] * 3# Cols for no-data plots
no_data_cols = [("osm_edge_density", "ref_edge_density"),("osm_node_density", "ref_node_density"),("osm_dangling_node_density", "ref_dangling_node_density"),
]cblim_edge = max(abs(min(grid["edge_density_diff"].fillna(value=0))),max(grid["edge_density_diff"].fillna(value=0)),
)cblim_node = max(abs(min(grid["node_density_diff"].fillna(value=0))),max(grid["node_density_diff"].fillna(value=0)),
)cblim_d_node = max(abs(min(grid["dangling_node_density_diff"].fillna(value=0))),max(grid["dangling_node_density_diff"].fillna(value=0)),
)norm_min = [-cblim_edge, -cblim_node, -cblim_d_node]
norm_max = [cblim_edge, cblim_node, cblim_d_node]plot_func.plot_grid_results(grid=grid,plot_cols=plot_cols,plot_titles=plot_titles,filepaths=filepaths,cmaps=cmaps,alpha=pdict["alpha_grid"],cx_tile=cx_tile_2,no_data_cols=no_data_cols,use_norm=True,norm_min=norm_min,norm_max=norm_max,
)
受保護(hù)和不受保護(hù)的自行車(chē)基礎(chǔ)設(shè)施的密度
受保護(hù)/未受保護(hù)基礎(chǔ)設(shè)施的全球網(wǎng)絡(luò)密度
# Plot global differencesset_renderer(renderer_plot)data_labels = ["protected_density", "unprotected_density", "mixed_density"]
legend_labels = ["OSM", reference_name]
data_osm = [osm_intrinsic_results["network_density"][label + "_m_sqkm"] for label in data_labels
]
data_ref = [ref_intrinsic_results["network_density"][label + "_m_sqkm"] for label in data_labels
]
bar_colors = [pdict["osm_base"], pdict["ref_base"]]
title = f"{area_name}"x_labels = ["Protected", "Unprotected", "Mixed"]
x_axis = [np.arange(len(x_labels)) * 2 - 0.25, np.arange(len(x_labels)) * 2 + 0.25]
x_ticks = np.arange(len(x_labels)) * 2y_label = "Infrastructure densities (m/km2)"filepath = compare_results_plots_fp + "infrastructure_type_density_diff_compare"fig = plot_func.make_bar_plot_side(x_axis=x_axis,data_osm=data_osm,data_ref=data_ref,bar_colors=bar_colors,legend_labels=legend_labels,title=title,x_ticks=x_ticks,x_labels=x_labels,x_label=None,y_label=y_label,filepath=filepath,figsize=pdict["fsbar_small"]
)
受保護(hù)/未受保護(hù)基礎(chǔ)設(shè)施的本地網(wǎng)絡(luò)密度
if "ref_protected_density" in grid.columns:plot_func.plot_saved_maps([osm_results_static_maps_fp + "density_protected_OSM",ref_results_static_maps_fp + "density_protected_reference",])else:plot_func.plot_saved_maps([osm_results_static_maps_fp + "density_protected_OSM"] * 2, alpha=[1, 0])print(f"No infrastructure is mapped as protected in the {reference_name} data.")if "ref_unprotected_density" in grid.columns:plot_func.plot_saved_maps([osm_results_static_maps_fp + "density_unprotected_OSM",ref_results_static_maps_fp + "density_unprotected_reference",])else:plot_func.plot_saved_maps([osm_results_static_maps_fp + "density_unprotected_OSM"] * 2, alpha=[1, 0])print(f"No infrastructure is mapped as unprotected in the {reference_name} data.")if "ref_mixed_density" in grid.columns:plot_func.plot_saved_maps([osm_results_static_maps_fp + "density_mixed_OSM",ref_results_static_maps_fp + "density_mixed_reference",])else:plot_func.plot_saved_maps([osm_results_static_maps_fp + "density_mixed_OSM"] * 2, alpha=[1, 0])print(f"No infrastructure is mapped as mixed protected/unprotected in the {reference_name} data.")
No infrastructure is mapped as mixed protected/unprotected in the GeoDanmark data.
基礎(chǔ)設(shè)施類(lèi)型密度的差異
# Computing difference in infrastructure type density# In case no infrastructure with mixed protected/unprotected exist
if "osm_mixed_density" not in grid.columns:grid["osm_mixed_density"] = 0if "ref_mixed_density" not in grid.columns:grid["ref_mixed_density"] = 0if "ref_protected_density" not in grid.columns:grid["ref_protected_density"] = 0if "ref_unprotected_density" not in grid.columns:grid["ref_unprotected_density"] = 0grid["protected_density_diff"] = grid.ref_protected_density.fillna(0
) - grid.osm_protected_density.fillna(0)
grid["unprotected_density_diff"] = grid.ref_unprotected_density.fillna(0
) - grid.osm_unprotected_density.fillna(0)
grid["mixed_density_diff"] = grid.ref_mixed_density.fillna(0
) - grid.osm_mixed_density.fillna(0)
# Infrastructure type density grid plotsset_renderer(renderer_map)plot_cols = ["protected_density_diff", "unprotected_density_diff", "mixed_density_diff"]
plot_cols = [c for c in plot_cols if c in grid.columns]
plot_titles = [area_name + f": {reference_name} protected infrastructure density differences to OSM (m/km2)",area_name + f": {reference_name} unprotected infrastructure density differences to OSM (1/km2)",area_name + f": {reference_name} mixed infrastructure density differences to OSM (1/km2)",
]filepaths = [compare_results_static_maps_fp + "protected_density_compare",compare_results_static_maps_fp + "unprotected_density_compare",compare_results_static_maps_fp + "mixed_density_compare",
]cmaps = [pdict["diff"]] * len(plot_cols)# Cols for no-data plots
no_data_cols = [("osm_edge_density", "ref_edge_density"),("osm_edge_density", "ref_edge_density"),("osm_edge_density", "ref_edge_density"),
]# Create symmetrical color range around zero
cblim = max(abs(min(grid[plot_cols].fillna(value=0).min())),max(grid[plot_cols].fillna(value=0).max()),
)norm_min = [-cblim] * len(plot_cols)
norm_max = [cblim] * len(plot_cols)plot_func.plot_grid_results(grid=grid,plot_cols=plot_cols,plot_titles=plot_titles,filepaths=filepaths,cmaps=cmaps,alpha=pdict["alpha_grid"],cx_tile=cx_tile_2,no_data_cols=no_data_cols,use_norm=True,norm_min=norm_min,norm_max=norm_max,
)
2.網(wǎng)絡(luò)拓?fù)浣Y(jié)構(gòu)
在比較數(shù)據(jù)完整性(即映射了“多少”基礎(chǔ)設(shè)施)之后,這里我們重點(diǎn)關(guān)注網(wǎng)絡(luò)“拓?fù)洹钡牟町?#xff0c;它提供了有關(guān)“如何”基礎(chǔ)設(shè)施在兩個(gè)數(shù)據(jù)集中映射的信息。 在這里,我們還分析網(wǎng)絡(luò)邊與一個(gè)或多個(gè)其他邊連接的程度,或者它們是否以懸空節(jié)點(diǎn)結(jié)束。 邊緣與相鄰邊緣正確連接的程度對(duì)于可訪問(wèn)性和路由分析等非常重要。
在處理自行車(chē)網(wǎng)絡(luò)上的數(shù)據(jù)時(shí),首選實(shí)際連接的網(wǎng)絡(luò)元素之間沒(méi)有間隙的數(shù)據(jù)集 - 當(dāng)然反映了真實(shí)情況。
識(shí)別網(wǎng)絡(luò)中的懸空節(jié)點(diǎn)是識(shí)別以“死胡同”結(jié)束的邊緣的快速且簡(jiǎn)單的方法。 下沖和過(guò)沖分別提供了網(wǎng)絡(luò)間隙和過(guò)度延伸邊緣的更精確圖像,這給出了懸空節(jié)點(diǎn)的誤導(dǎo)性計(jì)數(shù)。
方法
為了識(shí)別數(shù)據(jù)中潛在的間隙或缺失的鏈接,首先繪制兩個(gè)數(shù)據(jù)集中的懸空節(jié)點(diǎn)。 然后,單獨(dú)繪制每個(gè)數(shù)據(jù)集中所有節(jié)點(diǎn)中懸掛節(jié)點(diǎn)的局部百分比。 最后,我們顯示了懸空節(jié)點(diǎn)百分比的局部差異。
OSM 和參考數(shù)據(jù)中的欠調(diào)和過(guò)調(diào)最終會(huì)一起繪制在交互式圖中,以供進(jìn)一步檢查。
解釋
如果一條邊在一個(gè)數(shù)據(jù)集中以懸空節(jié)點(diǎn)結(jié)束,但在另一個(gè)數(shù)據(jù)集中卻沒(méi)有,則表明數(shù)據(jù)質(zhì)量存在問(wèn)題。 數(shù)據(jù)中缺少連接,或者兩條邊連接錯(cuò)誤。 類(lèi)似地,懸空節(jié)點(diǎn)份額的不同局部率表明自行車(chē)網(wǎng)絡(luò)的映射方式存在差異——盡管在解釋中當(dāng)然應(yīng)該考慮數(shù)據(jù)完整性的差異。
下沖是網(wǎng)絡(luò)數(shù)據(jù)中誤導(dǎo)性差距的明顯跡象——盡管它們也可能代表自行車(chē)基礎(chǔ)設(shè)施中的實(shí)際差距。 將一個(gè)數(shù)據(jù)集與另一數(shù)據(jù)集的下沖進(jìn)行比較可以幫助確定這是數(shù)據(jù)質(zhì)量問(wèn)題還是實(shí)際基礎(chǔ)設(shè)施的質(zhì)量問(wèn)題。 交叉口之間存在下沖或間隙的系統(tǒng)差異可能表明不同的數(shù)字化策略,因?yàn)橐恍┓椒〞?huì)將穿過(guò)街道的自行車(chē)道繪制為連接的延伸段,而其他方法則會(huì)在交叉街道的寬度上引入間隙。 雖然這兩種方法都是有效的,但使用前一種方法創(chuàng)建的數(shù)據(jù)集更適合基于路由的分析。
超調(diào)對(duì)于分析來(lái)說(shuō)通常不太重要,但大量的超調(diào)會(huì)引入錯(cuò)誤的懸空節(jié)點(diǎn),并扭曲基于節(jié)點(diǎn)度或節(jié)點(diǎn)與邊之間的比率等網(wǎng)絡(luò)結(jié)構(gòu)的測(cè)量。
2.1 簡(jiǎn)化結(jié)果
print(f"Simplifying the OSM network decreased the number of edges by {osm_intrinsic_results['simplification_outcome']['edge_percent_diff']:.1f}%."
)
print(f"Simplifying the OSM network decreased the number of nodes by {osm_intrinsic_results['simplification_outcome']['node_percent_diff']:.1f}%."
)
print("\n")
print(f"Simplifying the {reference_name} network decreased the number of edges by {ref_intrinsic_results['simplification_outcome']['edge_percent_diff']:.1f}%."
)
print(f"Simplifying the {reference_name} network decreased the number of nodes by {ref_intrinsic_results['simplification_outcome']['node_percent_diff']:.1f}%."
)
Simplifying the OSM network decreased the number of edges by 89.0%.
Simplifying the OSM network decreased the number of nodes by 84.4%.Simplifying the GeoDanmark network decreased the number of edges by 91.2%.
Simplifying the GeoDanmark network decreased the number of nodes by 92.2%.
Node degree distribution
degree_sequence_before_osm = sorted((d for n, d in osm_graph.degree()), reverse=True)
degree_sequence_after_osm = sorted((d for n, d in osm_graph_simplified.degree()), reverse=True
)degree_sequence_before_ref = sorted((d for n, d in ref_graph.degree()), reverse=True)
degree_sequence_after_ref = sorted((d for n, d in ref_graph_simplified.degree()), reverse=True
)
# Display already saved degree distribution plotsprint("Note that the two figures below have different y-axis scales.")plot_func.plot_saved_maps([osm_results_plots_fp + "degree_dist_osm",ref_results_plots_fp + "degree_dist_reference"]
)
Note that the two figures below have different y-axis scales.
2.2 Alpha、beta 和 gamma 指數(shù)
在本小節(jié)中,我們計(jì)算并對(duì)比三個(gè)聚合網(wǎng)絡(luò)指標(biāo) alpha、beta 和 gamma。 這些指標(biāo)通常用于描述網(wǎng)絡(luò)結(jié)構(gòu),但作為數(shù)據(jù)質(zhì)量的衡量標(biāo)準(zhǔn),它們僅在與相應(yīng)數(shù)據(jù)集的值進(jìn)行比較時(shí)才有意義。 因此,alpha、beta 和 gamma 僅是外在分析的一部分,不包含在內(nèi)在筆記本中。
雖然無(wú)法根據(jù)這三個(gè)指標(biāo)中的任何一個(gè)本身得出有關(guān)數(shù)據(jù)質(zhì)量的結(jié)論,但對(duì)兩個(gè)數(shù)據(jù)集的指標(biāo)進(jìn)行比較可以表明網(wǎng)絡(luò)拓?fù)涞牟町?#xff0c;從而表明基礎(chǔ)設(shè)施映射方式的差異。
方法
所有三個(gè)索引均使用“eval_func.compute_alpha_beta_gamma”計(jì)算。
alpha 值是網(wǎng)絡(luò)中實(shí)際與可能的周期的比率。 網(wǎng)絡(luò)循環(huán)被定義為閉環(huán) - 即在其起始節(jié)點(diǎn)上結(jié)束的路徑。 alpha值的范圍是0到1。alpha值為0意味著網(wǎng)絡(luò)根本沒(méi)有環(huán),即它是一棵樹(shù)。 alpha 值為 1 意味著網(wǎng)絡(luò)完全連接,但這種情況很少見(jiàn)。
beta 值是網(wǎng)絡(luò)中現(xiàn)有邊與現(xiàn)有節(jié)點(diǎn)的比率。 beta的取值范圍是0到N-1,其中N是現(xiàn)有節(jié)點(diǎn)的數(shù)量。 beta值為0意味著網(wǎng)絡(luò)沒(méi)有邊; Beta 值為 N-1 意味著網(wǎng)絡(luò)完全連接(另請(qǐng)參見(jiàn) gamma 值 1)。 beta 值越高,在任意一對(duì)節(jié)點(diǎn)之間可以選擇的不同路徑(平均)就越多。
gamma 值是網(wǎng)絡(luò)中現(xiàn)有邊與可能邊的比率。 連接兩個(gè)現(xiàn)有網(wǎng)絡(luò)節(jié)點(diǎn)的任何邊都被定義為“可能”。 因此,gamma 的取值范圍為 0 到 1。gamma 值為 0 表示網(wǎng)絡(luò)沒(méi)有邊;gamma 值為 0 表示網(wǎng)絡(luò)沒(méi)有邊; gamma 值為 1 意味著網(wǎng)絡(luò)的每個(gè)節(jié)點(diǎn)都連接到每個(gè)其他節(jié)點(diǎn)。
對(duì)于所有三個(gè)指數(shù),請(qǐng)參閱 Ducruet 和 Rodrigue,2020。 所有三個(gè)指數(shù)都可以根據(jù)網(wǎng)絡(luò)連接性進(jìn)行解釋: alpha 值越高,網(wǎng)絡(luò)中存在的周期越多; beta值越高,路徑數(shù)量越多,網(wǎng)絡(luò)復(fù)雜度越高; 伽馬值越高,任何一對(duì)節(jié)點(diǎn)之間的邊越少。
解釋
這些指標(biāo)并沒(méi)有過(guò)多說(shuō)明數(shù)據(jù)質(zhì)量本身,也對(duì)于類(lèi)似規(guī)模的網(wǎng)絡(luò)的拓?fù)浔容^沒(méi)有用處。 不過(guò),通過(guò)比較還是可以得出一些結(jié)論。 例如,如果兩個(gè)網(wǎng)絡(luò)的索引非常相似,盡管網(wǎng)絡(luò)例如 具有非常不同的幾何長(zhǎng)度,這表明數(shù)據(jù)集是以大致相同的方式映射的,但一個(gè)數(shù)據(jù)集只是比另一個(gè)包含更多的特征。 然而,如果網(wǎng)絡(luò)的總幾何長(zhǎng)度大致相同,但 alpha、beta 和 gamma 的值不同,則這可能表明兩個(gè)數(shù)據(jù)集的結(jié)構(gòu)和拓?fù)涓静煌?/p>
osm_alpha, osm_beta, osm_gamma = eval_func.compute_alpha_beta_gamma(edges=osm_edges_simplified,nodes=osm_nodes_simplified,G=osm_graph_simplified,planar=True,
) # We assume network to be planar or approximately planarprint(f"Alpha for the simplified OSM network: {osm_alpha:.2f}")
print(f"Beta for the simplified OSM network: {osm_beta:.2f}")
print(f"Gamma for the simplified OSM network: {osm_gamma:.2f}")print("\n")ref_alpha, ref_beta, ref_gamma = eval_func.compute_alpha_beta_gamma(ref_edges_simplified, ref_nodes_simplified, ref_graph_simplified, planar=True
) # We assume network to be planar or approximately planarprint(f"Alpha for the simplified {reference_name} network: {ref_alpha:.2f}")
print(f"Beta for the simplified {reference_name} network: {ref_beta:.2f}")
print(f"Gamma for the simplified {reference_name} network: {ref_gamma:.2f}")
Alpha for the simplified OSM network: 0.11
Beta for the simplified OSM network: 1.15
Gamma for the simplified OSM network: 0.38Alpha for the simplified GeoDanmark network: 0.10
Beta for the simplified GeoDanmark network: 1.14
Gamma for the simplified GeoDanmark network: 0.38
# Plot alpha, beta, gammaset_renderer(renderer_plot)bar_labels = ["OSM", reference_name]bar_colors = [pdict["osm_base"], pdict["ref_base"]]subplot_data = [(len(osm_nodes_simplified), len(ref_nodes_simplified)),(len(osm_edges_simplified), len(ref_edges_simplified)),(osm_edges_simplified.geometry.length.sum()/1000,ref_edges_simplified.geometry.length.sum()/1000,),(osm_alpha, ref_alpha),(osm_beta, ref_beta),(osm_gamma, ref_gamma),
]
y_label = ["","","","","","",
]
subplottitle = ["Total nodes", "Total edges", "Network length (km)", "Alpha", "Beta", "Gamma"]
filepath = compare_results_plots_fp + "alpha_beta_gamma"plot = plot_func.make_bar_subplots(subplot_data=subplot_data,nrows=2,ncols=3,bar_labels=[["OSM", reference_name] for j in range(6)],y_label=y_label,x_positions=[[1,2] for j in range(6)],title=subplottitle,bar_colors=bar_colors,filepath=filepath,wspace=0.4
);
2.3 懸空節(jié)點(diǎn)
osm_dangling_nodes = gpd.read_file(osm_results_data_fp + "dangling_nodes.gpkg")
ref_dangling_nodes = gpd.read_file(ref_results_data_fp + "dangling_nodes.gpkg")
OSM 和參考網(wǎng)絡(luò)中的懸空節(jié)點(diǎn)
# Interactive plot of dangling nodesosm_edges_simplified_folium = plot_func.make_edgefeaturegroup(gdf=osm_edges_simplified,mycolor=pdict["osm_base"],myweight=pdict["line_base"],nametag="OSM edges",show_edges=True,
)osm_nodes_simplified_folium = plot_func.make_nodefeaturegroup(gdf=osm_nodes_simplified,mysize=pdict["mark_base"],mycolor=pdict["osm_base"],nametag="OSM all nodes",show_nodes=True,
)osm_dangling_nodes_folium = plot_func.make_nodefeaturegroup(gdf=osm_dangling_nodes,mysize=pdict["mark_emp"],mycolor=pdict["osm_contrast"],nametag="OSM dangling nodes",show_nodes=True,
)ref_edges_simplified_folium = plot_func.make_edgefeaturegroup(gdf=ref_edges_simplified,mycolor=pdict["ref_base"],myweight=pdict["line_base"],nametag="Reference edges",show_edges=True,
)ref_nodes_simplified_folium = plot_func.make_nodefeaturegroup(gdf=ref_nodes_simplified,mysize=pdict["mark_base"],mycolor=pdict["ref_base"],nametag="Reference all nodes",show_nodes=True,
)ref_dangling_nodes_folium = plot_func.make_nodefeaturegroup(gdf=ref_dangling_nodes,mysize=pdict["mark_emp"],mycolor=pdict["ref_contrast2"],nametag="Reference dangling nodes",show_nodes=True,
)m = plot_func.make_foliumplot(feature_groups=[osm_edges_simplified_folium,osm_nodes_simplified_folium,osm_dangling_nodes_folium,ref_edges_simplified_folium,ref_nodes_simplified_folium,ref_dangling_nodes_folium,],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 + "danglingmap_compare.html")display(m)
print("Interactive map saved at " + compare_results_inter_maps_fp.lstrip("../") + "danglingmap_compare.html")
Interactive map saved at results/COMPARE/cph_geodk/maps_interactive/danglingmap_compare.html
懸空節(jié)點(diǎn)的局部值
# Compute pct difference relative to OSMgrid["dangling_nodes_diff_pct"] = np.round(100* (grid.count_ref_dangling_nodes - grid.count_osm_dangling_nodes)/ grid.count_osm_dangling_nodes,2,
)
懸空節(jié)點(diǎn)占所有節(jié)點(diǎn)的百分比
plot_func.plot_saved_maps([osm_results_static_maps_fp + "pct_dangling_nodes_osm",ref_results_static_maps_fp + "pct_dangling_nodes_reference",]
)
懸空節(jié)點(diǎn)百分比的局部差異
# Plotset_renderer(renderer_map)# norm color bar
cbnorm_dang_diff = colors.Normalize(vmin=-100, vmax=100) # from -max to +maxfig, 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="dangling_nodes_diff_pct",cmap=pdict["diff"],legend=True,norm=cbnorm_dang_diff,
)# Add no data patches
grid[grid["dangling_nodes_diff_pct"].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"],
)ax.legend(handles=[nodata_patch], loc="upper right")ax.set_title(area_name + f": {reference_name} percent difference to OSM in dangling nodes"
)
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 + "dangling_nodes_pct_diff_compare")
下沖/過(guò)沖
# USER INPUT: LENGTH TOLERANCE FOR OVER- AND UNDERSHOOTS
length_tolerance_over = 3
length_tolerance_under = 3for s in [length_tolerance_over, length_tolerance_under]:assert isinstance(s, int) or isinstance(s, float), print("Settings must be integer or float values!")
osm_overshoot_ids = pd.read_csv(osm_results_data_fp + f"overshoot_edges_{length_tolerance_over}.csv"
)["edge_id"].to_list()
osm_undershoot_ids = pd.read_csv(osm_results_data_fp + f"undershoot_nodes_{length_tolerance_under}.csv"
)["node_id"].to_list()ref_overshoot_ids = pd.read_csv(ref_results_data_fp + f"overshoot_edges_{length_tolerance_over}.csv"
)["edge_id"].to_list()
ref_undershoot_ids = pd.read_csv(ref_results_data_fp + f"undershoot_nodes_{length_tolerance_under}.csv"
)["node_id"].to_list()osm_overshoots = osm_edges_simplified.loc[osm_edges_simplified.edge_id.isin(osm_overshoot_ids)
]
ref_overshoots = ref_edges_simplified.loc[ref_edges_simplified.edge_id.isin(ref_overshoot_ids)
]
ref_undershoots = ref_nodes_simplified.loc[ref_nodes_simplified.nodeID.isin(ref_undershoot_ids)
]
osm_undershoots = osm_nodes_simplified.loc[osm_nodes_simplified.osmid.isin(osm_undershoot_ids)
]
OSM 和參考網(wǎng)絡(luò)中的過(guò)沖和下沖
# Interactive plot of over/undershootsfeature_groups = []# OSM feature groups
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,
)feature_groups.append(osm_edges_simplified_folium)if len(osm_overshoots) > 0:osm_overshoots_folium = plot_func.make_edgefeaturegroup(gdf=osm_overshoots,mycolor=pdict["osm_contrast"],myweight=pdict["line_emp"],nametag="OSM overshoots",show_edges=True,)feature_groups.append(osm_overshoots_folium)if len(osm_undershoots) > 0:osm_undershoot_nodes_folium = plot_func.make_nodefeaturegroup(gdf=osm_undershoots,mysize=pdict["mark_emp"],mycolor=pdict["osm_contrast2"],nametag="OSM undershoot nodes",show_nodes=True,)feature_groups.append(osm_undershoot_nodes_folium)# Reference feature groups
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,
)feature_groups.append(ref_edges_simplified_folium)if len(ref_overshoots) > 0:ref_overshoots_folium = plot_func.make_edgefeaturegroup(gdf=ref_overshoots,mycolor=pdict["ref_contrast"],myweight=pdict["line_emp"],nametag=f"{reference_name} overshoots",show_edges=True,)feature_groups.append(ref_overshoots_folium)if len(ref_undershoots) > 0:ref_undershoot_nodes_folium = plot_func.make_nodefeaturegroup(gdf=ref_undershoots,mysize=pdict["mark_emp"],mycolor=pdict["ref_contrast2"],nametag=f"{reference_name} undershoot nodes",show_nodes=True,)feature_groups.append(ref_undershoot_nodes_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+ f"overundershoots_{length_tolerance_over}_{length_tolerance_under}_compare.html"
)display(m)
print("Interactive map saved at " + compare_results_inter_maps_fp.lstrip("../")+ f"overundershoots_{length_tolerance_over}_{length_tolerance_under}_compare.html")
Interactive map saved at results/COMPARE/cph_geodk/maps_interactive/overundershoots_3_3_compare.html
3.網(wǎng)絡(luò)組件
見(jiàn)鏈接
4.概括
見(jiàn)鏈接
5.保存結(jié)果
見(jiàn)鏈接