BikeDNA(五)参考数据的内在分析1

BikeDNA(五)参考数据的内在分析1

该笔记本分析用户提供的给定区域的参考自行车基础设施数据集的质量。 质量评估是“内在的”,即仅基于一个输入数据集,并且不使用数据集外部的信息。 对于将参考数据集与相应 OSM 数据进行比较的外在质量评估,请参阅笔记本 3a 和 3b。

该分析评估给定区域参考数据的“目的适应性”(Barron et al., 2014)。 分析的结果可能与自行车规划和研究相关 - 特别是对于包括自行车基础设施网络分析的项目,在这种情况下,几何拓扑尤为重要。

由于评估不使用外部参考数据集作为基本事实,因此无法对数据质量做出普遍的声明。 这个想法是让那些使用自行车网络的人能够评估他们的数据是否足以满足他们的特定用例。 该分析有助于发现潜在的数据质量问题,但将结果的最终解释权留给用户。

该笔记本利用了一系列先前调查 OSM/VGI 数据质量的项目的质量指标,例如 Ferster et al. (2020), Hochmair et al. (2015), Barron et al. (2014), and Neis et al. (2012).

Prerequisites & Input/Output

提前运行笔记本 1b。

此笔记本的输出文件(数据、地图、绘图)保存到 …/results/REFERENCE/[study_area]/ 子文件夹中。

Familiarity required

为了正确解释一些空间数据质量指标,需要对该区域有一定的了解。


# Load libraries, settings and dataimport json
import pickle
import warnings
from collections import Counter
import mathimport contextily as cx
import folium
import geopandas as gpd
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
import osmnx as ox
import pandas as pd
import yaml
from matplotlib import cm, colorsfrom src import evaluation_functions as eval_func
from src import plotting_functions as plot_func%run ../settings/yaml_variables.py
%run ../settings/plotting.py
%run ../settings/tiledict.py
%run ../settings/load_refdata.py
%run ../settings/df_styler.py
%run ../settings/paths.pywarnings.filterwarnings("ignore")grid = ref_grid
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)Reference graphs loaded successfully!
Reference data loaded successfully!<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.

1.数据完整性

1.1 网络密度

在此设置中,网络密度是指边的长度或每平方公里的节点数。 这是空间(道路)网络中网络密度的通常定义,它与网络科学中更常见的“结构”网络密度不同。 如果不与参考数据集进行比较,网络密度本身并不表明空间数据质量。 然而,对于熟悉研究区域的任何人来说,网络密度可以表明该区域的某些部分是否映射不足或过度。

方法

这里的密度不是基于边缘的几何长度,而是基于基础设施的计算长度。 例如,一条 100 米长的双向路径贡献了 200 米的自行车基础设施。 该方法用于考虑绘制自行车基础设施的不同方式,否则可能会导致网络密度出现较大偏差。 使用“compute_network_densis”,可以计算每单位面积的元素数量(节点、悬空节点和基础设施总长度)。 密度计算两次:首先计算整个网络的研究区域(“全局密度”),然后计算每个网格单元(“局部密度”)。 全局和局部密度都是针对整个网络以及受保护和未受保护的基础设施计算的。

解释

由于此处进行的分析是内在的,即不使用外部信息,因此无法知道低密度值是由于测绘不完整还是由于该地区实际缺乏基础设施所致。 然而,网格单元密度值的比较可以提供一些见解,例如:

  • 基础设施密度低于平均水平表明局部网络较为稀疏
  • 高于平均节点密度表明网格单元内交叉点相对较多
  • 悬挂节点密度高于平均水平表明网格单元中存在相对较多的死角
全球网络密度

