Walking and cycling legs

Walking and cycling appear in the model in two roles:

  • as legs of a public transport journey: the pre-transport from the origin to the first stop and the post-transport from the last stop to the destination;
  • as direct trips from origin to destination: the components WW (walking) and CC (cycling).

This page describes how both are computed, step by step. The car is described on Private transport; how the legs are joined to the public transport chains, on Public transport.

Contents


Step 1: the network

Walking

Walking uses the OSM network: the road segments that the OSM classification marks as pedestrian (IsPedestrian). The extract follows the reference date (AnalysisMoment): 20240524 for Y2015 to Y2024, 20260601 for Y2025 and Y2026. The model reads it from the network store %LocalDataProjDir%/OSM/Final_Network_<date>_r3.mmd, which it makes from the Geofabrik shapefiles (see Private transport, OSM). Every link can be walked in both directions.

Cycling

ModelParameters/Advanced/CyclingNetwork chooses the network for all cycling: cycling as pre- and post-transport, the OV-fiets, and the direct cycling trip.

With 'OSM', the default, the network consists of the OSM segments of the road types in the bike network (IsPartOfBikeNetwork, a BikeSpeed above 1 km/h), from the same extract as walking. Every link can be ridden in both directions, because the oneway of the Geofabrik shapefiles does not say whether cyclists are exempt.

With 'Fietsersbond', the network is the route network of the Fietsersbond, the network of 2024 delivered by PBL on 25 May 2025 (Fietsersbond_file_date), in %NetworkModel_Dir%/Infrastructuur/Fietsersbond_20250525. One delivery serves all reference dates. SourceData/Infrastructure/Fietsersbond/Network_Cycling turns it into a network with the attributes of the OSM bike network:

  • It keeps the links with bicycle access (toegang not 'geen') and two known nodes: 1,449,915 of the 1,771,242 links, 160,500 km.
  • A link with toegang 'heen' or 'terug' (10% of the links) is a one-way cycle path: it can only be ridden in its direction of travel (IsOneDirection, with the geometry in that direction).
  • The 217 river ferries up to Fietsersbond_MaxVeerpontLengte (2 km) take part, with Fietsersbond_VeerpontExtraTijd (5 min) for waiting and crossing on top of the cycling time. The 62 longer crossings (2 to 39 km) do not. No origin, destination or stop is connected to a ferry.
  • The road type, used for the junction penalties, is ferry, tertiary (cars above 30 km/h), residential (cars up to 30 km/h) or cycleway (cycle paths and pedestrian areas).
  • The topology is built from the end points of the segments, as for OSM, not from van_id and naar_id.
  • The network covers the Netherlands only, so there are no cycling legs to stops across the border.

With the Fietsersbond network the signature of the output names the network (Advanced/CyclingNetwork_FileTag, _fb20250525-veer2000m5min), and the output folder of a component that cycles gets _fb after its name (Advanced/CyclingNetwork_DirTag), for example 20251014_b2025_CC_fb. The output of both networks can so stand side by side; WW, W_PT_W and Car do not depend on the cycling network. The leg stores have the network in the hash of their name (see The store).

