BikeDNA(六)参考数据的内在分析2

BikeDNA(六)参考数据的内在分析2

1.数据完整性

见链接

2.网络拓扑结构

见链接

3.网络组件

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

方法

首先,在“return_components”的帮助下,获得网络所有(断开连接的)组件的列表。 打印组件总数,并以不同颜色绘制所有组件以进行视觉分析。 接下来,绘制组件大小分布(组件按其包含的网络长度排序),然后绘制最大连接组件的图。

解释

与之前的许多分析步骤一样,该领域的知识对于正确解释成分分析至关重要。 鉴于数据准确地代表了实际的基础设施,较大的组件表示连贯的网络部分,而较小的组件表示分散的基础设施(例如,沿着街道的一条自行车道,不连接到任何其他自行车基础设施)。 大量彼此邻近的断开组件表明数字化错误或丢失数据。

3.1 断开的组件

ref_components = eval_func.return_components(ref_graph_simplified)
print(
    f"The network in the study area has {len(ref_components)} disconnected components."
)
The network in the study area has 204 disconnected components.
# Plot disconnected components

set_renderer(renderer_map)

# set seed for colors
np.random.seed(42)

# generate enough random colors to plot all components
randcols = np.random.rand(len(ref_components), 3)
randcols[0, :] = col_to_rgb(pdict['ref_base'])

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

ax.set_title(f"{area_name}: {reference_name} disconnected components")

ax.set_axis_off()

for j, c in enumerate(ref_components):
    if len(c.edges) > 0:
        edges = ox.graph_to_gdfs(c, nodes=False)
        edges.plot(ax=ax, color=randcols[j])

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 + "all_components_reference")

在这里插入图片描述

3.2 每个网格单元的组件

# Assign component ids to grid
grid = eval_func.assign_component_id_to_grid(
    ref_edges_simplified,
    ref_edges_simp_joined,
    ref_components,
    grid,
    prefix="ref",
    edge_id_col="edge_id",
)

fill_na_dict = {"component_ids_ref": ""}
grid.fillna(value=fill_na_dict, inplace=True)

grid["component_count_ref"] = grid.component_ids_ref.apply(lambda x: len(x))
# Plot number of components per grid cell

set_renderer(renderer_map)

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

ncolors = grid["component_count_ref"].max()

from mpl_toolkits.axes_grid1 import make_axes_locatable
divider = make_axes_locatable(ax)
cax = divider.append_axes("right", size="3.5%", pad="1%")

mycm = cm.get_cmap(pdict["seq"], ncolors)
grid[grid.component_count_ref>0].plot(
    cax=cax,
    ax=ax,
    column="component_count_ref",
    legend=True,
    legend_kwds={'ticks': list(range(1, ncolors+1))},
    cmap=mycm,
    alpha=pdict["alpha_grid"],
)