# Entire study area
edge_density, node_density, dangling_node_density = eval_func.compute_network_density((ref_edges_simplified, ref_nodes_simplified),grid.unary_union.area,return_dangling_nodes=True,
)density_results = {}
density_results["edge_density_m_sqkm"] = edge_density
density_results["node_density_count_sqkm"] = node_density
density_results["dangling_node_density_count_sqkm"] = dangling_node_densityref_protected = ref_edges_simplified.loc[ref_edges_simplified.protected == "protected"]
ref_unprotected = ref_edges_simplified.loc[ref_edges_simplified.protected == "unprotected"
]
ref_mixed = ref_edges_simplified.loc[ref_edges_simplified.protected == "mixed"]ref_data = [ref_protected, ref_unprotected, ref_mixed]
labels = ["protected_density", "unprotected_density", "mixed_density"]for data, label in zip(ref_data, labels):if len(data) > 0:ref_edge_density_type, _ = eval_func.compute_network_density((data, ref_nodes_simplified),grid.unary_union.area,return_dangling_nodes=False,)density_results[label + "_m_sqkm"] = ref_edge_density_typeelse:density_results[label + "_m_sqkm"] = 0protected_edge_density = density_results["protected_density_m_sqkm"]
unprotected_edge_density = density_results["unprotected_density_m_sqkm"]
mixed_protection_edge_density = density_results["mixed_density_m_sqkm"]print(f"For the entire study area, there are:")
print(f"- {edge_density:.2f} meters of bicycle infrastructure per km2.")
print(f"- {node_density:.2f} nodes in the bicycle network per km2.")
print(f"- {dangling_node_density:.2f} dangling nodes in the bicycle network per km2."
)
print(f"- {protected_edge_density:.2f} meters of protected bicycle infrastructure per km2."
)
print(f"- {unprotected_edge_density:.2f} meters of unprotected bicycle infrastructure per km2."
)
print(f"- {mixed_protection_edge_density:.2f} meters of mixed protection bicycle infrastructure per km2."
)
For the entire study area, there are:
- 3453.85 meters of bicycle infrastructure per km2.
- 22.74 nodes in the bicycle network per km2.
- 4.80 dangling nodes in the bicycle network per km2.
- 2998.80 meters of protected bicycle infrastructure per km2.
- 455.05 meters of unprotected bicycle infrastructure per km2.
- 0.00 meters of mixed protection bicycle infrastructure per km2.
# Save stats to csv
pd.DataFrame({"metric": ["meters of bicycle infrastructure per square km","nodes in the bicycle network per square km","dangling nodes in the bicycle network per square km","meters of protected bicycle infrastructure per square km","meters of unprotected bicycle infrastructure per square km","meters of mixed protection bicycle infrastructure per square km",],"value": [np.round(edge_density, 2),np.round(node_density, 2),np.round(dangling_node_density, 2),np.round(protected_edge_density, 2),np.round(unprotected_edge_density, 2),np.round(mixed_protection_edge_density, 2),],}
).to_csv(ref_results_data_fp + "stats_area.csv", index=False)
本地网络密度
# Per grid cell
results_dict = {}
data = (ref_edges_simp_joined, ref_nodes_simp_joined.set_index("osmid"))[eval_func.run_grid_analysis(grid_id,data,results_dict,eval_func.compute_network_density,grid["geometry"].loc[grid.grid_id == grid_id].area.values[0],return_dangling_nodes=True,)for grid_id in grid_ids
]results_df = pd.DataFrame.from_dict(results_dict, orient="index")
results_df.reset_index(inplace=True)
results_df.rename(columns={"index": "grid_id",0: "ref_edge_density",1: "ref_node_density",2: "ref_dangling_node_density",},inplace=True,
)grid = eval_func.merge_results(grid, results_df, "left")ref_protected = ref_edges_simp_joined.loc[ref_edges_simp_joined.protected == "protected"
]
ref_unprotected = ref_edges_simp_joined.loc[ref_edges_simp_joined.protected == "unprotected"
]
ref_mixed = ref_edges_simp_joined.loc[ref_edges_simp_joined.protected == "mixed"]ref_data = [ref_protected, ref_unprotected, ref_mixed]ref_labels = ["ref_protected_density", "ref_unprotected_density", "ref_mixed_density"]for data, label in zip(ref_data, ref_labels):if len(data) > 0:results_dict = {}data = (ref_edges_simp_joined.loc[data.index], ref_nodes_simp_joined)[eval_func.run_grid_analysis(grid_id,data,results_dict,eval_func.compute_network_density,grid["geometry"].loc[grid.grid_id == grid_id].area.values[0],)for grid_id in grid_ids]results_df = pd.DataFrame.from_dict(results_dict, orient="index")results_df.reset_index(inplace=True)results_df.rename(columns={"index": "grid_id", 0: label}, inplace=True)results_df.drop(1, axis=1, inplace=True)grid = eval_func.merge_results(grid, results_df, "left")
# Network density grid plotsset_renderer(renderer_map)
plot_cols = ["ref_edge_density", "ref_node_density", "ref_dangling_node_density"]
plot_titles = [area_name + f": {reference_name} edge density",area_name + f": {reference_name} node density",area_name + f": {reference_name} dangling node density",
]
filepaths = [ref_results_static_maps_fp + "density_edge_reference",ref_results_static_maps_fp + "density_node_reference",ref_results_static_maps_fp + "density_danglingnode_reference",
]
cmaps = [pdict["pos"], pdict["pos"], pdict["pos"]]
no_data_cols = ["count_ref_edges", "count_ref_nodes", "count_ref_nodes"]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,attr=reference_name
)

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

