Network skimming#

In this example, we show how to perform network skimming for Coquimbo, a city in La Serena Metropolitan Area in Chile.

See also

Several functions, methods, classes and modules are used in this example:

# Imports
from uuid import uuid4
from tempfile import gettempdir
from os.path import join
from aequilibrae.utils.create_example import create_example
# We create the example project inside our temp folder
fldr = join(gettempdir(), uuid4().hex)

project = create_example(fldr, "coquimbo")
import logging
import sys

When the project opens, we can tell the logger to direct all messages to the terminal as well

logger = project.logger
stdout_handler = logging.StreamHandler(sys.stdout)
formatter = logging.Formatter("%(asctime)s;%(levelname)s ; %(message)s")
stdout_handler.setFormatter(formatter)
logger.addHandler(stdout_handler)

Network Skimming#

from aequilibrae.paths import NetworkSkimming
import numpy as np

Let’s build all graphs

project.network.build_graphs()
# We get warnings that several fields in the project are filled with ``NaN``s.
# This is true, but we won't use those fields.
2024-11-08 03:00:58,497;WARNING ; Field(s) speed, travel_time, capacity, osm_id, lanes has(ve) at least one NaN value. Check your computations
2024-11-08 03:00:58,570;WARNING ; Field(s) speed, travel_time, capacity, osm_id, lanes has(ve) at least one NaN value. Check your computations
2024-11-08 03:00:58,658;WARNING ; Field(s) speed, travel_time, capacity, osm_id, lanes has(ve) at least one NaN value. Check your computations
2024-11-08 03:00:58,744;WARNING ; Field(s) speed, travel_time, capacity, osm_id, lanes has(ve) at least one NaN value. Check your computations

We grab the graph for cars

graph = project.network.graphs["c"]

# we also see what graphs are available
project.network.graphs.keys()

# let's say we want to minimize the distance
graph.set_graph("distance")

# And will skim distance while we are at it, other fields like ``free_flow_time`` or ``travel_time``
# can be added here as well
graph.set_skimming(["distance"])

# But let's say we only want a skim matrix for nodes 28-40, and 49-60 (inclusive),
# these happen to be a selection of western centroids.
graph.prepare_graph(np.array(list(range(28, 41)) + list(range(49, 91))))
2024-11-08 03:00:58,816;WARNING ; Field(s) speed, travel_time, capacity, osm_id, lanes has(ve) at least one NaN value. Check your computations

And run the skimming

skm = NetworkSkimming(graph)
skm.execute()
                                                  :   0%|          | 0/55 [00:00<?, ?it/s]
