Note
Go to the end to download the full example code.
Computing paths over the network#
In this example we show how to use the Polaris Batch Router to compute paths over the network
Imports#
from pathlib import Path
import folium
import numpy as np
from polaris import Polaris
from polaris.utils.database.db_utils import read_and_close
sphinx_gallery_thumbnail_path = "../../examples/working_with_models/routed_path.png"
Data Sources#
Open the demand database for analysis
model_fldr = "/tmp/Grid"
# model_fldr = r"D:\src\argonne\MODELS\Grid"
project = Polaris.from_dir(Path(model_fldr))
router = project.router
Traceback (most recent call last):
File "/home/jamie/git/anl/polarislib/docs/examples/working_with_models/plot_computing_paths.py", line 36, in <module>
router = project.router
^^^^^^^^^^^^^^
File "/home/jamie/git/anl/polarislib/polaris/project/polaris.py", line 162, in router
self.__batch_router = BatchRouter(self.run_config, self.supply_file)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/jamie/git/anl/polarislib/polaris/runs/router/batch_router.py", line 20, in __init__
bin_path = Path(convergence_config.polaris_exe).parent
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/jamie/.pyenv/versions/3.12.2/lib/python3.12/pathlib.py", line 1162, in __init__
super().__init__(*args)
File "/home/jamie/.pyenv/versions/3.12.2/lib/python3.12/pathlib.py", line 373, in __init__
raise TypeError(
TypeError: argument should be a str or an os.PathLike object where __fspath__ returns a str, not 'NoneType'
We can first compute the path between two links The departure is in seconds, and we need to provide both the links and their directions (0 for AB and 1 for BA) If we don’t provide the link directions, they default to 0
path = router.route_links(link_origin=678, link_destination=656, origin_dir=1, destination_dir=0, departure_time=72000)
# Then we can see the total travel time
print(path.travel_time)
# Then we can see the list of links we traversed
print(path.links)
# And the direction we traversed them through
print(path.link_directions)
# And the cumulative travel time at each link
print(path.cumulative_time)
We can also compute the path between two locations In this case, the link and direction associated with the locations will be used as Origin and destination If we don’t provide a departure time, 8AM (28800) is used
new_path = router.route(90, 740)
We can compute the multi-modal travel time between two locations. We do need to input the mode, however
multimodal_path = router.multimodal(90, 740, 1)
print(f"Multimodal travel time: {multimodal_path.travel_time}")
print(f"Car travel time: {new_path.travel_time}")
And we can plot this path on the network
data = project.network.data_tables
with read_and_close(project.supply_file, spatial=True) as conn:
links_layer = data.plotting_layer("Link", conn)
loc_layer = data.plotting_layer("Location", conn)
# We create a Folium layer
network_links = folium.FeatureGroup("links")
computed_path = folium.FeatureGroup("path")
locations = folium.FeatureGroup("Locations")
# We do some Python magic to transform this dataset into the format required by Folium
# We are only getting link_id and link_type into the map, but we could get other pieces of info as well
for link_id, row in links_layer.iterrows():
points = row.geo.replace("LINESTRING", "").replace("(", "").replace(")", "").split(", ")
points = "[[" + "],[".join([p.replace(" ", ", ") for p in points]) + "]]"
# We need to take from x/y to lat/long
points = [[x[1], x[0]] for x in eval(points)]
line = folium.vector_layers.PolyLine(points, popup=f"<b>link_id: {link_id}</b>", color="blue", weight=2)
line.add_to(network_links)
if link_id in new_path.links:
line = folium.vector_layers.PolyLine(points, popup=f"<b>link_id: {link_id}</b>", color="red", weight=5)
line.add_to(computed_path)
for location_id, row in loc_layer[loc_layer.index.isin([90, 740])].iterrows():
point = eval(row.geo.replace("POINT", "").replace(" ", ","))
point = (point[1], point[0])
_ = folium.vector_layers.CircleMarker(
point,
popup=f"<b>Location: {location_id}</b>",
color="black",
radius=6,
fill=True,
fillColor="black",
fillOpacity=1.0,
).add_to(locations)
a, b = network_links.get_bounds()
location = list((np.array(a) + np.array(b)) / 2)
map_osm = folium.Map(location=location, zoom_start=12)
network_links.add_to(map_osm)
computed_path.add_to(map_osm)
locations.add_to(map_osm)
folium.LayerControl().add_to(map_osm)
map_osm
Total running time of the script: (0 minutes 0.182 seconds)