The two networks compare as follows (#124, at 14 km/h):

  • 95% of the Fietsersbond network lies within 25 m of the OSM bike network. Most of the rest is in OSM under a road type outside the bike network (footways, pedestrian areas, tracks without a grade).
  • 72% of the OSM bike network in the Netherlands lies near a Fietsersbond link; the rest is mainly path and service.
  • For neighbourhood-to-neighbourhood trips up to 15 minutes the median ratio of the travel times is 1.000.

Speed

Every link has a constant speed: WalkingSpeed_kmhr (4.5 km/h) for walking and CyclingSpeed_kmhr (14 km/h) for cycling. An e-bike is a run with a higher cycling speed (Advanced/E_BikingSpeed_kmhr, 20 km/h). Measured speeds from the Fietstelweek (Advanced/UseActualCyclingSpeeds, OSM only) are used in the cycling travel time matrices for other analyses, not in the legs or the direct trips.

Step 2: preparing the network

PublicTransport_Prep/Create_Optimised_Network_Walking and Create_Optimised_Network_Cycling (Templates/CreateNetwork_Efficient_T) prepare one network per mode, which all leg types of that mode share:

  1. The origins, the destinations and the stops are connected to the network at the nearest connectable point (connect).
  2. Every junction a route passes costs time, a junction penalty, by the number of road links at the node: 0 s for 2 or fewer, 2 s for 3, 5 s for 4 and 6 s for more (Advanced/Junction_Penalties, the same for walking and cycling). A junction where every road link is a slow-traffic road, a road type with a car speed of at most 30 km/h such as a residential street, a service road or a footway (Classifications/OSM/roadType/IsSlowTrafficRoad), costs nothing, because the with_*_lowerSpeedLinks_* penalties are 0 s: in a residential area a walker or cyclist does not stop at every side street. Each link carries half of the penalty of each of its end nodes, so a route pays the penalty of a junction once. Only road links count, not the connection links of origins, destinations and stops.
  3. Nodes that are not junctions are removed and their links merged into longer links; routes and travel times do not change (see Network optimisation).

Step 3: the leg stores

The base sets

All leg types are selections from four base sets, each computed once per reference date, origin set and destination set:

Base set From To Network Store
Org2Stops_Walking every origin every stop walking Legs_<Set>toStops_Walking_<hash>.parquet
Org2Stops_Cycling every origin every stop cycling Legs_<Set>toStops_Cycling_<hash>.parquet
Stops2Dest_Cycling every stop every destination cycling Legs_Stops2<Set>_Cycling_<hash>.parquet
Stops2Dest_Walking every stop every destination walking Legs_Stops2<Set>_Walking_<hash>.parquet, only when the origin and destination sets differ

When the origin set and the destination set are the same (PublicTransport_Prep/WalkingMirror), walking from a stop to a destination is read as the mirror of Org2Stops_Walking, because the walking network has no one-way links. Cycling has a store per direction, because the Fietsersbond network has one-way cycle paths (on the OSM network both directions give the same legs).

The computation

Per base set the model runs one Dijkstra over the whole prepared network (PublicTransport_Prep/TimeInvariantConnections/<base set>/Create_Routes, Templates/CreateNetwork_Pedestrian_Bike_T, with impedance_matrix_od64):

  1. from every origin (pre-transport) or every stop (post-transport);
  2. to every stop or every destination that is reachable;
  3. cut at the maximum time of the base set: MaxWalkingTime_Org2Stops, MaxCyclingTime_Org2Stops, MaxCyclingTime_Stops2Dest and MaxWalkingTime_Stops2Dest, 15 minutes each.

The time of a leg is its network time: the length of each link divided by the speed, plus the junction penalties.

The store

Each base set is a parquet file (zstd) in %LocalDataProjDir%/IntermediateResults, so that it can also be used outside the model:

  • The columns are BuurtCode (the CBS code of the neighbourhood), stop_id and stop_name (from the GTFS feed), Traveltime (the network time in minutes) and TravelDist (metres), as float64, so that the model reads them back exactly.
  • In the name, <Set> is the origin or destination set (Advanced/OrgSet_NameTag, DestSet_NameTag, for example B2025), <hash> a hash of the signature.
  • The signature, in <name>.signature.txt next to the store, names the base set, the network and speed, the maximum time, the origin and destination sets, the reference date and feed, the numbers of places and stops, the format and the revision. The model reads a store only when its signature matches the settings of the run; otherwise it computes a new store, which has another hash and so stands next to the old one.

For 2025 (Buurt2025 to Buurt2025) the walking store is 5 MB and the two cycling stores 23 and 22 MB.

Generating the stores

  • With batch\UpdateAll.cmd legs: all base sets in one GeoDmsRun, about 10 minutes per reference date and neighbourhood set.
  • In GeoDmsGui, under /MakeUnlinkedData/LegStores: right-click Generate_All (all base sets), or Org2Stops_Walking, Org2Stops_Cycling or Stops2Dest_Cycling (one base set), and choose Update TreeItem; then reload the configuration (Alt+R). See step 3 of How to run the model.

The stores do not depend on the part of the day or the component. They need to be computed again after a change in the network (the OSM extract or CyclingNetwork), the walking or cycling speed, a maximum pre- or post-transport time, the origins, the destinations, or the stops (the feed and the reference date).

Step 4: the leg types of the components

Selection from the base sets

The pre- and post-transport type of a component (see Components and merging) reads the store of its base set (PublicTransport_Prep/Legs/<type>, template Legs_T) and keeps the legs to or from the stops of its stop set, within its own maximum time:

Type Code Base set Stops
Org2Stops_Walking W Org2Stops_Walking all
Org2Stops_Cycling C Org2Stops_Cycling all
Org2RM_Stops_Cycling C_RM Org2Stops_Cycling rail and metro
Org2RMT_Stops_Cycling C_RMT Org2Stops_Cycling rail, metro and tram
Org2Ric_Stops_Cycling C_Ric Org2Stops_Cycling InterCity stations
Stops2Dest_Walking W Stops2Dest_Walking, or the mirror of Org2Stops_Walking all
Stops2Dest_Cycling C Stops2Dest_Cycling all
RM_Stops2Dest_Cycling RM_C Stops2Dest_Cycling rail and metro
RMT_Stops2Dest_Cycling RMT_C Stops2Dest_Cycling rail, metro and tram
OVF_Stops2Dest_Cycling OVf_C Stops2Dest_Cycling stops near an OV-fiets location

A selection gives the same legs as a Dijkstra of its own, because the route to a stop does not depend on which other stops are targets. The maximum time of a type may not exceed that of its base set (an integrity check of Legs_T).

Extra time

On reading, a leg gets fixed times on top of its network time:

  • every cycling leg: Cycling_StartTime (1 min);
  • a cycling pre-transport leg: also Advanced/Cycling_PreTransport_Penalty (0 min), and Cycling_ParkingTime_IC_Station (3 min) when it ends at an InterCity station.

The maximum times apply to the network time, as the cut of the Dijkstra does.

Price

  • An OV-fiets leg (OVf_C) costs the rental price OVFiets_RentalPrice (4.45 euro).
  • Any other leg costs its time with the extra time, times the time costs of the mode: PreTransport_Walking_Time_Costs and PostTransport_Walking_Time_Costs (0.19 euro per minute), PreTransport_Cycling_Time_Costs and PostTransport_Cycling_Time_Costs (0.09 euro per km at CyclingSpeed_kmhr).

The price of a leg always counts in Price_Augm. In Price it counts for cycling with Advanced/IncludeCyclingCostsInPrice (default TRUE) and for walking with Advanced/IncludeWalkingCostsInPrice (default FALSE).

Step 5: the direct walking and cycling trips

The components WW and CC are the direct trips (PublicTransport_Prep/Direct/Walking and Direct/Cycling):

  1. The route is a Dijkstra from every origin to every destination over the same network as the legs (NetworkSetup/PrivateTransport/Walking and Cycling), up to MaxWalkingTime_Org2Dest and MaxCyclingTime_Org2Dest (90 min).
  2. The duration is the network time; for cycling plus Cycling_StartTime.
  3. The price is the time valuation Direct_Walking_Time_Costs or Direct_Cycling_Time_Costs when IncludeWalkingCostsInPrice or IncludeCyclingCostsInPrice is set, else 0.
  4. The direct trips do not depend on the departure moment, so the components write one moment per origin block (the congestion moment of the part of the day, 07h30m in the morning), computed in the output step (batch\UpdateAll.cmd output with Component 'WW' or 'CC'). There is no intermediate store.

Parameters

Parameter Default Description
WalkingSpeed_kmhr, CyclingSpeed_kmhr 4.5, 14 km/h Speed on every link; in the signature of the leg stores.
MaxWalkingTime_Org2Stops, MaxWalkingTime_Stops2Dest 15 min Maximum walking pre- and post-transport time; in the signature of the leg stores.
MaxCyclingTime_Org2Stops, MaxCyclingTime_Stops2Dest 15 min Maximum cycling pre- and post-transport time of the base sets; in the signature of the leg stores.
MaxCyclingTime_Org2RM_Stops, _Org2RMT_Stops, _Org2Ric_Stops, _RM_Stops2Dest, _RMT_Stops2Dest, _OVF_Stops2Dest 15 min Maximum time of the derived cycling types; at most that of the base set.
MaxWalkingTime_Org2Dest, MaxCyclingTime_Org2Dest 90 min Maximum duration of a direct walking or cycling trip.
Cycling_StartTime 1 min Added to every cycling leg and direct cycling trip.
Cycling_ParkingTime_IC_Station, Advanced/Cycling_PreTransport_Penalty 3, 0 min Extra time at the end of a cycling pre-transport leg at an InterCity station, and at the end of every cycling pre-transport leg.
OVFiets_RentalPrice 4.45 euro Price of an OV-fiets leg.
PreTransport_*_Time_Costs, PostTransport_*_Time_Costs, Direct_*_Time_Costs 0.19 euro/min (walking), 0.09 euro/km (cycling) Time valuation of a leg or direct trip.
Advanced/IncludeWalkingCostsInPrice, Advanced/IncludeCyclingCostsInPrice FALSE, TRUE Does the time valuation of walking or cycling count in Price?
Advanced/CyclingNetwork 'OSM' 'OSM' or 'Fietsersbond'.
Advanced/Fietsersbond_file_date, Fietsersbond_MaxVeerpontLengte, Fietsersbond_VeerpontExtraTijd '20250525', 2 km, 5 min The Fietsersbond delivery and its ferries.