.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "_auto_examples/public_transport/plot_public_transit_assignment.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code. .. rst-class:: sphx-glr-example-title .. _sphx_glr__auto_examples_public_transport_plot_public_transit_assignment.py: .. _example_transit_asssignment: Public transport assignment with Optimal Strategies =================================================== In this example, perform a Spiess & Florian assignment. `Click here `_ to check out the paper. We use data from Coquimbo, a city in La Serena Metropolitan Area in Chile. .. GENERATED FROM PYTHON SOURCE LINES 13-16 .. admonition:: References * :doc:`../../public_transport` .. GENERATED FROM PYTHON SOURCE LINES 18-26 .. seealso:: Several functions, methods, classes and modules are used in this example: * :func:`aequilibrae.transit.Transit` * :func:`aequilibrae.transit.TransitGraphBuilder` * :func:`aequilibrae.paths.TransitClass` * :func:`aequilibrae.paths.TransitAssignment` * :func:`aequilibrae.matrix.AequilibraeMatrix` .. GENERATED FROM PYTHON SOURCE LINES 28-37 .. code-block:: Python # Imports for example construction from uuid import uuid4 from os.path import join from tempfile import gettempdir from aequilibrae.transit import Transit from aequilibrae.utils.create_example import create_example .. GENERATED FROM PYTHON SOURCE LINES 39-40 Let's create an empty project on an arbitrary folder. .. GENERATED FROM PYTHON SOURCE LINES 40-44 .. code-block:: Python fldr = join(gettempdir(), uuid4().hex) project = create_example(fldr, "coquimbo") .. GENERATED FROM PYTHON SOURCE LINES 45-46 Let's create our ``Transit`` object. .. GENERATED FROM PYTHON SOURCE LINES 46-48 .. code-block:: Python data = Transit(project) .. GENERATED FROM PYTHON SOURCE LINES 49-57 Graph building -------------- Let's build the transit network. We'll disable ``outer_stop_transfers`` and ``walking_edges`` because Coquimbo doesn't have any parent stations. For the OD connections we'll use the ``overlapping_regions`` method and create some accurate line geometry later. Creating the graph should only take a moment. By default zoning information is pulled from the project network. If you have your own zoning information add it using ``graph.add_zones(zones)`` then ``graph.create_graph()``. .. GENERATED FROM PYTHON SOURCE LINES 59-64 .. code-block:: Python graph = data.create_graph(with_outer_stop_transfers=False, with_walking_edges=False, blocking_centroid_flows=False, connector_method="overlapping_regions") # We drop geometry here for the sake of display. graph.vertices.drop(columns="geometry") .. raw:: html
node_id node_type stop_id line_id line_seg_idx taz_id
0 1 od -1 1
1 2 od -1 2
2 3 od -1 3
3 4 od -1 4
4 5 od -1 5
... ... ... ... ... ... ...
362 363 alighting 10000000075 1_10001003000 31 -1
363 364 alighting 10000000076 1_10001003000 32 -1
364 365 alighting 10000000077 1_10001003000 33 -1
365 366 alighting 10000000078 1_10001003000 34 -1
366 367 alighting 10000000053 1_10001003000 35 -1

367 rows × 6 columns



.. GENERATED FROM PYTHON SOURCE LINES 65-67 .. code-block:: Python graph.edges .. raw:: html
link_id link_type line_id stop_id line_seg_idx b_node a_node trav_time freq o_line_id d_line_id direction
0 1 on-board 1_10001001000 0 212 290 90.000000 inf 1
1 2 on-board 1_10001001000 1 213 291 90.000000 inf 1
2 3 on-board 1_10001001000 2 214 292 120.000000 inf 1
3 4 on-board 1_10001001000 3 215 293 120.000000 inf 1
4 5 on-board 1_10001001000 4 216 294 120.000000 inf 1
... ... ... ... ... ... ... ... ... ... ... ... ...
641 642 egress_connector -1 166 112 630.543431 inf 1
642 643 egress_connector -1 177 112 754.081137 inf 1
643 644 egress_connector -1 178 112 386.262027 inf 1
644 645 egress_connector -1 179 112 558.108038 inf 1
645 646 egress_connector -1 166 113 604.831967 inf 1