受保护和未受保护基础设施的密度

在 BikeDNA 中,“受保护的基础设施”是指通过高架路缘、护柱或其他物理屏障等与汽车交通分开的所有自行车基础设施,或者不毗邻街道的自行车道。

不受保护的基础设施是专门供骑自行车者使用的所有其他类型的车道,但仅通过汽车交通分隔,例如街道上的画线。

# Network density grid plotsset_renderer(renderer_map)
plot_cols = ["ref_protected_density", "ref_unprotected_density", "ref_mixed_density"]plot_cols = [p for p in plot_cols if p in grid.columns]plot_titles = [area_name + f": {reference_name} protected infrastructure density (m/km2)",area_name + f": {reference_name} unprotected infrastructure density (m/km2)",area_name + f": {reference_name} mixed protection infrastructure density (m/km2)"
]# plot_titles = plot_titles[0:len(plot_cols)]filepaths = [ref_results_static_maps_fp + "density_protected_reference",ref_results_static_maps_fp + "density_unprotected_reference",ref_results_static_maps_fp + "density_mixed_reference",
]cmaps = [pdict["pos"]] * len(plot_cols)
no_data_cols = ["ref_protected_density", "ref_unprotected_density", "ref_mixed_density"]
norm_min = [0] * len(plot_cols)
norm_max = [max(grid[plot_cols].fillna(value=0).max())] * 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,attr=reference_name
)

在这里插入图片描述

在这里插入图片描述

2.网络拓扑结构

本节探讨数据的几何和拓扑特征。 例如,这些是网络密度、断开的组件和悬空(一级)节点。 它还包括探索是否存在彼此非常接近但不共享边缘的节点(边缘下冲的潜在迹象),或者是否存在相交边缘而在相交处没有节点,这可能表明存在数字化错误,该错误将导致数字化错误。 扭曲网络上的路由。

由于大多数自行车网络的分散性,许多指标(例如缺失链接或网络间隙)可以简单地反映基础设施的真实范围(Natera Orozco et al., 2020)。 这对于道路网络来说是不同的,例如,断开的组件更容易被解释为数据质量问题。 因此,分析仅将非常小的网络间隙视为潜在的数据质量问题。

2.1 简化结果

为了比较网络中节点和边之间的结构和真实比率,通过删除所有间隙节点,在笔记本“1b”中创建了仅包括端点和交叉点处的节点的简化网络表示。

比较简化前后网络的度分布是对简化例程的快速健全性检查。 通常,非简化网络中的绝大多数节点都是二级节点; 然而,在简化的网络中,大多数节点的度数不是二。 仅在两种情况下保留二级节点:如果它们代表两种不同类型的基础设施之间的连接点; 或者如果需要它们以避免自循环(起点和终点相同的边)或同一对节点之间的多个边。

在这里插入图片描述

非简化网络(左)和简化网络(右)

方法

