0

I have used OSmnx's osmnx.graph_project to first project my graph onto UTM coordinate system in order to use consolidate_intersections function and then ox.project_graph(G_proj_ConsolidateIntersection, to_crs='epsg:4326') to project it onto Latitude-Longitude coordinate system in order to make use of ox.get_nearest_nodes. This last projection takes a long time (5 minute), while the first projection is done within seconds. Is there a better and faster way of projection onto epsg:4326? I have looked at this answer but when I execute this line gdf = gpd.GeoDataFrame(geometry=intersections), I get the following error:

ValueError: Unknown column

Here is an example from the extreme side (the graph I am working it is smaller but I hope it illustrates my point):

import osmnx as ox
G = ox.graph_from_place('Edmonton, Canada', network_type='drive', simplify=False)
# 39.1 s

G_proj = ox.project_graph(G)
# 15.9 s

G_proj_ConsolidateIntersection = ox.consolidate_intersections(G_proj)
# 14 min 45 s

G_proj_ConsolidateIntersection_LatLon = ox.project_graph(G_proj_ConsolidateIntersection, to_crs='epsg:4326')
# 44 min 35 s

Also gpd.GeoDataFrame(geometry=G_proj_ConsolidateIntersection) raises the Unknown column error.

Rob
  • 241
  • 1
  • 14
  • Please provide a complete minimal reproducible example and I'll take a look. – gboeing Jun 19 '20 at 19:14
  • @gboeing just updated the question with an example. Please let me know if you need more information. – Rob Jun 19 '20 at 20:44

1 Answers1

2

Two things. First, make sure you're using the latest version of OSMnx as there were significant performance enhancements in the prior release. Second, this will all be much, much faster if you simplify your graph first.

But more importantly, it doesn't really make sense to consolidate intersections unless you have already simplified your graph, because the concept of real-world "intersections" is meaningless in an unsimplified (expansion) graph. Only when a graph is simplified do the model's nodes map to the real-world concepts of intersections and dead-ends. See the docs and related literature for details.

Here's a code snippet comparing your original timings (left) vs my simplified timings (right):

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

G = ox.graph_from_place('Edmonton, Canada', network_type='drive', simplify=True)
# 39.1 s vs 18.2 s

G_proj = ox.project_graph(G)
# 15.9 s vs 8.9 s

G_proj_con = ox.consolidate_intersections(G_proj)
# 14 m 45 s vs 24.2 s

G_con = ox.project_graph(G_proj_con, to_crs='epsg:4326')
# 44 m 35 s vs 6.4 s

EDIT: I just re-ran the code snippet I shared above but changed simplify=False, and my timings using the latest release are still much faster than what you had seen. For example, the final 2 lines of code above finished in 6m 20s and 12s respectively (compared to your 14m 45s and 44m 35s timings).

gboeing
  • 5,691
  • 2
  • 15
  • 41
  • Thank you for your detailed answer. I was using version 0.13.0. I will update the package and check the performance. The reason I pass in `simplify=False` first is because I want to divide street with curvatures into more pieces and this is something that gets lost with `simplify=True`: `# finally remove all the interstitial nodes between the new edges G.remove_nodes_from(set(all_nodes_to_remove))` Using `consolidate_intersections` then helps to clean up the intersections while preserving more nodes between intersections. If there is another way of achieving this, please let me know. – Rob Jun 19 '20 at 21:48
  • I ran my code with version 0.14.1 and it is a lot faster. On the graph I am currently working, it used to take 5 minutes to run `ox.consolidate_intersections(G_proj)`, now it is done under 2 minutes. Projecting it to `epsg:4326` is also done 9 seconds. The new update is much faster. – Rob Jun 23 '20 at 00:36
  • 1
    Glad to hear it. – gboeing Jun 23 '20 at 00:55