Compute isochrones

Compute isochrones#

Isochrones are lines of equal travel time. They are the boundaries of a geographic area reachable from a point of origin within a specified amount of time. Isochrones can be used to answer questions of a spatial accessibility footprint, they are visually intuitive, can reveal barriers and bottlenecks and the seemingly teleportative powers of fast public transport. Isochrones are used to plan service areas and carry out equity analysis.

To compute isochrones in r5py, you need a TransportNetwork and a point of origin. For this example, we use the main railway station in Helsinki.

import r5py
import r5py.sampledata.helsinki
import shapely

transport_network = r5py.TransportNetwork(
    r5py.sampledata.helsinki.osm_pbf,
    [
        r5py.sampledata.helsinki.gtfs,
    ]
)

RAILWAY_STATION = shapely.Point(24.941521, 60.170666)

We then instantiate an r5py.Isochrones() object, to which we pass the transport network, the origin point, a departure datetime and the transport modes which will be used for routing. Note that when multiple origin points or multiple transport modes are specified, the respective fastest will be recorded in the outputs.

import datetime

isochrones = r5py.Isochrones(
    transport_network,
    origins=RAILWAY_STATION,
    departure=datetime.datetime(2022, 2, 22, 8, 30),
    transport_modes=[r5py.TransportMode.TRANSIT, r5py.TransportMode.WALK],
    isochrones=[5, 10, 15],
)

Isochrones inherit from geopandas.GeoDataFrame: all methods and attributes of geo data frames work on isochrone data sets.

The output has two columns: a MultiLineString geometry and the travel time to the geometry as TimeDelta:

isochrones
travel_time geometry
0 0 days 00:05:00 MULTILINESTRING ((24.93896 60.16979, 24.93873 ...
1 0 days 00:10:00 MULTILINESTRING ((24.92815 60.16807, 24.92793 ...
2 0 days 00:15:00 MULTILINESTRING ((24.97562 60.18749, 24.97567 ...
isochrones.explore(column="travel_time", cmap="YlOrRd", tiles="CartoDB.Positron")
Make this Notebook Trusted to load map: File -> Trust Notebook

Isochrones from multiple locations#

Sometimes, the accessibility from multiple locations is at the interest of an analysis. In the example below, we model which area the bicycle emergency response of the Helsinki rescue departments can reach within 5, 10, or 15 minutes.

First, we download the locations of the rescue stations from the city’s WFS open data endpoint:

import geopandas

rescue_stations = geopandas.read_file(
    (
        "https://kartta.hel.fi/ws/geoserver/avoindata/wfs"
        "?service=wfs"
        "&version=2.0.0"
        "&request=GetFeature"
        "&typeName=avoindata:Toimipisterekisteri_yksikot"
        "&srsName=EPSG:3879"
        "&outputFormat=application/json"
        "&CQL_FILTER=address_city_en+LIKE+'Helsinki'+AND+service_en+LIKE+'%25rescue+station%25'"
    )
).to_crs("EPSG:3879")

Then we use this rescue_stations as origins and restrict transport_modes to cycling.

isochrones = r5py.Isochrones(
    transport_network,
    origins=rescue_stations,
    transport_modes=[r5py.TransportMode.BICYCLE],
    isochrones=[5, 10, 15]
)

isochrones
travel_time geometry
0 0 days 00:05:00 MULTILINESTRING ((24.94379 60.21892, 24.94396 ...
1 0 days 00:10:00 MULTILINESTRING ((24.93805 60.22825, 24.93838 ...
2 0 days 00:15:00 MULTILINESTRING ((24.99568 60.22359, 24.99568 ...
isochrones.explore(column="travel_time", cmap="YlOrRd", tiles="CartoDB.Positron")
Make this Notebook Trusted to load map: File -> Trust Notebook

Performance tuning

Computing isochrones over large areas is expensive. You can tweak performance (at the expense of precision) by coarsening the point grid that underlies the computation.

If your analysis covers a large area and/or long travel times, increase the distance between the grid’s points by increasing point_grid_resolution from its default value of 100 metres.

If reproducibility of exact results is not required, compute isochrones for a sample of the grid’s points by setting a point_grid_sample_ratio smaller than one.