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")
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")
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.