646 rows × 12 columns



.. GENERATED FROM PYTHON SOURCE LINES 68-71 The graphs also also stored in the ``Transit.graphs`` dictionary. They are keyed by the 'period_id' they were created for. A graph for a different 'period_id' can be created by providing ``period_id=`` in the ``Transit.create_graph`` call. You can view previously created periods with the ``Periods`` object. .. GENERATED FROM PYTHON SOURCE LINES 71-74 .. code-block:: Python periods = project.network.periods periods.data .. raw:: html
period_id period_start period_end period_description
0 1 0 86400 Default time period, whole day


.. GENERATED FROM PYTHON SOURCE LINES 75-77 Connector project matching -------------------------- .. GENERATED FROM PYTHON SOURCE LINES 77-79 .. code-block:: Python project.network.build_graphs() .. rst-class:: sphx-glr-script-out .. code-block:: none /home/runner/work/aequilibrae/aequilibrae/aequilibrae/paths/graph.py:248: UserWarning: Found centroids not present in the graph! [ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133] warnings.warn("Found centroids not present in the graph!\n" + str(centroids[~present_centroids])) /home/runner/work/aequilibrae/aequilibrae/aequilibrae/paths/graph.py:248: UserWarning: Found centroids not present in the graph! [ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133] warnings.warn("Found centroids not present in the graph!\n" + str(centroids[~present_centroids])) .. GENERATED FROM PYTHON SOURCE LINES 80-84 Now we'll create the line strings for the access connectors, this step is optional but provides more accurate distance estimations and better looking geometry. Because Coquimbo doesn't have many walking edges we'll match onto the ``"c"`` graph. .. GENERATED FROM PYTHON SOURCE LINES 84-86 .. code-block:: Python graph.create_line_geometry(method="connector project match", graph="c") .. rst-class:: sphx-glr-script-out .. code-block:: none /home/runner/work/aequilibrae/aequilibrae/aequilibrae/transit/transit_graph_builder.py:1191: UserWarning: In its current implementation, the "connector project match" method may take a while for large networks. warnings.warn( .. GENERATED FROM PYTHON SOURCE LINES 87-90 Saving and reloading -------------------- Lets save all graphs to the 'public_transport.sqlite' database. .. GENERATED FROM PYTHON SOURCE LINES 90-92 .. code-block:: Python data.save_graphs() .. GENERATED FROM PYTHON SOURCE LINES 93-97 We can reload the saved graphs with ``data.load``. This will create new ``TransitGraphBuilder``\'s based on the 'period_id' of the saved graphs. The graph configuration is stored in the 'transit_graph_config' table in 'project_database.sqlite' as serialised JSON. .. GENERATED FROM PYTHON SOURCE LINES 97-99 .. code-block:: Python data.load() .. GENERATED FROM PYTHON SOURCE LINES 100-101 We can also remove the previously saved graphs. .. GENERATED FROM PYTHON SOURCE LINES 101-104 .. code-block:: Python # data.remove_graphs() .. GENERATED FROM PYTHON SOURCE LINES 105-110 Links and nodes are stored in a similar manner to the 'project_database.sqlite' database. Reading back into AequilibraE ----------------------------- You can create back in a particular graph via it's 'period_id'. .. GENERATED FROM PYTHON SOURCE LINES 110-113 .. code-block:: Python from aequilibrae.project.database_connection import database_connection from aequilibrae.transit.transit_graph_builder import TransitGraphBuilder .. GENERATED FROM PYTHON SOURCE LINES 114-119 .. code-block:: Python pt_con = database_connection("transit") graph_db = TransitGraphBuilder.from_db(pt_con, periods.default_period.period_id) graph_db.vertices.drop(columns="geometry") .. raw:: html
node_id node_type stop_id line_id line_seg_idx taz_id
0 1 od -1 1
1 2 od -1 2
2 3 od -1 3
3 4 od -1 4
4 5 od -1 5
... ... ... ... ... ... ...
362 363 alighting 10000000075 1_10001003000 31 -1
363 364 alighting 10000000076 1_10001003000 32 -1
364 365 alighting 10000000077 1_10001003000 33 -1
365 366 alighting 10000000078 1_10001003000 34 -1
366 367 alighting 10000000053 1_10001003000 35 -1