简化前后的节点度分布如下图所示。

解释

通常,节点度分布将从高(简化前)到低(简化后)二度节点计数,而对于所有其他度(1 或 3 及更高),它不会改变。 此外,节点总数将出现大幅下降。 如果简化后的图仍然保持相对较高的二度节点数量,或者简化后具有其他度数的节点数量发生变化,则这可能表明图转换或简化过程存在问题。


# Decrease in network elements after simplificationedge_percent_diff = (len(ref_edges) - len(ref_edges_simplified)) / len(ref_edges) * 100
node_percent_diff = (len(ref_nodes) - len(ref_nodes_simplified)) / len(ref_nodes) * 100simplification_results = {"edge_percent_diff": edge_percent_diff,"node_percent_diff": node_percent_diff,
}print(f"Simplifying the network decreased the number of edges with {edge_percent_diff:.1f}% and the number of nodes with {node_percent_diff:.1f}%."
)
Simplifying the network decreased the number of edges with 91.2% and the number of nodes with 92.2%.
# Node degree distributionset_renderer(renderer_plot)
fig, ax = plt.subplots(1, 2, figsize=pdict["fsbar_short"], sharey=True)degree_sequence_before = sorted((d for n, d in ref_graph.degree()), reverse=True)
degree_sequence_after = sorted((d for n, d in ref_graph_simplified.degree()), reverse=True
)ax[0].bar(*np.unique(degree_sequence_before, return_counts=True), tick_label = np.unique(degree_sequence_before), color=pdict["ref_base"])
ax[0].set_title("Before simplification")
ax[0].set_xlabel("Degree")
ax[0].set_ylabel("Nodes")ax[1].bar(*np.unique(degree_sequence_after, return_counts=True), tick_label = np.unique(degree_sequence_after), color=pdict["ref_base"])
ax[1].set_title("After simplification")
ax[1].set_xlabel("Degree")plt.suptitle(f"{area_name}: {reference_name} degree distributions")fig.tight_layout()plot_func.save_fig(fig, ref_results_plots_fp + "degree_dist_reference")
plt.show();

在这里插入图片描述

2.2 悬空节点

悬空节点是一阶节点,即它们仅附有一条边。 大多数网络自然会包含许多悬空节点。 悬空节点可能出现在实际的死胡同(代表死胡同)或某些特征的端点处,例如 当自行车道在街道中间结束时。 但是,在出现过冲/下冲的情况下,悬空节点也可能会作为数据质量问题出现(请参阅下一节)。 网络中悬空节点的数量在某种程度上也取决于数字化方法,如下图所示。

因此,悬空节点的存在本身并不是数据质量低的标志。 然而,在未知包含许多死胡同的区域中存在大量悬空节点可能表明数字化错误和边缘上冲/下冲问题。

在这里插入图片描述

左:悬挂节点出现在道路要素结束处。 右:但是,当最后连接单独的特征时,将不会有悬空节点。

方法

下面,在“get_dangling_nodes”的帮助下获得了所有悬空节点的列表。 然后,绘制包含所有节点的网络。 悬空节点以颜色显示,所有其他节点以黑色显示。

解释

我们建议进行可视化分析,以解释悬挂节点的空间分布,特别注意悬挂节点密度高的区域。 重要的是要了解悬挂节点的来源:它们是真正的死胡同还是数字化错误(例如,过冲/下冲)? 数字化错误数量越多表明数据质量越低。