# add no data patches
grid[grid["count_ref_edges"].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")

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')
ax.set_title(area_name + f": {reference_name} number of components in grid cells") 
ax.set_axis_off()

plot_func.save_fig(fig, ref_results_static_maps_fp + f"number_of_components_in_grid_cells_reference")

在这里插入图片描述

3.3 组件长度分布

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

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

自行车网络也可能介于两者之间,有几个大型组件作为异常值。

# Zipf plot of component lengths

set_renderer(renderer_plot)

components_length = {}

for i, c in enumerate(ref_components):
    c_length = 0
    for (u, v, l) in c.edges(data="length"):
        c_length += l
    components_length[i] = c_length

components_df = pd.DataFrame.from_dict(components_length, orient="index")
components_df.rename(columns={0: "component_length"}, inplace=True)

fig = plt.figure(figsize=pdict["fsbar_small"])
axes = fig.add_axes([0, 0, 1, 1])

axes.set_axisbelow(True)
axes.grid(True,which="major",ls="dotted")
yvals = sorted(list(components_df["component_length"] / 1000), reverse = True)
axes.scatter(
    x=[i+1 for i in range(len(components_df))],
    y=yvals,
    s=18,
    color=pdict["ref_base"],
)
axes.set_ylim(ymin=10**math.floor(math.log10(min(yvals))), ymax=10**math.ceil(math.log10(max(yvals))))
axes.set_xscale("log")
axes.set_yscale("log")

axes.set_ylabel("Component length [km]")
axes.set_xlabel("Component rank (largest to smallest)")
axes.set_title(area_name+": " + f"{reference_name} component length distribution")

plot_func.save_fig(fig, ref_results_plots_fp + "component_length_distribution_reference")

在这里插入图片描述

largest_cc = max(ref_components, key=len)

largest_cc_length = 0

for (u, v, l) in largest_cc.edges(data="length"):

    largest_cc_length += l

largest_cc_pct = largest_cc_length / components_df["component_length"].sum() * 100

print(
    f"The largest connected component contains {largest_cc_pct:.2f}% of the network length."
)

lcc_edges = ox.graph_to_gdfs(
    G=largest_cc, nodes=False, edges=True, node_geometry=False, fill_edge_geometry=False
)

# Export to GPKG
lcc_edges[["edge_id", "geometry"]].to_file(
    ref_results_data_fp + "largest_connected_component.gpkg"
)
The largest connected component contains 80.04% of the network length.

3.4 最大连通分量

# Plot of largest connected component

set_renderer(renderer_map)
fig, ax = plt.subplots(1, 1, figsize=pdict["fsmap"])
ref_edges_simplified.plot(ax=ax, color = pdict["base"], linewidth = 1.5, label = "All smaller components")
lcc_edges.plot(ax=ax, color=pdict["ref_base"], linewidth = 2, label = "Largest connected component")
grid.plot(ax=ax,alpha=0)
ax.set_axis_off()
ax.set_title(area_name + f": {reference_name} largest connected component")
ax.legend()

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 + f"largest_conn_comp_reference")

在这里插入图片描述

# Save plot without basemap for potential report titlepage

set_renderer(renderer_map)
fig, ax = plt.subplots(1, 1, figsize=pdict["fsmap"])
ref_edges_simplified.plot(ax=ax, color = pdict["base"], linewidth = 1.5, label = "Disconnected components")
lcc_edges.plot(ax=ax, color=pdict["ref_base"], linewidth = 2, label = "Largest connected component")
ax.set_axis_off()

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

3.5 缺少链接

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

User configurations

在分析组件之间潜在的缺失链接时,用户必须定义两个组件之间的距离被认为足够低以至于怀疑数字化错误的阈值。
# 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!")

print(f"Running analysis with component distance threshold of {component_min_distance} meters.")
Running analysis with component distance threshold of 10 meters.
component_gaps = eval_func.find_adjacent_components(
    components=ref_components,
    buffer_dist=component_min_distance,
    crs=study_crs,
    edge_id="edge_id",
)
component_gaps_gdf = gpd.GeoDataFrame.from_dict(
    component_gaps, orient="index", geometry="geometry", crs=study_crs
)

edge_ids = set(
    component_gaps_gdf["edge_id" + "_left"].to_list()
    + component_gaps_gdf["edge_id" + "_right"].to_list()
)

edge_ids = [int(i) for i in edge_ids]
edges_with_gaps = ref_edges_simplified.loc[ref_edges_simplified.edge_id.isin(edge_ids)]
# Save to csv
pd.DataFrame(edge_ids, columns=["edge_id"]).to_csv(
    ref_results_data_fp + f"component_gaps_edges_{component_min_distance}.csv",
    index=False,
)

component_gaps_gdf.to_file(
    ref_results_data_fp + f"component_gaps_centroids_{component_min_distance}.gpkg"
)
# Interactive plot of adjacent components

if len(component_gaps) > 0:

    simplified_edges_folium = plot_func.make_edgefeaturegroup(
        gdf=ref_edges_simplified,
        mycolor=pdict["ref_base"],
        myweight=pdict["line_base"],
        nametag="All edges",
        show_edges=True,
    )

    component_issues_edges_folium = plot_func.make_edgefeaturegroup(
        gdf=edges_with_gaps,
        mycolor=pdict["ref_emp"],
        myweight=pdict["line_emp"],
        nametag="Adjacent disconnected edges",
        show_edges=True,
    )

    component_issues_gaps_folium = plot_func.make_markerfeaturegroup(
        gdf=component_gaps_gdf, nametag="Component gaps", show_markers=True
    )

    m = plot_func.make_foliumplot(
        feature_groups=[
            simplified_edges_folium,
            component_issues_edges_folium,
            component_issues_gaps_folium,
        ],
        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"component_gaps_{component_min_distance}_reference.html")

    display(m)