367 rows × 6 columns



.. GENERATED FROM PYTHON SOURCE LINES 120-122 .. code-block:: Python graph_db.edges .. raw:: html
link_id link_type line_id stop_id line_seg_idx b_node a_node trav_time freq o_line_id d_line_id direction geometry
0 1 on-board 1_10001001000 0 212 290 90.000000 inf 1 b'\x01\x02\x00\x00\x00\x02\x00\x00\x00\xb8Y\xf...
1 2 on-board 1_10001001000 1 213 291 90.000000 inf 1 b'\x01\x02\x00\x00\x00\x02\x00\x00\x00U2\x00T\...
2 3 on-board 1_10001001000 2 214 292 120.000000 inf 1 b'\x01\x02\x00\x00\x00\x02\x00\x00\x00A\xb1\xf...
3 4 on-board 1_10001001000 3 215 293 120.000000 inf 1 b'\x01\x02\x00\x00\x00\x02\x00\x00\x008\xde\xf...
4 5 on-board 1_10001001000 4 216 294 120.000000 inf 1 b'\x01\x02\x00\x00\x00\x02\x00\x00\x00\xc8\xd5...
... ... ... ... ... ... ... ... ... ... ... ... ... ...
641 642 egress_connector -1 166 112 1039.945114 inf 1 b"\x01\x02\x00\x00\x00\x1b\x00\x00\x00\xa1\x92...
642 643 egress_connector -1 177 112 1149.832226 inf 1 b"\x01\x02\x00\x00\x00\x1e\x00\x00\x00\xa1\x92...
643 644 egress_connector -1 178 112 508.359402 inf 1 b"\x01\x02\x00\x00\x00\x13\x00\x00\x00\xa1\x92...
644 645 egress_connector -1 179 112 968.705083 inf 1 b'\x01\x02\x00\x00\x00\x1d\x00\x00\x00\xa1\x92...
645 646 egress_connector -1 166 113 1831.651685 inf 1 b'\x01\x02\x00\x00\x00/\x00\x00\x00\x1ci\x91$\...

646 rows × 13 columns



