Skip to content

Commit

Permalink
Merge pull request #140 from benchmark-urbanism/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
songololo authored Jan 6, 2025
2 parents 8dcf915 + ef1a8ec commit cd3b416
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 11 deletions.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "cityseer"
version = '4.17.3'
version = '4.17.4'
description = "Computational tools for network-based pedestrian-scale urban analysis"
readme = "README.md"
requires-python = ">=3.10, <3.14"
Expand Down
30 changes: 20 additions & 10 deletions pysrc/cityseer/tools/io.py
Original file line number Diff line number Diff line change
Expand Up @@ -1251,25 +1251,35 @@ def network_structure_from_gpd(
for col in edges_cols:
if col not in edges_gdf.columns:
raise ValueError(f"Missing expected column in edges GDF: {col}")
# sort by network structure nodes and check for continuity
nodes_gdf_sorted = nodes_gdf.sort_values(by="ns_node_idx")
expected_range = list(range(len(nodes_gdf_sorted)))
actual_range = list(nodes_gdf_sorted["ns_node_idx"])
if actual_range != expected_range:
raise ValueError("ns_node_idx column should be continuous but seems to be missing rows.")
for nd_key, node_data in tqdm(nodes_gdf_sorted.iterrows(), disable=config.QUIET_MODE):
nodes_gdf["node_idx_mapping"] = -1
for nd_key, node_data in tqdm(nodes_gdf.iterrows(), disable=config.QUIET_MODE):
ns_node_idx = network_structure.add_node(
str(nd_key),
float(node_data["x"]),
float(node_data["y"]),
bool(node_data["live"]),
float(node_data["weight"]),
)
assert ns_node_idx == node_data["ns_node_idx"]
nodes_gdf.loc[nd_key, "node_idx_mapping"] = ns_node_idx # type: ignore
for _edge_key, edge_data in tqdm(edges_gdf.iterrows(), disable=config.QUIET_MODE):
# start node network structure idx
start_nx_nd_key = edge_data["nx_start_node_key"]
if start_nx_nd_key not in nodes_gdf.index.values:
logger.info(f"Skipping edge as start node nx key not found {start_nx_nd_key}")
continue
start_nd_data = nodes_gdf.loc[nodes_gdf.index == start_nx_nd_key]
start_ns_nd_key: int = start_nd_data["node_idx_mapping"].values[0]
# end node network structure idx
end_nx_nd_key = edge_data["nx_end_node_key"]
if end_nx_nd_key not in nodes_gdf.index.values:
logger.info(f"Skipping edge as end node nx key not found {end_nx_nd_key}")
continue
end_nd_data = nodes_gdf.loc[nodes_gdf.index == end_nx_nd_key]
end_ns_nd_key: int = end_nd_data["node_idx_mapping"].values[0]
# add edge
network_structure.add_edge(
int(edge_data["start_ns_node_idx"]),
int(edge_data["end_ns_node_idx"]),
start_ns_nd_key,
end_ns_nd_key,
int(edge_data["edge_idx"]),
str(edge_data["nx_start_node_key"]),
str(edge_data["nx_end_node_key"]),
Expand Down
36 changes: 36 additions & 0 deletions tests/tools/test_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -675,6 +675,42 @@ def test_network_structure_from_gpd(primal_graph):
assert edge_data.imp_factor == edge_data_round.imp_factor
assert edge_data.in_bearing == edge_data_round.in_bearing
assert edge_data.out_bearing == edge_data_round.out_bearing
# check that edges aren't added for missing nodes
nodes_pruned_gdf = nodes_gdf.iloc[1:]
network_structure_pruned = io.network_structure_from_gpd(nodes_pruned_gdf, edges_gdf)
assert network_structure_round.node_count() == 57
assert network_structure_round.edge_count == 158
assert network_structure_pruned.node_count() == 56
assert network_structure_pruned.edge_count == 152
# test robustness of centralities for pruned
for netw_struct, nd_gdf in [(network_structure_round, nodes_gdf), (network_structure_pruned, nodes_pruned_gdf)]:
nd_gdf = networks.node_centrality_shortest(
network_structure=netw_struct,
nodes_gdf=nd_gdf,
distances=[400],
compute_closeness=True,
compute_betweenness=True,
)
# test against underlying method
node_result = netw_struct.local_node_centrality_shortest(
distances=[400], compute_closeness=True, compute_betweenness=True
)
for measure_key, attr_key in [
("beta", "node_beta"),
("cycles", "node_cycles"),
("density", "node_density"),
("farness", "node_farness"),
("harmonic", "node_harmonic"),
("betweenness", "node_betweenness"),
("betweenness_beta", "node_betweenness_beta"),
]:
data_key = config.prep_gdf_key(measure_key, 400)
assert np.allclose(
nd_gdf[data_key],
getattr(node_result, attr_key)[400],
atol=config.ATOL,
rtol=config.RTOL,
)


def test_nx_from_cityseer_geopandas(primal_graph):
Expand Down

0 comments on commit cd3b416

Please sign in to comment.