# Compute number of dangling nodes
dangling_nodes = eval_func.get_dangling_nodes(ref_edges_simplified, ref_nodes_simplified
)# Export results
dangling_nodes.to_file(ref_results_data_fp + "dangling_nodes.gpkg", index=False)# Compute local count and pct of dangling nodes
dn_ref_joined = gpd.overlay(dangling_nodes, grid[["geometry", "grid_id"]], how="intersection"
)
df = eval_func.count_features_in_grid(dn_ref_joined, "ref_dangling_nodes")
grid = eval_func.merge_results(grid, df, "left")grid["ref_dangling_nodes_pct"] = np.round(100 * grid.count_ref_dangling_nodes / grid.count_ref_simplified_nodes, 2
)# set to zero where there are simplified nodes but no dangling nodes
grid["ref_dangling_nodes_pct"].loc[grid.count_ref_simplified_nodes.notnull() & grid.ref_dangling_nodes_pct.isnull()
] = 0
# Plot dangling nodesset_renderer(renderer_map)
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,column="ref_dangling_nodes_pct",ax=ax,alpha=pdict["alpha_grid"],cmap=pdict["pos"],legend=True,
)# add no data patches
grid[grid["count_ref_simplified_nodes"].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(f"{area_name}: {reference_name} percent of dangling nodes")
ax.set_axis_off()
cx.add_basemap(ax=ax, crs=study_crs, source=cx_tile_2)
cx.add_attribution(ax=ax, text=f"(C) {reference_name}")
txt = ax.texts[-1]
txt.set_position([1,0.00])
txt.set_ha('right')
txt.set_va('bottom')plot_func.save_fig(fig,ref_results_static_maps_fp + "pct_dangling_nodes_reference")

在这里插入图片描述

# Interactive plot of dangling nodesedges_simplified_folium = plot_func.make_edgefeaturegroup(gdf=ref_edges_simplified,mycolor=pdict["base"],myweight=pdict["line_base"],nametag="Edges",show_edges=True,
)nodes_simplified_folium = plot_func.make_nodefeaturegroup(gdf=ref_nodes_simplified,mysize=pdict["mark_base"],mycolor=pdict["base"],nametag="All nodes",show_nodes=True,
)dangling_nodes_folium = plot_func.make_nodefeaturegroup(gdf=dangling_nodes,mysize=pdict["mark_emp"],mycolor=pdict["ref_base"],nametag="Dangling nodes",show_nodes=True,
)m = plot_func.make_foliumplot(feature_groups=[edges_simplified_folium,nodes_simplified_folium,dangling_nodes_folium,],layers_dict=folium_layers,center_gdf=ref_nodes_simplified,center_crs=ref_nodes_simplified.crs,attr=reference_name
)bounds = plot_func.compute_folium_bounds(ref_nodes_simplified)
m.fit_bounds(bounds)m.save(ref_results_inter_maps_fp + "folium_danglingmap_reference.html")display(m)

在这里插入图片描述

print("Interactive map saved at " + ref_results_inter_maps_fp.lstrip("../") + "folium_danglingmap_reference.html")
Interactive map saved at results/REFERENCE/cph_geodk/maps_interactive/folium_danglingmap_reference.html

2.3 下冲/过冲

当简化网络中的两个节点放置在几米距离内但不共享公共边缘时,通常是由于边缘上冲/下冲或其他数字化错误造成的。 当两个特征应该相交,但实际上彼此非常接近时,就会发生下冲。 当两个特征相遇并且其中一个特征超出另一个特征时,就会发生超调。 请参见下图的说明。 有关过冲/下冲的更详细说明,请参阅 GIS Lounge 网站。

在这里插入图片描述

左:当两条线要素未正确连接时(例如在交叉点处),会发生下冲。 右图:过冲是指线要素在相交线处延伸太远,而不是在相交处结束的情况。

方法

*下冲:*首先,“length_tolerance”(以米为单位)在下面的单元格中定义。 然后,使用“find_undershoots”,所有之间距离最大为“length_tolerance”的悬空节点对都被识别为下冲,并绘制结果。

*超调:*首先,“长度公差”(以米为单位)在下面的单元格中定义。 然后,使用“find_overshoots”,所有附加有悬空节点且最大长度为“length_tolerance”的网络边都被识别为过冲,并绘制结果。

过冲/下冲检测方法的灵感来自于 Neis et al. (2012)。

解释

欠调/过调不一定总是数据质量问题 - 它们可能是网络状况或数字化策略的准确表示。 例如,自行车道可能在转弯后不久突然结束,从而导致超调。 受保护的自行车道有时会被数字化为在交叉路口中断,从而导致交叉路口下冲。

