Отсечение графа networkx по полигону с географической привязкой - PullRequest
0 голосов
/ 17 февраля 2020

Я запускаю al oop, который вычисляет networkx.classes.multidigraph.MultiDiGraph для каждой строки (окрестности) списка GeoDataFrames (городов). Затем он вычисляет некоторую статистику для каждой строки и записывает файл на диск. Проблема в том, что l oop очень долго вычисляется, потому что график вычисляется для каждой строки.

Я хочу ускорить l oop путем вычисления графика для всего GeoDataFrame, а затем вырезания графика в каждой строке (каждая строка имеет многоугольник). Вы можете сделать это для GeoSeries с geopandas.clip. Однако, похоже, что для графа networkx не существует эквивалента geopandas.clip.

  • Кто-нибудь знает способ обрезки графа networkx?

  • В качестве альтернативы, какие существуют другие методы для ускорения моего l oop.

  • Примечание : отсечение сработало бы, если бы я мог преобразовать график networkx в pandas объект. К сожалению, я думаю, что невозможно сохранить свойства, на которые действует osmnx, когда граф преобразуется в объект pandas. Если я не прав, скажите, пожалуйста.

Вот мой начальный код:

import osmnx as ox
import pandas as pd
import geopandas as gpd
import os

path="C:/folder/"
files=[os.path.join(path, f) for f in os.listdir(path)]

for i in range(0,2):
    city=gpd.read_file(files[i])
    circ=[]

    for i in range(0,181):
        graph_for_row=ox.graph_from_polygon(city.geometry[i])
        #above is the long command
        stat = ox.basic_stats(graph_for_row)
        circ.append(stat['circuity_avg'])

    circ=pd.Series(circ)
    merged.append(pd.concat([city, circ], axis=1))

for i in (range(0,len(merged))):
    with open(geofiles[i], 'w') as f:
        f.write(merged[i].to_json())

Вот новый l oop, к которому я стремлюсь:

clipped_graph=[]

for i in range(0,2):
    city=gpd.read_file(files[i])
    whole_city=city.unary_union
    graph=ox.graph_from_polygon(whole_city)
    clipped_graph.append(gpd.clip(graph, city.geometry))#this line 
    #does not work since 'graph' is a networkx object, not
    #a GeoDataFrame or GeoSeries
    circ=[]

    for i in range(0,181)
        stat = ox.basic_stats(clipped_graph[i])
        circ.append(stat['circuity_avg'])

    circ=pd.Series(circ)
    merged.append(pd.concat([city, circ], axis=1))

for i in (range(0,len(merged))):
    with open(geofiles[i], 'w') as f:
        f.write(merged[i].to_json())

1 Ответ

1 голос
/ 18 февраля 2020

Вы можете использовать свои отдельные многоугольники для (пространственного) пересечения узлов графа, а затем использовать эти узлы, чтобы вызвать подграф . MWE:

import osmnx as ox
ox.config(use_cache=True, log_console=True)

# load a shapefile of polygons as geodataframe using geopandas
# here i just get 3 cities from OSM to make example reproducible without a shapefile
places = ['Cudahy, CA, USA', 'Bell, CA, USA', 'Maywood, CA, USA']
gdf = ox.gdf_from_places(places)

# get a graph of the union of their boundaries, then extract nodes as geodataframe
G = ox.graph_from_polygon(gdf.unary_union, network_type='drive')
nodes = ox.graph_to_gdfs(G, edges=False)

# for each city polygon, find intersecting nodes then induce subgraph
for polygon in gdf['geometry']:
    intersecting_nodes = nodes[nodes.intersects(polygon)].index
    G_sub = G.subgraph(intersecting_nodes)
    fig, ax = ox.plot_graph(G_sub)
...