Usage

Python

R5py exposes some of R5’s functionality via its Python API, in a syntax similar to r5r’s. At the time of this writing, only the computation of travel time matrices has been fully implemented.

Below, you find a minimal example of computing a travel time matrix:

Load transport network

Virtually all operations of r5py require a transport network. As input files to construct a transport network topology, r5py needs the following data sets:

  • The street network in the form of an OpenStreetMap extract covering the study area, prepared according to the instructions at https://docs.conveyal.com/prepare-inputs#preparing-the-osm-data, and possibly annotated with LADOT tags (see https://github.com/RSGInc/ladot_analysis_dataprep).

  • Public transport schedules in GTFS format (optional, r5py can combine multiple GTFS files)

In this example, we use data from Helsinki metropolitan area, which you can find in the source code repository of r5py in docs/data/. The street network is a cropped and filtered extract of OpenStreetMap (© OpenStreetMap contributors, ODbL license), the GTFS transport schedule is a cropped and minimised copy of Helsingin seudun liikenne’s (HSL) open data set Creative Commons BY 4.0.

To import the street and public transport networks, instantiate an r5py.TransportNetwork with the file paths to the OSM extract and the GTFS files:

from r5py import TransportNetwork

transport_network = TransportNetwork(
    "data/kantakaupunki.osm.pbf",
    [
        "data/GTFS.zip"
    ]
)
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.mapdb.Volume$ByteBufferVol (file:/home/docs/.cache/r5py/r5-v6.6-all.jar) to method java.nio.DirectByteBuffer.cleaner()
WARNING: Please consider reporting this to the maintainers of org.mapdb.Volume$ByteBufferVol
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release

Compute a travel time matrix

A travel time matrix is a data set detailing the travel costs (e.g., time) from each point to each point in a set of origins and destinations in a study area.

For the sake of this exercise, we have prepared a grid of points covering parts of Helsinki. The point dataset has been obtained from Helsinki Region Environmental Services (HSY) licensed under a Creative Commons By Attribution 4.0. The point data also contains information about residents of each 250 meter cell.

import geopandas

grid_points = geopandas.read_file("data/population_points_2020.gpkg")

grid_points.head()
Warning: SIGINT handler expected:libjvm.so+0xbdcd90  found:0x0000000000000001
Running in non-interactive shell, SIGINT handler is replaced by shell
Signal Handlers:
SIGSEGV: [libjvm.so+0xbdca50], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO
SIGBUS: [libjvm.so+0xbdca50], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO
SIGFPE: [libjvm.so+0xbdca50], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO
SIGPIPE: [libjvm.so+0xbdca50], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO
SIGXFSZ: [libjvm.so+0xbdca50], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO
SIGILL: [libjvm.so+0xbdca50], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO
SIGUSR2: [libjvm.so+0xbdc8f0], sa_mask[0]=00000000000000000000000000000000, sa_flags=SA_RESTART|SA_SIGINFO
SIGHUP: [libjvm.so+0xbdcd90], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO
SIGINT: SIG_IGN, sa_mask[0]=00000000000000000000000000000000, sa_flags=SA_ONSTACK
SIGTERM: [libjvm.so+0xbdcd90], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO
SIGQUIT: [libjvm.so+0xbdcd90], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO
id population geometry
0 0 389 POINT (24.90770 60.16199)
1 1 296 POINT (24.90771 60.15974)
2 2 636 POINT (24.90772 60.15750)
3 3 1476 POINT (24.90772 60.15526)
4 4 23 POINT (24.91219 60.16648)

We can now visualise the number of people living in each cell (the cells are represented by their centre point):

grid_points.explore("population", cmap="Reds", marker_kwds={"radius": 12})
Make this Notebook Trusted to load map: File -> Trust Notebook

Now, to compute a travel time matrix between all grid_points, we first instantiate an r5py.TravelTimeMatrixComputer with the transport network we created earlier, and a list of origins (since we don’t specify a separate set of destinations, r5py will use the same points as destinations and produce a full set of origins and destinations). The constructor also accepts all parameters of RegionalTask, such as transport modes, or walking speed.

Calling compute_travel_times() on the instance will return a pandas.DataFrame with travel times between all points.

import datetime

from r5py import TravelTimeMatrixComputer, TransitMode, LegMode


travel_time_matrix_computer = TravelTimeMatrixComputer(
    transport_network,
    origins=grid_points,
    departure=datetime.datetime(2022,2,22,8,30),
    transport_modes=[TransitMode.TRANSIT, LegMode.WALK],
    #percentiles=[1,25,50,75,99],
    #breakdown=True
)
travel_time_matrix = travel_time_matrix_computer.compute_travel_times()
travel_time_matrix
from_id to_id travel_time
0 0 0 7
1 0 1 0
2 0 2 5
3 0 3 14
4 0 4 20
... ... ... ...
87 91 87 27
88 91 88 23
89 91 89 10
90 91 90 6
91 91 91 0

8464 rows × 3 columns

The values in the travel_time column are travel times between the points identified by from_id and to_id, in minutes.

The median travel time to or from a certain point gives a good estimate of the overall accessibility to or from it, in relation to other points:

travel_time_matrix.groupby("from_id")["travel_time"].median()
from_id
0     25.5
1     25.0
2     27.0
3     27.5
4     26.0
      ... 
87    25.0
88    24.0
89    24.0
90    25.5
91    27.5
Name: travel_time, Length: 92, dtype: float64
travel_time_matrix.groupby("from_id")["travel_time"].median().median()
22.0