Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updates for v1.9.2 in prep for v2 #84

Merged
merged 4 commits into from
Apr 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ channels:
- conda-forge
dependencies:
- jupyterlab
- osmnx=1.9.1
- osmnx=1.9.2
- pillow
- pre-commit
- python=3.11.*
Expand Down
12 changes: 6 additions & 6 deletions notebooks/00-osmnx-features-demo.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,10 @@
"outputs": [],
"source": [
"# convert your MultiDiGraph to an undirected MultiGraph\n",
"M = ox.utils_graph.get_undirected(G)\n",
"M = ox.convert.to_undirected(G)\n",
"\n",
"# convert your MultiDiGraph to a DiGraph without parallel edges\n",
"D = ox.utils_graph.get_digraph(G)"
"D = ox.convert.to_digraph(G)"
]
},
{
Expand Down Expand Up @@ -214,8 +214,8 @@
"outputs": [],
"source": [
"# impute missing edge speeds and calculate edge travel times with the speed module\n",
"G = ox.speed.add_edge_speeds(G)\n",
"G = ox.speed.add_edge_travel_times(G)"
"G = ox.routing.add_edge_speeds(G)\n",
"G = ox.routing.add_edge_travel_times(G)"
]
},
{
Expand Down Expand Up @@ -247,7 +247,7 @@
"outputs": [],
"source": [
"# how long is our route in meters?\n",
"edge_lengths = ox.utils_graph.route_to_gdf(G, route)[\"length\"]\n",
"edge_lengths = ox.routing.route_to_gdf(G, route)[\"length\"]\n",
"round(sum(edge_lengths))"
]
},
Expand Down Expand Up @@ -455,7 +455,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.6"
"version": "3.11.8"
}
},
"nbformat": 4,
Expand Down
10 changes: 5 additions & 5 deletions notebooks/01-overview-osmnx.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
"source": [
"# get the boundary polygon for manhattan, project it, and plot it\n",
"city = ox.geocode_to_gdf(\"Manhattan, New York, USA\")\n",
"city_proj = ox.project_gdf(city)\n",
"city_proj = ox.projection.project_gdf(city)\n",
"ax = city_proj.plot(fc=\"gray\", ec=\"none\")\n",
"_ = ax.axis(\"off\")"
]
Expand All @@ -88,7 +88,7 @@
"]\n",
"east_bay = ox.geocode_to_gdf(place_names)\n",
"east_bay.to_file(\"./data/east_bay.gpkg\", driver=\"GPKG\")\n",
"east_bay = ox.project_gdf(east_bay)\n",
"east_bay = ox.projection.project_gdf(east_bay)\n",
"ax = east_bay.plot(fc=\"gray\", ec=\"none\")\n",
"_ = ax.axis(\"off\")"
]
Expand Down Expand Up @@ -143,10 +143,10 @@
"outputs": [],
"source": [
"# define a bounding box in San Francisco\n",
"north, south, east, west = 37.79, 37.78, -122.41, -122.43\n",
"bbox = 37.79, 37.78, -122.41, -122.43\n",
"\n",
"# create network from that bounding box\n",
"G = ox.graph_from_bbox(north, south, east, west, network_type=\"drive_service\")"
"G = ox.graph_from_bbox(bbox=bbox, network_type=\"drive_service\")"
]
},
{
Expand Down Expand Up @@ -485,7 +485,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.6"
"version": "3.11.8"
}
},
"nbformat": 4,
Expand Down
14 changes: 7 additions & 7 deletions notebooks/02-routing-speed-time.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
"outputs": [],
"source": [
"# randomly sample n points spatially-constrained to the network's geometry\n",
"points = ox.utils_geo.sample_points(ox.get_undirected(Gp), n=100)\n",
"points = ox.utils_geo.sample_points(ox.convert.to_undirected(Gp), n=100)\n",
"X = points.x.values\n",
"Y = points.y.values\n",
"X0 = X.mean()\n",
Expand Down Expand Up @@ -190,7 +190,7 @@
"# same thing again, but this time pass in a few default speed values (km/hour)\n",
"# to fill in edges with missing `maxspeed` from OSM\n",
"hwy_speeds = {\"residential\": 35, \"secondary\": 50, \"tertiary\": 60}\n",
"G = ox.add_edge_speeds(G, hwy_speeds)\n",
"G = ox.add_edge_speeds(G, hwy_speeds=hwy_speeds)\n",
"G = ox.add_edge_travel_times(G)"
]
},
Expand Down Expand Up @@ -226,10 +226,10 @@
"outputs": [],
"source": [
"# compare the two routes\n",
"route1_length = int(sum(ox.utils_graph.route_to_gdf(G, route1, \"length\")[\"length\"]))\n",
"route2_length = int(sum(ox.utils_graph.route_to_gdf(G, route2, \"length\")[\"length\"]))\n",
"route1_time = int(sum(ox.utils_graph.route_to_gdf(G, route1, \"travel_time\")[\"travel_time\"]))\n",
"route2_time = int(sum(ox.utils_graph.route_to_gdf(G, route2, \"travel_time\")[\"travel_time\"]))\n",
"route1_length = int(sum(ox.routing.route_to_gdf(G, route1, weight=\"length\")[\"length\"]))\n",
"route2_length = int(sum(ox.routing.route_to_gdf(G, route2, weight=\"length\")[\"length\"]))\n",
"route1_time = int(sum(ox.routing.route_to_gdf(G, route1, weight=\"travel_time\")[\"travel_time\"]))\n",
"route2_time = int(sum(ox.routing.route_to_gdf(G, route2, weight=\"travel_time\")[\"travel_time\"]))\n",
"print(\"Route 1 is\", route1_length, \"meters and takes\", route1_time, \"seconds.\")\n",
"print(\"Route 2 is\", route2_length, \"meters and takes\", route2_time, \"seconds.\")"
]
Expand Down Expand Up @@ -395,7 +395,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.6"
"version": "3.11.8"
}
},
"nbformat": 4,
Expand Down
12 changes: 6 additions & 6 deletions notebooks/03-graph-place-queries.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,8 @@
")\n",
"\n",
"# the city is a very small part of the county\n",
"alameda1 = ox.project_gdf(alameda1)\n",
"alameda2 = ox.project_gdf(alameda2)\n",
"alameda1 = ox.projection.project_gdf(alameda1)\n",
"alameda2 = ox.projection.project_gdf(alameda2)\n",
"alameda2.area.iloc[0] / alameda1.area.iloc[0]"
]
},
Expand Down Expand Up @@ -173,7 +173,7 @@
"source": [
"# you can pass multiple queries with mixed types (dicts and strings)\n",
"mx_gt_tx = ox.geocode_to_gdf([{\"country\": \"Mexico\"}, \"Guatemala\", {\"state\": \"Texas\"}])\n",
"mx_gt_tx = ox.project_gdf(mx_gt_tx)\n",
"mx_gt_tx = ox.projection.project_gdf(mx_gt_tx)\n",
"ax = mx_gt_tx.plot(fc=\"gray\", ec=\"w\")\n",
"_ = ax.axis(\"off\")"
]
Expand All @@ -192,7 +192,7 @@
"outputs": [],
"source": [
"france = ox.geocode_to_gdf(\"France\")\n",
"france = ox.project_gdf(france)\n",
"france = ox.projection.project_gdf(france)\n",
"ax = france.plot(fc=\"gray\", ec=\"none\")\n",
"_ = ax.axis(\"off\")"
]
Expand All @@ -203,7 +203,7 @@
"metadata": {},
"outputs": [],
"source": [
"france = ox.project_gdf(ox.geocode_to_gdf(\"R1403916\", by_osmid=True))\n",
"france = ox.projection.project_gdf(ox.geocode_to_gdf(\"R1403916\", by_osmid=True))\n",
"ax = france.plot(fc=\"gray\", ec=\"none\")\n",
"_ = ax.axis(\"off\")"
]
Expand Down Expand Up @@ -343,7 +343,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.6"
"version": "3.11.8"
}
},
"nbformat": 4,
Expand Down
88 changes: 3 additions & 85 deletions notebooks/04-simplify-graph-consolidate-nodes.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@
"outputs": [],
"source": [
"# simplify network with strict mode turned off\n",
"G3 = ox.simplify_graph(G.copy(), strict=False)\n",
"G3 = ox.simplify_graph(G.copy(), edge_attrs_differ=[\"osmid\"])\n",
"fig, ax = ox.plot_graph(G3, node_color=\"r\")"
]
},
Expand All @@ -206,89 +206,7 @@
"\n",
"This is related to simplification. OSMnx by default (with clean_periphery parameter equal to True) buffers the area you request by 0.5km, and then retrieves the street network within this larger, buffered area. Then it simplifies the topology so that nodes represent intersections of streets (rather than including all the interstitial OSM nodes). Then it calculates the (undirected) degree of each node in this larger network. Next it truncates this network by the actual area you requested (either by bounding box, or by polygon). Finally it saves a dictionary of node degree values as a graph attribute.\n",
"\n",
"This has two primary benefits. First, it cleans up stray false edges around the periphery. If clean_periphery=False, peripheral non-intersection nodes within the requested area appear to be cul-de-sacs, as the rest of the edge leading to an intersection outside the area is ignored. If clean_periphery=True, the larger graph is first created, allowing simplification of such edges to their true intersections, allowing their entirety to be pruned after truncating down to the actual requested area. Second, it gives accurate node degrees by both a) counting node neighbors even if they fall outside the retained network (so you don't claim a degree-4 node is degree-2 because only 2 of its neighbors lie within the area), and b) not counting all those stray false edges' terminus nodes as cul-de-sacs that otherwise grossly inflate the count of nodes with degree=1, even though these nodes are really just interstitial nodes in the middle of a chopped-off street segment between intersections.\n",
"\n",
"See two examples below."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# get some bbox\n",
"bbox = ox.utils_geo.bbox_from_point((45.518698, -122.679964), dist=300)\n",
"north, south, east, west = bbox"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"G = ox.graph_from_bbox(north, south, east, west, network_type=\"drive\", clean_periphery=False)\n",
"fig, ax = ox.plot_graph(G, node_color=\"r\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# the node degree distribution for this graph has many false cul-de-sacs\n",
"k = dict(G.degree())\n",
"{n: list(k.values()).count(n) for n in range(max(k.values()) + 1)}"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Above, notice all the peripheral stray edge stubs. Below, notice these are cleaned up and that the node degrees are accurate with regards to the wider street network that may extend beyond the limits of the requested area."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"G = ox.graph_from_bbox(north, south, east, west, network_type=\"drive\")\n",
"fig, ax = ox.plot_graph(G, node_color=\"r\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# the streets per node distribution for this cleaned up graph is more accurate\n",
"# dict keys = count of streets emanating from the node (ie, intersections and dead-ends)\n",
"# dict vals = number of nodes with that count\n",
"k = nx.get_node_attributes(G, \"street_count\")\n",
"{n: list(k.values()).count(n) for n in range(max(k.values()) + 1)}"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"A final example. Compare the network below to the ones in the section above. It has the stray peripheral edges cleaned up. Also notice toward the bottom left, two interstitial nodes remain in that east-west street. Why? These are actually intersections, but their (southbound) edges were removed because these edges' next intersections were south of the requested area's boundaries. However, OSMnx correctly kept these nodes in the graph because they are in fact intersections and should be counted in measures of intersection density, etc."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"location_point = (33.299896, -111.831638)\n",
"G = ox.graph_from_point(location_point, dist=500, simplify=True)\n",
"fig, ax = ox.plot_graph(G, node_color=\"r\")"
"This has two primary benefits. First, it cleans up stray false edges around the periphery. If clean_periphery=False, peripheral non-intersection nodes within the requested area appear to be cul-de-sacs, as the rest of the edge leading to an intersection outside the area is ignored. If clean_periphery=True, the larger graph is first created, allowing simplification of such edges to their true intersections, allowing their entirety to be pruned after truncating down to the actual requested area. Second, it gives accurate node degrees by both a) counting node neighbors even if they fall outside the retained network (so you don't claim a degree-4 node is degree-2 because only 2 of its neighbors lie within the area), and b) not counting all those stray false edges' terminus nodes as cul-de-sacs that otherwise grossly inflate the count of nodes with degree=1, even though these nodes are really just interstitial nodes in the middle of a chopped-off street segment between intersections."
]
},
{
Expand Down Expand Up @@ -316,7 +234,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.6"
"version": "3.11.8"
}
},
"nbformat": 4,
Expand Down
6 changes: 3 additions & 3 deletions notebooks/05-save-load-networks.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"## Save .osm XML files\n",
"## Save OSM XML files\n",
"\n",
"To save your graph to disk as a .osm formatted XML file, ensure that you created the graph with `ox.settings.all_oneway=True` for `save_graph_xml` to work properly. See docstring for details.\n",
"\n",
Expand All @@ -154,7 +154,7 @@
"# save graph to disk as .osm xml file\n",
"ox.settings.all_oneway = True\n",
"ox.settings.log_console = True\n",
"G = ox.graph_from_place(\"Piedmont, California, USA\", network_type=\"drive\")\n",
"G = ox.graph_from_place(\"Piedmont, California, USA\", network_type=\"drive\", simplify=False)\n",
"ox.save_graph_xml(G, filepath=\"./data/piedmont.osm\")"
]
},
Expand Down Expand Up @@ -183,7 +183,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.6"
"version": "3.11.8"
}
},
"nbformat": 4,
Expand Down
6 changes: 3 additions & 3 deletions notebooks/06-stats-indicators-centrality.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
"# get the street network for a place, and its area in square meters\n",
"place = \"Piedmont, California, USA\"\n",
"gdf = ox.geocode_to_gdf(place)\n",
"area = ox.project_gdf(gdf).unary_union.area\n",
"area = ox.projection.project_gdf(gdf).unary_union.area\n",
"G = ox.graph_from_place(place, network_type=\"drive\")"
]
},
Expand Down Expand Up @@ -119,7 +119,7 @@
"outputs": [],
"source": [
"# calculate betweenness with a digraph of G (ie, no parallel edges)\n",
"bc = nx.betweenness_centrality(ox.get_digraph(G), weight=\"length\")\n",
"bc = nx.betweenness_centrality(ox.convert.to_digraph(G), weight=\"length\")\n",
"max_node, max_bc = max(bc.items(), key=lambda x: x[1])\n",
"max_node, max_bc"
]
Expand Down Expand Up @@ -193,7 +193,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.6"
"version": "3.11.8"
}
},
"nbformat": 4,
Expand Down
2 changes: 1 addition & 1 deletion notebooks/07-plot-graph-over-shape.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.6"
"version": "3.11.8"
}
},
"nbformat": 4,
Expand Down
2 changes: 1 addition & 1 deletion notebooks/08-custom-filters-infrastructure.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.6"
"version": "3.11.8"
}
},
"nbformat": 4,
Expand Down
Loading