1/55                                              :   2%|▏         | 1/55 [00:00<00:00, 265.75it/s]
2/55                                              :   4%|▎         | 2/55 [00:00<00:00, 494.84it/s]
3/55                                              :   5%|▌         | 3/55 [00:00<00:00, 701.27it/s]
4/55                                              :   7%|▋         | 4/55 [00:00<00:00, 877.33it/s]
5/55                                              :   9%|▉         | 5/55 [00:00<00:00, 1024.35it/s]
6/55                                              :  11%|█         | 6/55 [00:00<00:00, 1164.87it/s]
7/55                                              :  13%|█▎        | 7/55 [00:00<00:00, 1291.86it/s]
8/55                                              :  15%|█▍        | 8/55 [00:00<00:00, 1397.00it/s]
9/55                                              :  16%|█▋        | 9/55 [00:00<00:00, 1501.42it/s]
10/55                                             :  18%|█▊        | 10/55 [00:00<00:00, 1598.07it/s]
11/55                                             :  20%|██        | 11/55 [00:00<00:00, 1677.23it/s]
12/55                                             :  22%|██▏       | 12/55 [00:00<00:00, 1758.86it/s]
13/55                                             :  24%|██▎       | 13/55 [00:00<00:00, 1796.93it/s]
14/55                                             :  25%|██▌       | 14/55 [00:00<00:00, 1860.59it/s]
15/55                                             :  27%|██▋       | 15/55 [00:00<00:00, 1933.04it/s]
16/55                                             :  29%|██▉       | 16/55 [00:00<00:00, 1979.85it/s]
17/55                                             :  31%|███       | 17/55 [00:00<00:00, 2038.98it/s]
18/55                                             :  33%|███▎      | 18/55 [00:00<00:00, 2084.70it/s]
19/55                                             :  35%|███▍      | 19/55 [00:00<00:00, 2136.39it/s]
20/55                                             :  36%|███▋      | 20/55 [00:00<00:00, 2175.41it/s]
21/55                                             :  38%|███▊      | 21/55 [00:00<00:00, 2222.06it/s]
22/55                                             :  40%|████      | 22/55 [00:00<00:00, 2257.93it/s]
23/55                                             :  42%|████▏     | 23/55 [00:00<00:00, 2299.51it/s]
24/55                                             :  44%|████▎     | 24/55 [00:00<00:00, 2329.79it/s]
25/55                                             :  45%|████▌     | 25/55 [00:00<00:00, 2366.94it/s]
26/55                                             :  47%|████▋     | 26/55 [00:00<00:00, 2394.96it/s]
27/55                                             :  49%|████▉     | 27/55 [00:00<00:00, 2431.43it/s]
28/55                                             :  51%|█████     | 28/55 [00:00<00:00, 2474.31it/s]
29/55                                             :  53%|█████▎    | 29/55 [00:00<00:00, 2497.48it/s]
30/55                                             :  55%|█████▍    | 30/55 [00:00<00:00, 2526.79it/s]
31/55                                             :  56%|█████▋    | 31/55 [00:00<00:00, 2545.83it/s]
32/55                                             :  58%|█████▊    | 32/55 [00:00<00:00, 2573.88it/s]
33/55                                             :  60%|██████    | 33/55 [00:00<00:00, 2599.58it/s]
34/55                                             :  62%|██████▏   | 34/55 [00:00<00:00, 2623.32it/s]
35/55                                             :  64%|██████▎   | 35/55 [00:00<00:00, 2646.96it/s]
36/55                                             :  65%|██████▌   | 36/55 [00:00<00:00, 2673.14it/s]
37/55                                             :  67%|██████▋   | 37/55 [00:00<00:00, 2699.98it/s]
38/55                                             :  69%|██████▉   | 38/55 [00:00<00:00, 2722.92it/s]
39/55                                             :  71%|███████   | 39/55 [00:00<00:00, 2741.60it/s]
40/55                                             :  73%|███████▎  | 40/55 [00:00<00:00, 2766.33it/s]
41/55                                             :  75%|███████▍  | 41/55 [00:00<00:00, 2785.42it/s]
42/55                                             :  76%|███████▋  | 42/55 [00:00<00:00, 2806.58it/s]
43/55                                             :  78%|███████▊  | 43/55 [00:00<00:00, 2826.39it/s]
44/55                                             :  80%|████████  | 44/55 [00:00<00:00, 2845.79it/s]
45/55                                             :  82%|████████▏ | 45/55 [00:00<00:00, 2857.72it/s]
46/55                                             :  84%|████████▎ | 46/55 [00:00<00:00, 2850.91it/s]
47/55                                             :  85%|████████▌ | 47/55 [00:00<00:00, 2864.75it/s]
48/55                                             :  87%|████████▋ | 48/55 [00:00<00:00, 2883.30it/s]
49/55                                             :  89%|████████▉ | 49/55 [00:00<00:00, 2896.54it/s]
50/55                                             :  91%|█████████ | 50/55 [00:00<00:00, 2905.77it/s]
51/55                                             :  93%|█████████▎| 51/55 [00:00<00:00, 2918.79it/s]
52/55                                             :  95%|█████████▍| 52/55 [00:00<00:00, 2929.81it/s]
53/55                                             :  96%|█████████▋| 53/55 [00:00<00:00, 2954.40it/s]
54/55                                             :  98%|█████████▊| 54/55 [00:00<00:00, 2970.24it/s]
55/55                                             : 100%|██████████| 55/55 [00:00<00:00, 2996.94it/s]
Saving Outputs                                    : 100%|██████████| 55/55 [00:00<00:00, 2913.01it/s]

The result is an AequilibraEMatrix object

skims = skm.results.skims

# Which we can manipulate directly from its temp file, if we wish
skims.matrices[:3, :3, :]
array([[[   0.        ],
        [4166.92919206],
        [5532.32681478]],

       [[3733.4499255 ],
        [   0.        ],
        [3311.30654014]],

       [[5446.26074416],
        [3596.12274848],
        [   0.        ]]])

Or access each matrix, lets just look at the first 3x3

skims.distance[:3, :3]
array([[   0.        , 4166.92919206, 5532.32681478],
       [3733.4499255 ,    0.        , 3311.30654014],
       [5446.26074416, 3596.12274848,    0.        ]])

We can save it to the project if we want

skm.save_to_project("base_skims")
2024-11-08 03:00:58,913;WARNING ; Matrix Record has been saved to the database

We can also retrieve this skim record to write something to its description

matrices = project.matrices
mat_record = matrices.get_record("base_skims")
mat_record.description = "minimized distance while also skimming distance for just a few nodes"
mat_record.save()
project.close()

Total running time of the script: (0 minutes 0.789 seconds)

Gallery generated by Sphinx-Gallery