Note
Go to the end to download the full example code.
Import GTFS#
In this example, we import a GTFS feed to our model and perform map matching.
We use data from 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 os import remove
from os.path import join
from tempfile import gettempdir
import folium
import pandas as pd
from aequilibrae.project.database_connection import database_connection
from aequilibrae.transit import Transit
from aequilibrae.utils.create_example import create_example
# Let's create an empty project on an arbitrary folder.
fldr = join(gettempdir(), uuid4().hex)
project = create_example(fldr, "coquimbo")
As the Coquimbo example already has a complete GTFS model, we shall remove its public transport database for the sake of this example.
remove(join(fldr, "public_transport.sqlite"))
Let’s import the GTFS feed.
dest_path = join(fldr, "gtfs_coquimbo.zip")
Now we create our Transit object and import the GTFS feed into our model. This will automatically create a new public transport database.
data = Transit(project)
transit = data.new_gtfs_builder(agency="Lisanco", file_path=dest_path)
To load the data, we must choose one date. We’re going to continue with 2016-04-13 but feel free to experiment with any other available dates. Transit class has a function allowing you to check dates for the GTFS feed. It should take approximately 2 minutes to load the data.
transit.load_date("2016-04-13")
# Now we execute the map matching to find the real paths.
# Depending on the GTFS size, this process can be really time-consuming.
transit.set_allow_map_match(True)
transit.map_match()
# Finally, we save our GTFS into our model.
transit.save_to_disk()
Loading routes (Step: 1/12) : 0it [00:00, ?it/s]
Loading stops (Step: 2/12) : 0%| | 0/78 [00:00<?, ?it/s]
Loading stop times (Step: 3/12) : 0%| | 0/1007 [00:00<?, ?it/s]
Loading stop times (Step: 3/12) : 63%|██████▎ | 637/1007 [00:00<00:00, 4677.86it/s]
Loading shapes (Step: 4/12) : 0%| | 0/2 [00:00<?, ?it/s]
Loading trips (Step: 5/12) : 0%| | 0/1007 [00:00<?, ?it/s]
Loading trips (Step: 5/12) : 4%|▍ | 43/1007 [00:00<00:02, 423.45it/s]
Loading trips (Step: 5/12) : 9%|▊ | 86/1007 [00:00<00:02, 417.56it/s]
Loading trips (Step: 5/12) : 13%|█▎ | 128/1007 [00:00<00:02, 416.84it/s]
Loading trips (Step: 5/12) : 17%|█▋ | 170/1007 [00:00<00:02, 409.99it/s]
Loading trips (Step: 5/12) : 21%|██ | 212/1007 [00:00<00:01, 408.56it/s]
Loading trips (Step: 5/12) : 25%|██▌ | 254/1007 [00:00<00:01, 410.54it/s]
Loading trips (Step: 5/12) : 29%|██▉ | 296/1007 [00:00<00:01, 410.23it/s]
Loading trips (Step: 5/12) : 34%|███▎ | 338/1007 [00:00<00:01, 412.17it/s]
Loading trips (Step: 5/12) : 38%|███▊ | 380/1007 [00:00<00:01, 412.11it/s]
Loading trips (Step: 5/12) : 42%|████▏ | 422/1007 [00:01<00:01, 410.19it/s]
Loading trips (Step: 5/12) : 46%|████▌ | 464/1007 [00:01<00:01, 412.48it/s]
Loading trips (Step: 5/12) : 50%|█████ | 506/1007 [00:01<00:01, 412.65it/s]
Loading trips (Step: 5/12) : 55%|█████▍ | 549/1007 [00:01<00:01, 417.30it/s]
Loading trips (Step: 5/12) : 59%|█████▉ | 592/1007 [00:01<00:00, 420.20it/s]
Loading trips (Step: 5/12) : 63%|██████▎ | 635/1007 [00:01<00:00, 419.71it/s]
Loading trips (Step: 5/12) : 67%|██████▋ | 678/1007 [00:01<00:00, 420.59it/s]
Loading trips (Step: 5/12) : 72%|███████▏ | 721/1007 [00:01<00:00, 302.52it/s]
Loading trips (Step: 5/12) : 76%|███████▌ | 764/1007 [00:01<00:00, 331.69it/s]
Loading trips (Step: 5/12) : 80%|████████ | 807/1007 [00:02<00:00, 355.94it/s]
Loading trips (Step: 5/12) : 84%|████████▍ | 850/1007 [00:02<00:00, 374.38it/s]
Loading trips (Step: 5/12) : 89%|████████▉ | 894/1007 [00:02<00:00, 390.22it/s]
Loading trips (Step: 5/12) : 93%|█████████▎| 937/1007 [00:02<00:00, 401.14it/s]
Loading trips (Step: 5/12) : 97%|█████████▋| 980/1007 [00:02<00:00, 409.11it/s]
De-conflicting stop times (Step: 6/12) : 0%| | 0/1 [00:00<?, ?it/s]
Loading fare data (Step: 7/12) : 100%|██████████| 1/1 [00:00<00:00, 1.63it/s]
Loading data for 2016-04-13 (Step: 9/12) - : 0%| | 0/1 [00:00<?, ?it/s]
Map-matching patterns : 0%| | 0/2 [00:00<?, ?it/s]
Creating map-matching graph from scratch for mode_id=3 (Step: 8/12): 50%|█████ | 1/2 [00:00<00:00, 6.69it/s]
Building graphs - Indexing links (Step: 8/12) : 0it [00:00, ?it/s]
Building graphs - Indexing links (Step: 8/12) : 881it [00:00, 8803.21it/s]
Building graphs - Indexing links (Step: 8/12) : 1762it [00:00, 8729.82it/s]
Building graphs - Indexing links (Step: 8/12) : 2636it [00:00, 8638.60it/s]
Building graphs - Indexing links (Step: 8/12) : 3500it [00:00, 8392.09it/s]
Building graphs - Indexing links (Step: 8/12) : 4341it [00:00, 8122.91it/s]
Building graphs - Indexing links (Step: 8/12) : 5155it [00:00, 7924.98it/s]
Building graphs - Indexing links (Step: 8/12) : 5949it [00:00, 7628.69it/s]
Building graphs - Indexing links (Step: 8/12) : 6714it [00:00, 7360.92it/s]
Building graphs - Indexing links (Step: 8/12) : 7452it [00:00, 7294.28it/s]
Building graphs - Indexing links (Step: 8/12) : 8183it [00:01, 7276.89it/s]
Building graphs - Indexing links (Step: 8/12) : 8952it [00:01, 7396.83it/s]
Building graphs - Indexing links (Step: 8/12) : 9696it [00:01, 7409.60it/s]
Building graphs - Indexing links (Step: 8/12) : 10438it [00:01, 7355.07it/s]
Building graphs - Indexing links (Step: 8/12) : 11174it [00:01, 7222.46it/s]
Building graphs - Indexing links (Step: 8/12) : 11901it [00:01, 7223.73it/s]
Building graphs - Indexing links (Step: 8/12) : 12624it [00:01, 7146.35it/s]
Building graphs - Indexing links (Step: 8/12) : 13339it [00:01, 7060.67it/s]
Building graphs - Indexing links (Step: 8/12) : 14086it [00:01, 7178.85it/s]
Building graphs - Indexing links (Step: 8/12) : 14820it [00:01, 7225.00it/s]
Building graphs - Indexing links (Step: 8/12) : 15543it [00:02, 7209.72it/s]
Building graphs - Indexing links (Step: 8/12) : 16265it [00:02, 7105.02it/s]
Building graphs - Indexing links (Step: 8/12) : 16976it [00:02, 7035.56it/s]
Building graphs - Indexing links (Step: 8/12) : 17680it [00:02, 6939.33it/s]
Building graphs - Indexing links (Step: 8/12) : 18400it [00:02, 7014.22it/s]
Building graphs - Indexing links (Step: 8/12) : 19102it [00:02, 6829.01it/s]
Building graphs - Indexing links (Step: 8/12) : 19850it [00:02, 7015.40it/s]
Building graphs - Indexing links (Step: 8/12) : 20553it [00:02, 7012.17it/s]
Building graphs - Indexing links (Step: 8/12) : 21274it [00:02, 7067.93it/s]
Building graphs - Indexing links (Step: 8/12) : 22014it [00:03, 7164.90it/s]
Building graphs - Indexing links (Step: 8/12) : 22732it [00:03, 7015.02it/s]
Building graphs - Indexing links (Step: 8/12) : 23438it [00:03, 7027.69it/s]
Building graphs - Indexing links (Step: 8/12) : 24156it [00:03, 7070.66it/s]
Building graphs - Indexing links (Step: 8/12) : 24869it [00:03, 7087.05it/s]
Building graphs - Indexing links (Step: 8/12) : 25628it [00:03, 7235.09it/s]
Building graphs - Indexing links (Step: 8/12) : 26355it [00:03, 7245.28it/s]
Building graphs - Indexing links (Step: 8/12) : 27085it [00:03, 7261.05it/s]
Building graphs - Indexing links (Step: 8/12) : 27812it [00:03, 7104.25it/s]
Building graphs - Indexing links (Step: 8/12) : 28524it [00:03, 7084.14it/s]
Building graphs - Indexing links (Step: 8/12) : 29299it [00:04, 7279.71it/s]
Building graphs - Indexing links (Step: 8/12) : 30028it [00:04, 7194.17it/s]
Building graphs - Indexing links (Step: 8/12) : 30749it [00:04, 7059.94it/s]
Building graphs - Indexing links (Step: 8/12) : 31456it [00:04, 7046.53it/s]
Building graphs - Indexing links (Step: 8/12) : 32179it [00:04, 7098.07it/s]
Building graphs - Indexing links (Step: 8/12) : 32895it [00:04, 7114.60it/s]
Building graphs - Indexing links (Step: 8/12) : 33631it [00:04, 7185.47it/s]
Building graphs - Indexing links (Step: 8/12) : 34350it [00:04, 7130.61it/s]
Building graphs - Breaking links (Step: 8/12) : 0%| | 0/78 [00:00<?, ?it/s]
Building graphs - Breaking links (Step: 8/12) : 17%|█▋ | 13/78 [00:00<00:00, 120.30it/s]
Building graphs - Breaking links (Step: 8/12) : 35%|███▍ | 27/78 [00:00<00:00, 128.23it/s]
Building graphs - Breaking links (Step: 8/12) : 51%|█████▏ | 40/78 [00:00<00:00, 121.90it/s]
Building graphs - Breaking links (Step: 8/12) : 68%|██████▊ | 53/78 [00:00<00:00, 122.82it/s]
Building graphs - Breaking links (Step: 8/12) : 85%|████████▍ | 66/78 [00:00<00:00, 103.59it/s]
Building graphs - Breaking links (Step: 8/12) : 99%|█████████▊| 77/78 [00:00<00:00, 95.32it/s]
Map-matching patterns : 3%|▎ | 2/78 [00:11<00:00, 95.32it/s]
Saving patterns (Step: 10/12) : 0%| | 0/2 [00:00<?, ?it/s]
Saving trips (Step: 11/12) : 0%| | 0/360 [00:00<?, ?it/s]
Saving links (Step: 11/12) : 0%| | 0/78 [00:00<?, ?it/s]
Saving stops (Step: 12/12) : 0%| | 0/78 [00:00<?, ?it/s]
Saving stops (Step: 12/12) : 8%|▊ | 6/78 [00:00<00:01, 48.70it/s]
Saving stops (Step: 12/12) : 14%|█▍ | 11/78 [00:00<00:01, 44.03it/s]
Saving stops (Step: 12/12) : 21%|██ | 16/78 [00:00<00:01, 42.39it/s]
Saving stops (Step: 12/12) : 27%|██▋ | 21/78 [00:00<00:01, 41.88it/s]
Saving stops (Step: 12/12) : 33%|███▎ | 26/78 [00:00<00:01, 41.27it/s]
Saving stops (Step: 12/12) : 40%|███▉ | 31/78 [00:00<00:01, 40.26it/s]
Saving stops (Step: 12/12) : 46%|████▌ | 36/78 [00:00<00:01, 40.45it/s]
Saving stops (Step: 12/12) : 53%|█████▎ | 41/78 [00:00<00:00, 40.41it/s]
Saving stops (Step: 12/12) : 59%|█████▉ | 46/78 [00:01<00:00, 40.38it/s]
Saving stops (Step: 12/12) : 65%|██████▌ | 51/78 [00:01<00:00, 40.52it/s]
Saving stops (Step: 12/12) : 72%|███████▏ | 56/78 [00:01<00:00, 40.38it/s]
Saving stops (Step: 12/12) : 78%|███████▊ | 61/78 [00:01<00:00, 40.30it/s]
Saving stops (Step: 12/12) : 85%|████████▍ | 66/78 [00:01<00:00, 40.44it/s]
Saving stops (Step: 12/12) : 91%|█████████ | 71/78 [00:01<00:00, 39.82it/s]
Saving stops (Step: 12/12) : 97%|█████████▋| 76/78 [00:01<00:00, 39.93it/s]
Now we will plot one of the route’s patterns we just imported
conn = database_connection("transit")
links = pd.read_sql("SELECT pattern_id, ST_AsText(geometry) geom FROM routes;", con=conn)
stops = pd.read_sql("""SELECT stop_id, ST_X(geometry) X, ST_Y(geometry) Y FROM stops""", con=conn)
gtfs_links = folium.FeatureGroup("links")
gtfs_stops = folium.FeatureGroup("stops")
layers = [gtfs_links, gtfs_stops]
pattern_colors = ["#146DB3", "#EB9719"]
for i, row in links.iterrows():
points = row.geom.replace("MULTILINESTRING", "").replace("(", "").replace(")", "").split(", ")
points = "[[" + "],[".join([p.replace(" ", ", ") for p in points]) + "]]"
points = [[x[1], x[0]] for x in eval(points)]
_ = folium.vector_layers.PolyLine(
points,
popup=f"<b>pattern_id: {row.pattern_id}</b>",
color=pattern_colors[i],
weight=5,
).add_to(gtfs_links)
for i, row in stops.iterrows():
point = (row.Y, row.X)
_ = folium.vector_layers.CircleMarker(
point,
popup=f"<b>stop_id: {row.stop_id}</b>",
color="black",
radius=2,
fill=True,
fillColor="black",
fillOpacity=1.0,
).add_to(gtfs_stops)
Let’s create the map!
map_osm = folium.Map(location=[-29.93, -71.29], zoom_start=13)
# add all layers
for layer in layers:
layer.add_to(map_osm)
# And add layer control before we display it
folium.LayerControl().add_to(map_osm)
map_osm
project.close()
Total running time of the script: (0 minutes 25.789 seconds)