import geopandas import networkx import numpy def get_frames(ways: geopandas.GeoDataFrame): """Extract nodes, edges, and relations from a GeoDataFrame of ways. Args: ways (geopandas.GeoDataFrame): A GeoDataFrame containing information about ways. Returns: nodes (geopandas.GeoDataFrame): A GeoDataFrame containing node geometries. edges (geopandas.GeoDataFrame): A GeoDataFrame containing ways information. rel (geopandas.GeoDataFrame): A GeoDataFrame representing relations between nodes and edges. """ edges = ways.explode(index_parts=False)[["id", "name", "geometry"]] edges.index.name = "way_id" edges = edges.reset_index() nodes = geopandas.GeoDataFrame({"geometry": edges.boundary.explode(index_parts=False).geometry.unique()}) nodes.index.name = "node_id" nodes.reset_index(inplace=True) rel = edges.sjoin(nodes).to_crs("epsg:2154") return nodes, edges, rel def get(ways: geopandas.GeoDataFrame) -> networkx.Graph: """ Convert a GeoDataFrame of ways into a networkx Graph. Args: ways (geopandas.GeoDataFrame): A GeoDataFrame containing information about ways. Returns: networkx.Graph: A networkx Graph representing the geographical network. """ nodes, edges, rel = get_frames(ways) graph = networkx.Graph() for node in rel['node_id'].unique(): graph.add_node(node, shape=nodes.loc[node, "geometry"]) for idx in rel['way_id'].unique(): node_id1, node_id2 = rel.loc[idx]['node_id'] way = edges.loc[idx] graph.add_edge( node_id1, node_id2, weight=way.geometry.length, shape=way.geometry, id_=idx, ) return graph def weighted_adjacency_matrix(graph: networkx.Graph) -> numpy.ndarray: """Generate the weighted adjacency matrix from a networkx Graph. Args: graph (networkx.Graph): A networkx Graph representing the network. Returns: numpy.ndarray: A NumPy array representing the weighted adjacency matrix. """ weights = numpy.full((graph.number_of_nodes(),)*2, numpy.inf) numpy.fill_diagonal(weights, 0., wrap=False) for i in graph: for j in graph[i]: weights[i, j] = graph[i][j]["weight"] return weights