过冲/下冲对数据质量影响的解释取决于上下文。 对于某些应用,例如路由,过冲并不构成特殊的挑战; 然而,鉴于它们扭曲了网络结构,它们可能会给网络分析等其他应用带来问题。 相反,下冲对于路线应用来说是一个严重的问题,特别是如果只考虑自行车基础设施的话。 它们还给网络分析带来了问题,例如对于任何基于路径的度量,例如大多数中心性度量,如介数中心性。


User configurations

在分析过冲和下冲时,用户可以修改过冲和下冲的长度公差。
例如,过冲的长度容差为 3 米,这意味着只有长度为 3 米或更小的边缘片段才被视为过冲。
下冲容差为 5 米,意味着只有 5 米或更小的间隙才被视为下冲。
# 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!")print(f"Running overshoot analysis with a tolerance threshold of {length_tolerance_over} m.")
print(f"Running undershoot analysis with a tolerance threshold of {length_tolerance_under} m.")
Running overshoot analysis with a tolerance threshold of 3 m.
Running undershoot analysis with a tolerance threshold of 3 m.
### Overshoots
overshoots = eval_func.find_overshoots(dangling_nodes,ref_edges_simplified,length_tolerance_over,return_overshoot_edges=True,
)print(f"{len(overshoots)} potential overshoots were identified with a length tolerance of {length_tolerance_over} m."
)### Undershoots
undershoot_dict, undershoot_nodes = eval_func.find_undershoots(dangling_nodes,ref_edges_simplified,length_tolerance_under,"edge_id",return_undershoot_nodes=True,
)print(f"{len(undershoot_nodes)} potential undershoots were identified with a length tolerance of {length_tolerance_under} m."
)
21 potential overshoots were identified with a length tolerance of 3 m.
11 potential undershoots were identified with a length tolerance of 3 m.
# Save to csv
overshoots[["edge_id", "length"]].to_csv(ref_results_data_fp + f"overshoot_edges_{length_tolerance_over}.csv", header = ["edge_id", "length (m)"], index = False
)pd.DataFrame(undershoot_nodes["nodeID"].to_list(), columns=["node_id"]).to_csv(ref_results_data_fp + f"undershoot_nodes_{length_tolerance_under}.csv", index=False
)
# Interactive plot over/undershootssimplified_edges_folium = plot_func.make_edgefeaturegroup(gdf=ref_edges_simplified,mycolor=pdict["base"],myweight=pdict["line_base"],nametag="Edges",show_edges=True,
)fg = [simplified_edges_folium]if len(overshoots) > 0 or len(undershoot_nodes) > 0:if len(overshoots) > 0:overshoots_folium = plot_func.make_edgefeaturegroup(gdf=overshoots,mycolor=pdict["ref_emp2"],myweight=pdict["line_emp2"],nametag="Overshoots",show_edges=True,)fg.append(overshoots_folium)if len(undershoot_nodes) > 0:undershoot_nodes_folium = plot_func.make_nodefeaturegroup(gdf=undershoot_nodes,mysize=pdict["mark_emp"],mycolor=pdict["ref_contrast"],nametag="Undershoot nodes",show_nodes=True,)fg.append(undershoot_nodes_folium)m = plot_func.make_foliumplot(feature_groups=fg,layers_dict=folium_layers,center_gdf=ref_nodes_simplified,center_crs=ref_nodes_simplified.crs,)bounds = plot_func.compute_folium_bounds(ref_nodes_simplified)m.fit_bounds(bounds)m.save(ref_results_inter_maps_fp+ f"underovershoots_{length_tolerance_under}_{length_tolerance_over}_reference.html")display(m)if len(undershoot_nodes) == 0:print("There are no undershoots to plot.")
if len(overshoots) == 0:print("There are no overshoots to plot.")

在这里插入图片描述

if len(overshoots) > 0 or len(undershoot_nodes) > 0:print("Interactive map saved at " + ref_results_inter_maps_fp.lstrip("../") + f"overundershoots_{length_tolerance_under}_{length_tolerance_over}_reference.html")
else:print("There are no under/overshoots to plot.")
Interactive map saved at results/REFERENCE/cph_geodk/maps_interactive/overundershoots_3_3_reference.html

