Quickstart#
One of the core functionalities of r5py is to compute travel time matrices efficiently, and for large extents such as entire cities or countries. This page walks you through the - pleasantly few - steps required to do so.
In our example below, we work with sample data from Helsinki, the capital of Finland. We calculate the travel times on public transport or on foot from all cells in a population grid data set to the city’s main railway station.
Origins and destination#
As we intend to compute the travel times from the centre points of population grid cells to the railway station, we need to know the locations of these places.
For this example, we prepared the data ahead of time: population_grid is a
geopandas.GeoDataFrame
containing a 250 ⨉ 250 m grid covering parts of downtown Helsinki, and obtained
from the Helsinki Region Environmental Services
(HSY). The
constant RAILWAY_STATION is a
shapely.Point,
its coordinates refer to Helsinki’s main railway station in the
EPSG:4326 reference system.
import geopandas
population_grid = geopandas.read_file(DATA_DIRECTORY / "Helsinki" / "population_grid_2020.gpkg")
import shapely
RAILWAY_STATION = shapely.Point(24.941521, 60.170666)
import folium
import geopandas
import shapely
overview_map = population_grid.explore("population", cmap="Reds")
folium.Marker((RAILWAY_STATION.y, RAILWAY_STATION.x)).add_to(overview_map)
overview_map
Transport network#
Virtually all operations of r5py require a transport network. R5py understands and reads the following types of transport networks:
a street network, including infrastructure for cycling and walking, is loaded from an OpenStreetMap extract in Protocol Buffer (
.pbf) format (mandatory)a public transport schedule from one or more GTFS files (optional).
For the quickstart example, you find sample data sets in the DATA_DIRECTORY
(docs/_static/data
in the source code repository).
To import the street and public transport networks, instantiate an
r5py.TransportNetwork with the file paths to the OSM extract and to
zero or more GTFS files:
import r5py
transport_network = r5py.TransportNetwork(
DATA_DIRECTORY / "Helsinki" / "kantakaupunki.osm.pbf",
[
DATA_DIRECTORY / "Helsinki" / "GTFS.zip",
]
)
At this stage, r5py has created a routable transport network, that is stored
in the transport_network variable. We can now use this network for travel time
calculations. Depending on the extent of the network, this step can take up to
several minutes. However, you can reuse the same TransportNetwork instance in
subsequent analyses.
Compute a travel time matrix#
A travel time matrix is a dataset of the travel costs (typically, time) between
given locations (origins and destinations) in a study area. In r5py,
TravelTimeMatrixComputers calculate
these matrices. A
TravelTimeMatrixComputer, once
initialised, can be used multiple times, for instance, with adjusted parameters,
such as a different departure time.
A TravelTimeMatrixComputer needs (at least)
the following input arguments:
a
transport_network(r5py.TransportNetwork), such as the one we just created,origins, ageopandas.GeoDataFramewith one or more points representing the departure points of routes,destinations, ageopandas.GeoDataFramewith one or more points representing the destinations of routes,departure, adatetime.datetimerefering to the departure date and time for routing, andtransport_modes, a list ofr5py.TransportModes: the travel modes that will be used in the calculations
Once instantiated, call
TravelTimeMatrixComputer.compute_travel_times()
to carry out the actual analysis.
import datetime
origins = population_grid.copy()
origins.geometry = origins.geometry.centroid
destinations = geopandas.GeoDataFrame(
{
"id": [1],
"geometry": [RAILWAY_STATION]
},
crs="EPSG:4326",
)
travel_time_matrix_computer = r5py.TravelTimeMatrixComputer(
transport_network,
origins=origins,
destinations=destinations,
departure=datetime.datetime(2022, 2, 22, 8, 30),
transport_modes=[
r5py.TransportMode.TRANSIT,
r5py.TransportMode.WALK,
],
)
travel_times = travel_time_matrix_computer.compute_travel_times()
travel_times.head()
| from_id | to_id | travel_time | |
|---|---|---|---|
| 0 | 0 | 1 | 16 |
| 1 | 1 | 1 | 18 |
| 2 | 2 | 1 | 20 |
| 3 | 3 | 1 | 22 |
| 4 | 4 | 1 | 18 |
The result of
compute_travel_times()
is a pandas.DataFrame. The values in its travel_time column are
travel times in minutes between the points identified by from_id and to_id
(the IDs of the origins and destinations, respectively). As you can see, the
id value in the to_id column is the same for all rows because our example
used only one destination point (the railway station).
Save results#
If you want to continue analysis later, in a different environment, or simply
retain a clean copy of the results, save the travel time matrix to a CSV file.
Simply use the to_csv() method of pandas data
frames:
travel_times.to_csv(DATA_DIRECTORY / "travel_times_to_helsinki_railway_station.csv")
Plot a result map#
To quickly plot the results in a map, join the travel_times with the input
data set population_grid and
explore() the joint data frame’s
data.
travel_times = population_grid.merge(travel_times, left_on="id", right_on="from_id")
travel_times.head()
| id | population | geometry | from_id | to_id | travel_time | |
|---|---|---|---|---|---|---|
| 0 | 0 | 389 | POLYGON ((24.90545 60.16086, 24.90545 60.16311... | 0 | 1 | 16 |
| 1 | 1 | 296 | POLYGON ((24.90546 60.15862, 24.90545 60.16086... | 1 | 1 | 18 |
| 2 | 2 | 636 | POLYGON ((24.90547 60.15638, 24.90546 60.15862... | 2 | 1 | 20 |
| 3 | 3 | 1476 | POLYGON ((24.90547 60.15413, 24.90547 60.15638... | 3 | 1 | 22 |
| 4 | 4 | 23 | POLYGON ((24.90994 60.16535, 24.90994 60.16760... | 4 | 1 | 18 |
travel_times.explore("travel_time", cmap="Greens")