Skip to content

Commit

Permalink
generic_edges_geopandas_from_nx
Browse files Browse the repository at this point in the history
  • Loading branch information
songololo committed Nov 18, 2023
1 parent 7173cdb commit 0c18b9d
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 1 deletion.
2 changes: 1 addition & 1 deletion pysrc/cityseer/tools/graphs.py
Original file line number Diff line number Diff line change
Expand Up @@ -670,7 +670,7 @@ def nx_consolidate_nodes(
The buffer distance to be used for consolidating nearby nodes. Defaults to 5.
neighbour_policy: str
Whether all nodes within the buffer distance are merged, or only "direct" or "indirect" neighbours. Defaults to
None.
None which will consider all nodes.
crawl: bool
Whether the algorithm will recursively explore neighbours of neighbours if those neighbours are within the
buffer distance from the prior node. Defaults to False.
Expand Down
45 changes: 45 additions & 0 deletions pysrc/cityseer/tools/io.py
Original file line number Diff line number Diff line change
Expand Up @@ -955,6 +955,51 @@ def nx_from_cityseer_geopandas(
return g_multi_copy


def generic_edges_geopandas_from_nx(
nx_multigraph: nx.MultiGraph,
crs: str | int,
) -> gpd.GeoDataFrame:
"""
Transpose a `cityseer` `networkX` `MultiGraph` into a `gpd.GeoDataFrame` representing the network edges.
Converts the `geom` attribute attached to each edge into a GeoPandas GeoDataFrame. This is useful when
inspecting or cleaning the network in QGIS. It can then be reimported with
[`nx_from_generic_geopandas`](#nx-from-generic-geopandas)
Parameters
----------
nx_multigraph: nx.MultiGraph
A `networkX` `MultiGraph` in a projected coordinate system, containing `x` and `y` node attributes, and `geom`
edge attributes containing `LineString` geoms.
crs: str | int
CRS for initialising the returned structures. This is used for initialising the GeoPandas
[`GeoDataFrame`](https://geopandas.org/en/stable/docs/reference/api/geopandas.GeoDataFrame.html#geopandas-geodataframe). # pylint: disable=line-too-long
Returns
-------
gpd.GeoDataFrame
A `gpd.GeoDataFrame` with `edge_idx` and `geom` attributes.
"""
if not isinstance(nx_multigraph, nx.MultiGraph):
raise TypeError("This method requires an undirected networkX MultiGraph.")
logger.info("Preparing node and edge arrays from networkX graph.")
agg_edge_data = []
# set edges
for start_nd_key, end_nd_key, edge_idx, edge_data in nx_multigraph.edges(keys=True, data=True):
agg_edge_data.append(
{
"start_nd_key": start_nd_key,
"end_nd_key": end_nd_key,
"edge_idx": edge_idx,
"geom": edge_data["geom"],
}
)
edges_gdf = gpd.GeoDataFrame(agg_edge_data, crs=crs, geometry="geom")

return edges_gdf


def nx_from_generic_geopandas(
gdf_network: gpd.GeoDataFrame, # type: ignore
) -> nx.MultiGraph:
Expand Down
11 changes: 11 additions & 0 deletions tests/tools/test_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -705,6 +705,17 @@ def test_nx_from_cityseer_geopandas(primal_graph):
assert G_round_trip_decomp.edges == G_decomposed.edges


def test_generic_edges_geopandas_from_nx(primal_graph):
""" """
edges_gdf = io.generic_edges_geopandas_from_nx(primal_graph, 3395)
assert len(edges_gdf) == len(primal_graph.edges)
for _idx, row_data in edges_gdf.iterrows():
assert (
row_data["geom"]
== primal_graph[row_data["start_nd_key"]][row_data["end_nd_key"]][row_data["edge_idx"]]["geom"]
)


def test_nx_from_generic_geopandas(primal_graph):
""" """
# generate a GDF for testing with
Expand Down

0 comments on commit 0c18b9d

Please sign in to comment.