在这里插入图片描述

if len(component_gaps) > 0:
    print("Interactive map saved at " + ref_results_inter_maps_fp.lstrip("../") + f"component_gaps_{component_min_distance}_reference.html")
else:
    print("There are no component gaps to plot.")
Interactive map saved at results/REFERENCE/cph_geodk/maps_interactive/component_gaps_10_reference.html

组件连接

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

ref_components_cell_count = eval_func.count_component_cell_reach(
    components_df, grid, "component_ids_ref"
)
grid["cells_reached_ref"] = grid["component_ids_ref"].apply(
    lambda x: eval_func.count_cells_reached(x, ref_components_cell_count)
    if x != ""
    else 0
)

grid["cells_reached_ref_pct"] = grid.apply(
    lambda x: np.round((x.cells_reached_ref / len(grid)) * 100, 2), axis=1
)

grid.loc[grid["cells_reached_ref_pct"] == 0, "cells_reached_ref_pct"] = np.NAN
# Plot percent of cells reachable

set_renderer(renderer_map)

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

# norm for color bars
cbnorm_reach = colors.Normalize(vmin=0, vmax=100)
cbnorm_reach_diff = colors.Normalize(vmin=-100, vmax=100)

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,
    column="cells_reached_ref_pct",
    legend=True,
    cmap=pdict["seq"],
    norm=cbnorm_reach,
    alpha=pdict["alpha_grid"],
)

ref_edges_simplified.plot(ax=ax, color=pdict["ref_emp"], linewidth=pdict["line_base"])

