{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "eb174deb",
   "metadata": {},
   "source": [
    "# Python and VGI - 05/06: osmnx Network Analysis"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "218920ee-c9b9-41c1-81a5-ad34b92e91d5",
   "metadata": {},
   "source": [
    "***"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "13fbc479",
   "metadata": {},
   "source": [
    "osmnx is a package for downloading and analysing network OpenStreetMap data. This can be in particular helpful in city planning efforts and spatial quality analyses. \n",
    "\n",
    "Documentation: https://github.com/gboeing/osmnx and https://osmnx.readthedocs.io/en/stable/osmnx.html#\n",
    "\n",
    "Importing necessary modules"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "15a301dc",
   "metadata": {},
   "outputs": [],
   "source": [
    "import osmnx as ox\n",
    "import networkx as nx\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "02d54e07-844d-4b59-ab4a-303fc86bfeec",
   "metadata": {},
   "outputs": [],
   "source": [
    "# This only turns off distracting and irrelevant error messages. If your script runs into problems, don't execute this line and interpret the error messages.\n",
    "import warnings\n",
    "warnings.filterwarnings('ignore', category=DeprecationWarning, module='ipykernel.ipkernel')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f7f11f5e",
   "metadata": {},
   "source": [
    "## Specify the AOI"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b4f2f9b8",
   "metadata": {},
   "outputs": [],
   "source": [
    "place_name = \"Wattenscheid, Bochum, Germany\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8a401a19",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Set a variable for plotting the graph and get the type of graph.\n",
    "graph = ox.graph_from_place(place_name)\n",
    "type(graph)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9a77442c",
   "metadata": {},
   "source": [
    "#### Plot the graph of the desired place:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "968dbb4b",
   "metadata": {},
   "outputs": [],
   "source": [
    "fig, ax = ox.plot_graph(graph)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6eb5a56f",
   "metadata": {},
   "source": [
    "## Analyse street networks"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d7534223",
   "metadata": {},
   "outputs": [],
   "source": [
    "basic_stats = ox.basic_stats(graph)\n",
    "print(basic_stats['circuity_avg'])\n",
    "# this prints a basic information of the average circuity"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "59886c27",
   "metadata": {},
   "outputs": [],
   "source": [
    "# if needed, save the osm data as shapefile to the desired path\n",
    "#ox.save_graph_shapefile(graph, filepath ='./osmnx_output.shp')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "373114b2",
   "metadata": {},
   "source": [
    "#### Nodes include intersections, but they also include all the points along a single street segment where the street curves. \n",
    "Convert a MultiDiGraph to node and/or edge GeoDataFrames."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8d6f9784",
   "metadata": {},
   "outputs": [],
   "source": [
    "nodes, edges = ox.graph_to_gdfs(graph)\n",
    "nodes.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "604514d3",
   "metadata": {},
   "source": [
    "#### Route plotting of shortest paths using distance.nearest_nodes function"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "33758da7",
   "metadata": {},
   "outputs": [],
   "source": [
    "origin_node = ox.distance.nearest_nodes(graph, 7.12, 51.473)\n",
    "destination_node = ox.distance.nearest_nodes(graph, 7.11, 51.483)\n",
    "route = nx.shortest_path(graph,origin_node, destination_node)\n",
    "fig, ax = ox.plot_graph_route(graph, route, route_linewidth=6, node_size=0, bgcolor='k')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "217c38c1",
   "metadata": {},
   "source": [
    "#### Plot streets based on criteria"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5ca9c13a",
   "metadata": {},
   "outputs": [],
   "source": [
    "streets = edges.copy()\n",
    "streets['lanes'] = streets[\"lanes\"].astype(str)\n",
    "fig, ax = plt.subplots()\n",
    "# Plot the streets, colored by the type of street\n",
    "streets.plot(categorical=True,column='lanes', cmap='Spectral',  legend=False,\n",
    "           legend_kwds={'bbox_to_anchor':(1.3, 1.0), 'fontsize':10,'frameon':False},ax=ax)\n",
    "plt.title('Street lanes of Wattenscheid')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a60c8e25",
   "metadata": {},
   "source": [
    "## Analyse buildings"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5f9d3f3d",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Set a separate variable for buildings\n",
    "buildings = ox.geometries.geometries_from_place(place_name, tags = {'building': True})"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "25adb7bd",
   "metadata": {},
   "source": [
    "#### Plot the data using matplotlib"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ed233795",
   "metadata": {},
   "outputs": [],
   "source": [
    "fig, ax = plt.subplots()\n",
    "edges.plot(ax=ax, linewidth=1, edgecolor='#BC8F8F')\n",
    "buildings.plot(ax=ax, facecolor='red', alpha=0.7)\n",
    "# plt.tight_layout()\n",
    "plt.title('Buildings of Wattenscheid')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4e5d96ec",
   "metadata": {},
   "source": [
    "#### Calculate the area in projected units (meters) of each building footprint, then display first five "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "67aee2b0",
   "metadata": {},
   "outputs": [],
   "source": [
    "buildings_proj = ox.project_gdf(buildings)\n",
    "buildings_proj['area'] =  buildings_proj.area\n",
    "buildings_proj['area'].head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "76e67baf",
   "metadata": {},
   "outputs": [],
   "source": [
    "selection = buildings_proj.loc[buildings_proj['area']  >= 1000]\n",
    "len(selection.index)  # the length of the dataframe, shows the number of buildings in the selection"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9e6876cc",
   "metadata": {},
   "source": [
    "#### Plot the data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6f0fdd01",
   "metadata": {},
   "outputs": [],
   "source": [
    "fig, ax = plt.subplots()\n",
    "edges.plot(ax=ax, linewidth=1, edgecolor='#b0acac')\n",
    "buildings.plot(ax=ax, facecolor='red', alpha=0.7)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9ca8e48a",
   "metadata": {},
   "source": [
    "#### Plot buildings based on the area"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "71152376",
   "metadata": {},
   "outputs": [],
   "source": [
    "fig, ax = plt.subplots()\n",
    "selection.plot(ax=ax, legend=True,  column='area', \n",
    "               legend_kwds={'label': \"Area of building\",'orientation': \"vertical\"})\n",
    "plt.title('Buildings in Wattenscheid based on area')"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