.. GENERATED FROM PYTHON SOURCE LINES 123-126 Converting to a AequilibraE graph object ---------------------------------------- To perform an assignment we need to convert the graph builder into a graph. .. GENERATED FROM PYTHON SOURCE LINES 126-128 .. code-block:: Python transit_graph = graph.to_transit_graph() .. rst-class:: sphx-glr-script-out .. code-block:: none /home/runner/work/aequilibrae/aequilibrae/aequilibrae/paths/graph.py:248: UserWarning: Found centroids not present in the graph! [ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 21 22 23 24 25 26 30 31 32 34 35 36 38 41 42 43 44 45 46 51 52 53 54 55 56 61 62 63 64 65 66 67 72 73 77 78 79 80 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 109 110 111 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133] warnings.warn("Found centroids not present in the graph!\n" + str(centroids[~present_centroids])) /home/runner/work/aequilibrae/aequilibrae/aequilibrae/paths/graph.py:248: UserWarning: Found centroids not present in the graph! [ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 21 22 23 24 25 26 30 31 32 34 35 36 38 41 42 43 44 45 46 51 52 53 54 55 56 61 62 63 64 65 66 67 72 73 77 78 79 80 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 109 110 111 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133] warnings.warn("Found centroids not present in the graph!\n" + str(centroids[~present_centroids])) .. GENERATED FROM PYTHON SOURCE LINES 129-133 Mock demand matrix ------------------ We'll create a mock demand matrix with demand 1 for every zone. We'll also need to convert from ``zone_id``\'s to ``node_id``\'s. .. GENERATED FROM PYTHON SOURCE LINES 133-136 .. code-block:: Python import numpy as np from aequilibrae.matrix import AequilibraeMatrix .. GENERATED FROM PYTHON SOURCE LINES 137-149 .. code-block:: Python zones_in_the_model = len(transit_graph.centroids) names_list = ['pt'] mat = AequilibraeMatrix() mat.create_empty(zones=zones_in_the_model, matrix_names=names_list, memory_only=True) mat.index = transit_graph.centroids[:] mat.matrices[:, :, 0] = np.full((zones_in_the_model, zones_in_the_model), 1.0) mat.computational_view() .. GENERATED FROM PYTHON SOURCE LINES 150-153 Hyperpath generation/assignment ------------------------------- We'll create a ``TransitAssignment`` object as well as a ``TransitClass`` .. GENERATED FROM PYTHON SOURCE LINES 153-155 .. code-block:: Python from aequilibrae.paths import TransitAssignment, TransitClass .. GENERATED FROM PYTHON SOURCE LINES 156-157 Create the assignment class .. GENERATED FROM PYTHON SOURCE LINES 157-170 .. code-block:: Python assigclass = TransitClass(name="pt", graph=transit_graph, matrix=mat) assig = TransitAssignment() assig.add_class(assigclass) # We need to tell AequilbraE where to find the appropriate fields we want to use, # as well as the assignment algorithm to use. assig.set_time_field("trav_time") assig.set_frequency_field("freq") assig.set_algorithm("os") .. GENERATED FROM PYTHON SOURCE LINES 171-173 When there's multiple matrix cores we'll also need to set the core to use for the demand as we can only assign one at a time. .. GENERATED FROM PYTHON SOURCE LINES 173-175 .. code-block:: Python assigclass.set_demand_matrix_core("pt") .. GENERATED FROM PYTHON SOURCE LINES 176-177 Let's perform the assignment for the transit classes added .. GENERATED FROM PYTHON SOURCE LINES 177-179 .. code-block:: Python assig.execute() .. GENERATED FROM PYTHON SOURCE LINES 180-181 View the results .. GENERATED FROM PYTHON SOURCE LINES 181-183 .. code-block:: Python assig.results() .. raw:: html
pt_volume
479 0.0
480 33.0
481 24.0
482 17.0
483 12.0
... ...
74 47.0
75 24.0
76 24.0
77 27.0
78 0.0

646 rows × 1 columns



.. GENERATED FROM PYTHON SOURCE LINES 184-189 Saving results -------------- We'll be saving the results to another sqlite db called 'results_database.sqlite'. The 'results' table with 'project_database.sqlite' contains some metadata about each table in 'results_database.sqlite'. .. GENERATED FROM PYTHON SOURCE LINES 189-191 .. code-block:: Python assig.save_results(table_name='hyperpath example') .. GENERATED FROM PYTHON SOURCE LINES 192-193 Wrapping up .. GENERATED FROM PYTHON SOURCE LINES 193-194 .. code-block:: Python project.close() .. rst-class:: sphx-glr-script-out .. code-block:: none This project at /tmp/11e931f57c7d4f959c6ea14a0c841ebe is already closed .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 5.339 seconds) .. _sphx_glr_download__auto_examples_public_transport_plot_public_transit_assignment.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_public_transit_assignment.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_public_transit_assignment.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_public_transit_assignment.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_