3.网络组件

4.概括

5.保存结果

后续见链接

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

redis — redis cluster集群模式下如何实现批量可重入锁?

一、redis cluster 集群版 在Redis 3.0版本以后,Redis发布了Redis Cluster。该集群主要支持搞并发和海量数据处理等优势,当 Redis 在集群模式下运行时,它处理数据存储的方式与作为单个实例运行时不同。这是因为它应该准备好跨多个节点分发数据,从而实现水平可扩展性。具体能…

Java内存结构

前文&#xff1a; 《Java8之类的加载》 《Java8之类加载机制class源码分析》 写在开头&#xff1a;本文为学习后的总结&#xff0c;可能有不到位的地方&#xff0c;错误的地方&#xff0c;欢迎各位指正。 JVM 在执行 Java 程序的过程中会把它所管理的内存划分为若干个不同的数…

Ubuntu server配置ssh远程登录

使用如下命令进行安装 apt-get install ssh 安装好后启动 service ssh start 然后查看运行状态 然后用本机ping虚拟机 关闭本机和虚拟机防火墙 ufw disable 然后打开Xshell进行连接

14、MySQL高频面试题

1、内连接和外连接的区别 内连接和外连接都是数据库进行多表联查时使用的连接方式&#xff0c;区别在于二者获取的数据集不同 内连接指的是使用左表中的每一条数据分别去连接右表中的每一条数据&#xff0c;仅仅显示出匹配成功的那部分 外连接有分为左外连接和右外连接 左外…

重磅!OpenAI正式发布,自定义ChatGPT商店!

1月11日凌晨&#xff0c;OpenAI在官网正式发布了&#xff0c;自定义GPT商店&#xff0c;可以帮助用户找到目前最好用、流行的自定义ChatGPT助手。 在2024年第一季度&#xff0c;OpenAI将启动GPT 开发者收入计划。首先&#xff0c;美国地区的开发者将根据用户对其 GPT 的使用情…

day-07 统计出现过一次的公共字符串

思路 用哈希表统计words1和words2中各个字符串的出现次数&#xff0c;次数皆为1的字符串符合题意 解题方法 //用于存储words1中各个字符串的出现次数 HashMap<String,Integer> hashMap1new HashMap<>(); //用于存储words2中各个字符串的出现次数 HashMap<Stri…

小程序系列-5.WXML 模板语法

一、数据绑定 1、在 data 中定义页面的数据 动态绑定内容&#xff1a; 动态绑定属性&#xff1a; 2. Mustache 语法的格式 3. Mustache 语法的应用场景 4. 三元运算 5.算数运算 二、 事件绑定 1. 什么是事件&#xff1f; 2. 小程序中常用的事件 3. 事件对象的属性列表 4.…

Linux基础工具的使用(yum,vim,gcc,g++,gdb,make/makefile)【详解】

目录 linux软件包管理器-yum什么是软件包&#xff1f;查找软件包如何安装软件卸载软件 linux编辑器 - vimvim的基本概念vim模式之间的切换vim命令模式各命令汇总vim底行模式各命令汇总 Linux编译器 - gcc/ggcc/g的作用gcc/g选项预处理编译汇编链接静态库与动态库 Linux调试器 -…

详细分析Java中的@Transactional注解

目录 前言1. 基本知识2. 常用属性3. Demo4. 总结 前言 Transactional 是 Spring 框架中用于管理事务的注解。 该注解来源于Spring&#xff0c;对于Spring的基础知识可看我之前的文章&#xff1a; Spring框架从入门到学精&#xff08;全&#xff09; 该注解也可用在xxl-job框架…

自动化测试框架pytest系列之8个常用的装饰器函数

自动化测试框架pytest系列之基础概念介绍(一)-CSDN博客 自动化测试框架pytest系列之21个命令行参数介绍(二)-CSDN博客 自动化测试框架pytest系列之强大的fixture功能&#xff0c;为什么fixture强大&#xff1f;一文拆解它的功能参数。(三)-CSDN博客 接上文 3.5 pytest的8…