# add no data patches
grid[grid["count_ref_edges"].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")

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')
ax.set_title(area_name+f": {reference_name} percent of cells reachable")
ax.set_axis_off()

plot_func.save_fig(fig,ref_results_static_maps_fp + "percent_cells_reachable_grid_reference")

在这里插入图片描述

components_results = {}
components_results["component_count"] = len(ref_components)
components_results["largest_cc_pct_size"] = largest_cc_pct
components_results["largest_cc_length"] = largest_cc_length
components_results["count_component_gaps"] = len(component_gaps)

4.概括

summarize_results = {**density_results, **components_results}

summarize_results["count_dangling_nodes"] = len(dangling_nodes)
summarize_results["count_overshoots"] = len(overshoots)
summarize_results["count_undershoots"] = len(undershoot_nodes)

# Add total node count and total infrastructure length
summarize_results["total_nodes"] = len(ref_nodes_simplified)
summarize_results["total_length"] = ref_edges_simplified.infrastructure_length.sum() / 1000

summarize_results_df = pd.DataFrame.from_dict(summarize_results, orient="index")
summarize_results_df.rename({0: " "}, axis=1, inplace=True)

# Convert length to km
summarize_results_df.loc["largest_cc_length"] = (
    summarize_results_df.loc["largest_cc_length"] / 1000
)

summarize_results_df = summarize_results_df.reindex([
    'total_length',
    'protected_density_m_sqkm',
    'unprotected_density_m_sqkm',
    'mixed_density_m_sqkm',
    'edge_density_m_sqkm',
    'total_nodes',
    'count_dangling_nodes',
    'node_density_count_sqkm',
    'dangling_node_density_count_sqkm',
    'count_overshoots',
    'count_undershoots',
    'component_count',
    'largest_cc_length',
    'largest_cc_pct_size', 
    'count_component_gaps'
     ])

rename_metrics = {
    "total_length": "Total infrastructure length (km)",
    "total_nodes": "Nodes",
    "edge_density_m_sqkm": "Bicycle infrastructure density (m/km2)",
    "node_density_count_sqkm": "Nodes per km2",
    "dangling_node_density_count_sqkm": "Dangling nodes per km2",
    "protected_density_m_sqkm": "Protected bicycle infrastructure density (m/km2)",
    "unprotected_density_m_sqkm": "Unprotected bicycle infrastructure density (m/km2)",
    "mixed_density_m_sqkm": "Mixed protection bicycle infrastructure density (m/km2)",
    "component_count": "Components",
    "largest_cc_pct_size": "Largest component's share of network length",
    "largest_cc_length": "Length of largest component (km)",
    "count_component_gaps": "Component gaps",
    "count_dangling_nodes": "Dangling nodes",
    "count_overshoots": "Overshoots",
    "count_undershoots": "Undershoots",
}

summarize_results_df.rename(rename_metrics, inplace=True)
summarize_results_df.style.pipe(format_ref_style)
Intrinsic Quality Metrics - GeoDanmark data
 
Total infrastructure length (km)626
Protected bicycle infrastructure density (m/km2)2,999
Unprotected bicycle infrastructure density (m/km2)455
Mixed protection bicycle infrastructure density (m/km2)0
Bicycle infrastructure density (m/km2)3,454
Nodes4,125
Dangling nodes870
Nodes per km223
Dangling nodes per km25
Overshoots21
Undershoots11
Components204
Length of largest component (km)501
Largest component's share of network length80%
Component gaps52

5.保存结果

all_results = {}

all_results["network_density"] = density_results
all_results["count_overshoots"] = len(overshoots)
all_results["count_undershoots"] = len(undershoot_nodes)
all_results["dangling_node_count"] = len(dangling_nodes)
all_results["simplification_outcome"] = simplification_results
all_results["component_analysis"] = components_results

with open(ref_intrinsic_fp, "w") as outfile:
    json.dump(all_results, outfile)

# Save summary dataframe
summarize_results_df.to_csv(
    ref_results_data_fp + "intrinsic_summary_results.csv", index=True
)

# Save grid with results
with open(ref_intrinsic_grid_fp, "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:21:28

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

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

相关文章

WPF实现右键选定TreeViewItem

在WPF中,TreeView默认情况是不支持右键选定的,也就是说,当右键点击某节点时,是无法选中该节点的。当我们想在TreeViewItem中实现右键菜单时,往往希望在弹出菜单的同时选中该节点,以使得菜单针对选中的节点生…

数据结构 模拟实现二叉树(孩子表示法)

目录 一、二叉树的简单概念 (1)关于树的一些概念 (2)二叉树的一些概念及性质 定义二叉树的代码: 二、二叉树的方法实现 (1)createTree (2)preOrder (…

密码学(三)

文章目录 前言一、Software Attestation Overview二、Authenticated Key Agreement三、The Role of Software Measurement 前言 本文来自 Intel SGX Explained 请参考: 密码学(一) 密码学(二) 一、Software Attesta…

Javascript jQuery简介

✨前言✨ 1.如果代码对您有帮助 欢迎点赞👍收藏⭐哟 后面如有问题可以私信评论哟🗒️ 2.博主后面将持续更新哟😘🎉本章目录🎉 🥝一.jQuery简介🥥二.JQeury常用API🍇1.jQeury选择…

Eclipse插件UCdetector清理无用JAVA代码

下载插件 UCDetector - Browse /ucdetector at SourceForge.net 目前最新版本是2017年的2.0.0 保存 Eclipse/dropins 重启 操作 在项目上右键

JavaScript Web Worker用法指南

🧑‍🎓 个人主页:《爱蹦跶的大A阿》 🔥当前正在更新专栏:《VUE》 、《JavaScript保姆级教程》、《krpano》 ​ ​ ✨ 前言 Web Worker可以将耗时任务放到后台执行,避免阻塞UI。本文将详细介绍Web Worker的用法,让你…

【AWS】使用亚马逊云服务器创建EC2实例

目录 前言为什么选择 Amazon EC2 云服务器搭建 Amazon EC2 云服务器注册亚马逊账号登录控制台服务器配置免费套餐预览使用 Amazon EC2 云服务器打开服务器管理界面设置服务器区域填写实例名称选择服务器系统镜像选择实例类型创建密钥对网络设置配置存储启动实例查看实例 总结 前…

基于SSM中小型医院管理系统的设计与实现

末尾获取源码 开发语言:Java Java开发工具:JDK1.8 后端框架:SSM 前端:采用JSP技术开发 数据库:MySQL5.7和Navicat管理工具结合 服务器:Tomcat8.5 开发软件:IDEA / Eclipse 是否Maven项目&#x…

高质量训练数据助力大语言模型摆脱数据困境 | 景联文科技

目前,大语言模型的发展已经取得了显著的成果,如OpenAI的GPT系列模型、谷歌的BERT模型、百度的文心一言模型等。这些模型在文本生成、问答系统、对话生成、情感分析、摘要生成等方面都表现出了强大的能力,为自然语言处理领域带来了新的突破。 …

面向零信任架构的访问安全态势评估

伴随着“云大物移”等新兴 IT 技术的快速发展,企业数字化转型使得 IT 业务的网络环境更加复杂多样,企业数字资源的安全防护正面临着前所未有的压力与威胁。零信任安全架构放弃了传统基于“边界”的安全模型,以访问上下文的安全态势感知为基础…

jdk、tomcat、mysql的安装windows项目部署

文章目录 1、安装jdk2、tomcat安装3、MySQL安装3、外部访问数据库 1、安装jdk 1.双击运行jdk-8u144进行一个安装 2.一直点击下一步,到修改路径那个地方把他的存放路径改到D盘 3.找到我们刚刚修改的那个路径点进bin目录然后复制该路径进行一个环境变量配置4.找到我的…

Gogs - 管理协作者

Gogs - 管理协作者 References 仓库设置 管理协作者 权限设置 References [1] Yongqiang Cheng, https://yongqiang.blog.csdn.net/

41k+ stars 闪电般快速的开源搜索引擎 docker安装教程

目录 1.下载 2.启动 成功示例 3.创建索引 4.插入数据 4.1下载数据 4.2插入数据 4.3查看数据 5.官方地址 1.下载 docker pull getmeili/meilisearch:latest 2.启动 mkdir -p /opt/meili_datadocker run -it --rm \-p 7700:7700 \-v /opt/meili_data:/meili_data \ge…

SAP OData(二)Association

Entity之间用Association来表示关联关系,可以同CDS view中的Association一起理解。 我们在上次已经建好实体Item的基础上,再建一个Header,其方法的重写也参考Item即可,然后开始本篇的探索。 一,构建Association 1.1…

数据结构——二叉树(先序、中序、后序及层次四种遍历(C语言版))超详细~ (✧∇✧) Q_Q

目录 ​​​​​​​ 二叉树的定义: *特殊的二叉树: 二叉树的性质: 二叉树的声明: 二叉树的先序遍历: 二叉树的中序遍历: 二叉树的后序遍历: 二叉树的层序遍历: 二叉树的节…

AVL树(Java)

目录 一、什么是AVL树 二、AVL树的实现 AVL树的节点 AVL树的插入 AVL树的旋转 右单旋 左单旋 左右双旋 右左双旋 AVL树的验证 三、AVL树的性能分析 一、什么是AVL树 在了解什么是AVL树之前,我们先回顾二叉搜索树的概念 二叉搜索树(二叉排序…

pytorch学习笔记(八)

Sequential 看看搭建了这个能不能更容易管理,CIFAR-10数据集进行 看一下网络模型CIFAR-10模型 1 2 3 4 5 6 7 8 9 输入进过一次卷积,然后经过一次最大池化&#…

Stronghold Village

有了近2000个预制件和大量资产,您可以用基本的或先进的模块化预制件建造您的设防城镇或梦幻村庄,其中有许多定制选项和大量道具和物品 通过这个巨大的资源库,你可以创建村庄、城市、要塞、农村建筑、大教堂、城堡等。为你的环境提供高水平的细节,你可以创建外部装饰建筑,也…

Maven的安装和配置

国内Maven仓库之阿里云Aliyun仓库地址及设置 用过Maven的都知道Maven的方便便捷,但由于某些网络原因,访问国外的Maven仓库不便捷,好在阿里云搭建了国内的maven仓库。 需要使用的话,要在maven的settings.xml 文件里配置mirrors的子…

Wpf 使用 Prism 实战开发Day11

仓储(Repository)/工作单元(Unit Of Work)模式 仓储(rep):仓储接口定义了对实体类访问数据库及操作的方法。它统一管理数据访问的逻辑,并与业务逻辑层进行解耦。 简单的理解就是对访问数据库的一…