How can I add buildings as nodes in a graph in osmnx?

Viewed 23

I am not very familiar with osmnx. I am trying to create graph that contains nodes in the center of each building, as well as street nodes. The following code shows the buildings (not as nodes) and street nodes together:

import networkx as nx
import osmnx as ox
from matplotlib import *
import matplotlib.pyplot as plt
from descartes import PolygonPatch
from shapely.geometry import MultiPolygon
from shapely.geometry import Polygon
from IPython.display import Image
import geopandas as gpd
from IPython.display import IFrame


place = "Piedmont, California, US"
G = ox.graph_from_place(place)

tags = {'building': True}
buildings = ox.geometries_from_place(place, tags)



# or plot street network and the entities' footprints together
fig, ax = ox.plot_footprints(buildings, alpha=0.4, show=False)
fig, ax = ox.plot_graph(G, ax=ax, node_size=10, edge_color="w", edge_linewidth=0.7)
1 Answers

I was able to do so by extracting centroids:

import networkx as nx
import osmnx as ox
from matplotlib import *
import matplotlib.pyplot as plt
from descartes import PolygonPatch
from shapely.geometry import MultiPolygon
from shapely.geometry import Polygon
from shapely.geometry import Point
from IPython.display import Image
import geopandas as gpd
from IPython.display import IFrame

# Specify the name that is used to seach for the data
place_name = "kirchberg, luxembourg, luxembourg"

# Fetch OSM street network from the location
graph = ox.graph_from_place(place_name)

nodes= ox.graph_to_gdfs(graph, nodes=True, edges=False)
edges= ox.graph_to_gdfs(graph, edges=True, nodes=False)
#ox.plot_graph(graph)


for i in range(len(list(graph.nodes))):
    node_id = list(graph.nodes)[i]
#    print(f"lon: {graph.nodes[node_id]['x']}, lat: {graph.nodes[node_id]['y']}")



#print(graph.nodes)


buildings = ox.geometries_from_place(place_name, tags={
'building':True
}) # Retrieve buildings from the area:


#buildings = buildings.to_crs(4326)


centroids = buildings.centroid

#print(dir(centroids))

lons = list(centroids.x)

lats = list(centroids.y)


building_coords = [[lons[i],lats[i]] for i in range(len(lons))]

print(building_coords)

dictionary = dict()

for i in range(len(building_coords)):
     node_id = i+1
     dictionary[node_id] = {
    'x': lons[i],
    'y': lats[i]
     }

tmp_list = []
for item_key, item_value in dictionary.items() :
  tmp_list.append({
    'geometry' : Point(item_value['x'], item_value['y']),
    'osmid': item_key,
    'y' : item_value['y'],
      'x' : item_value['x'],
   })
my_nodes = gpd.GeoDataFrame(tmp_list)

# just plot the building nodes
nodes = my_nodes

# or plot building nodes and street nodes
#nodes = nodes.append(my_nodes, ignore_index = True)

graph2 = ox.graph_from_gdfs(nodes, edges)
#fig, ax = ox.plot_footprints(buildings, alpha=0.4, show=False)
#ox.plot_graph(graph2)
ox.plot_graph(graph2, node_size=10, edge_color="grey", node_color="green", edge_linewidth=0.7, bgcolor="white")

credit to Debjit Bhowmick for their code in this answer.

Related