Vant4在Vue3.3中如何按需导入组件和样式

前言 最近我在Vue 3.3的项目中对Vant4做按需导入时&#xff0c;尽管按照Vant4的官方指南进行操作&#xff0c;但样式仍然无法正确加载。经过深入研究和多篇文章的比较&#xff0c;我终于找到了在Vue3中如何正确的按需导入Vant 4组件和样式的方法。由于Vue3.3和Vant4相对较新&am…

多无人机编队避障(人工势场法)

matlab2020正常运行&#xff0c;预设编队类型&#xff0c;目标位置&#xff0c;障碍物 多无人机编队避障&#xff08;人工势场法&#xff09;资源-CSDN文库

浅析链表结构

一、单向链表 C语言中数组是常用的一种数据类型&#xff0c;但可惜数组长度是固定大小的&#xff0c;不能动态扩展&#xff0c;使用起来有时不是很方便。然后就有了自定义的动态数组结构&#xff0c;动态数组就比较好用了&#xff0c;长度可以任意扩展&#xff0c;但还有一个问…

easyexcel 3.0.x 版本实现指定列 锁定以及指定列隐藏

1&#xff1a;效果示例 2&#xff1a;代码示例&#xff1a; UnLockCell.java package com.example.juc.zhujie;/*** Author * Date Created in 2023/12/19 10:09* DESCRIPTION:* Version V1.0*/import java.lang.annotation.*;/*** 用于标记锁定哪些列不需要锁定* author 12…

【LangChain学习之旅】—(7) 调用模型:使用OpenAI API还是微调开源Llama2/ChatGLM?

【LangChain学习之旅】—&#xff08;7&#xff09; 调用模型&#xff1a;使用OpenAI API还是微调开源Llama2/ChatGLM&#xff1f; 大语言模型发展史预训练 微调的模式用 HuggingFace 跑开源模型申请使用 Meta 的 Llama2 模型通过 HuggingFace 调用 LlamaLangChain 和 Hugging…

若依在表格中如何将字典的键值转为中文

文章目录 一、需求&#xff1a;二、问题解决步骤1、给需要转换的列绑定formatter属性2、获取字典项3、编写formatter属性绑定的方法 一、需求&#xff1a; 后端有时候返回的是字典的键值&#xff0c;在前端展示时需要转成中文值 后端返回的是dictValue&#xff0c;现在要转换…

【Git】本地仓库文件的创建、修改和删除

目录 一、基本信息设置 1、设置用户名2、设置用户名邮箱 二、Git仓库操作介绍 1、创建一个新的文件夹2、在文件内初始化git仓库&#xff08;创建git仓库&#xff09;3、向仓库中添加文件 1.创建一个文件2.将文件添加到暂存区3.将暂存区添加到仓库 4、修改仓库文件 1.修改文件2.…

java中数组

文章目录 java中数组思维导图数组数组概念 数组定义格式详解数组的访问 常见异常数组索引值越界异常&#xff1a;ArrayIndexOutOfBoundsException空指针异常&#xff1a;NullPointerException 案例例一打印A-Z和0-9例二数组转置输出 java中数组 思维导图 数组 数组概念 组就…

Java8常用新特性

目录 简介 1.默认方法 2..Lambda表达式 3.Stream API 4.方法引用 5.Optional类 简介 Java 8是Java编程语言的一个重要版本&#xff0c;引入了许多令人兴奋和强大的新特性。这些特性使得Java程序更加现代化、灵活和高效。让我们一起来探索一些Java 8的常用新特性吧&#…

Mac 下载 nvm 后执行nvm -v 命令报错 nvm: command not found

1、问题&#xff1a;Mac 使用命令下载nvm 成功后执行 nvm -v 查看&#xff0c;报错&#xff1a;nvm command not found 2、原因&#xff1a;可能是系统更新后&#xff0c;默认的 shell 是 zsh&#xff0c;所以找不到配置文件 3、解决&#xff1a;可添加编辑.bash_profile 和 …