{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "\n\n# Path and skimming\n\nIn this example, we show how to perform path computation and network skimming\nfor the Sioux Falls example model.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Imports\nfrom uuid import uuid4\nfrom tempfile import gettempdir\nfrom os.path import join\nfrom aequilibrae.utils.create_example import create_example\n\n# We create the example project inside our temp folder\nfldr = join(gettempdir(), uuid4().hex)\n\nproject = create_example(fldr)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "import logging\nimport sys\n\n# We the project opens, we can tell the logger to direct all messages to the terminal as well\nlogger = project.logger\nstdout_handler = logging.StreamHandler(sys.stdout)\nformatter = logging.Formatter(\"%(asctime)s;%(levelname)s ; %(message)s\")\nstdout_handler.setFormatter(formatter)\nlogger.addHandler(stdout_handler)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Path Computation\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "from aequilibrae.paths import PathResults" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We build all graphs\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "project.network.build_graphs()\n# We get warnings that several fields in the project are filled with NaNs. \n# This is true, but we won't use those fields." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We grab the graph for cars\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "graph = project.network.graphs[\"c\"]\n\n# we also see what graphs are available\n# project.network.graphs.keys()\n\n# let's say we want to minimize the distance\ngraph.set_graph(\"distance\")\n\n# And will skim time and distance while we are at it\ngraph.set_skimming([\"free_flow_time\", \"distance\"])\n\n# And we will allow paths to be computed going through other centroids/centroid connectors\n# required for the Sioux Falls network, as all nodes are centroids\n# BE CAREFUL WITH THIS SETTING\ngraph.set_blocked_centroid_flows(False)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's instantiate a path results object and prepare it to work with the graph\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "res = PathResults()\nres.prepare(graph)\n\n# compute a path from node 8 to 13\nres.compute_path(8, 4)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# We can get the sequence of nodes we traverse\nres.path_nodes" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# We can get the link sequence we traverse\nres.path" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# We can get the mileposts for our sequence of nodes\nres.milepost" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# If we want to compute the path for a different destination and the same origin, we can just do this\n# It is way faster when you have large networks\nres.update_trace(13)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "res.path_nodes" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If you want to show the path in Python\nWe do NOT recommend this, though.... It is very slow for real networks\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "import matplotlib.pyplot as plt\nfrom shapely.ops import linemerge" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "links = project.network.links\n\n# We plot the entire network\ncurr = project.conn.cursor()\ncurr.execute(\"Select link_id from links;\")\n\nfor lid in curr.fetchall():\n geo = links.get(lid[0]).geometry\n plt.plot(*geo.xy, color=\"red\")\n\npath_geometry = linemerge(links.get(lid).geometry for lid in res.path)\nplt.plot(*path_geometry.xy, color=\"blue\", linestyle=\"dashed\", linewidth=2)\nplt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Now to skimming\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "from aequilibrae.paths import NetworkSkimming" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "But let's say we only want a skim matrix for nodes 1, 3, 6 & 8\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "import numpy as np\n\ngraph.prepare_graph(np.array([1, 3, 6, 8]))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# And run the skimming\nskm = NetworkSkimming(graph)\nskm.execute()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The result is an AequilibraEMatrix object\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "skims = skm.results.skims\n\n# Which we can manipulate directly from its temp file, if we wish\nskims.matrices" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Or access each matrix\nskims.free_flow_time" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# We can save it to the project if we want\nskm.save_to_project(\"base_skims\")\n\n# We can also retrieve this skim record to write something to its description\nmatrices = project.matrices\nmat_record = matrices.get_record(\"base_skims\")\nmat_record.description = \"minimized FF travel time while also skimming distance for just a few nodes\"\nmat_record.save()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "project.close()" ] } ], "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.9.18" } }, "nbformat": 4, "nbformat_minor": 0 }