Multimodal and wheelchair: GTFS wheelchair_boarding not considered for in-station transfers
- Dominant language
- C++
- Stars
- 6.2k
- Forks
- 981
- Avg merge
- 2d 14h
- Merged PRs (30d)
- 14
Description
Hi,
I recently jumped into the multimodal routing algorithm, thanks to the new GTFS loader. Which works really great :+1:
I'm mainly interested in wheelchair routing - currently working on a highly specialized custom costing, feeded with proprietary data. When playing around with multimodal routes, I realized that:
- `wheelchair_boarding` in GTFS stops is taken into account when transitioning from pedestrian to transit or the opposite: if the pedestrian costing `type` is `wheelchair`, the user won't be able to start or end a route from a stop without `wheelchair_boarding`
- This is not true for in-station transfers (changing trip at the same stop): the multimodal algorithm will happily ask the user to change bus in a stop without `wheelchair_boarding`. But in real life this would mean changing vehicle, so unboarding from the first one and boarding into the second one. Which sounds wrong if the stop os not `wheelchair_boarding` capable.
I realize multimodal + wheelchair is kinda dragon zone. So I first wanted to share my findings and the fix I did on my side to see if it sounds good to you. If so I'll be happy to try to write a test case and contribute a fix.
**What I found:**
GTFS `wheelchair_boarding` is set on transit stop nodes during transit ingestion:
https://github.com/valhalla/valhalla/blob/c9c241873bab2155c814d5d04ab740f492427b06/src/mjolnir/ingest_transit.cc#L278-L279
This info will be translated into access mask on the hraph node during transit conversion:
https://github.com/valhalla/valhalla/blob/c9c241873bab2155c814d5d04ab740f492427b06/src/mjolnir/convert_transit.cc#L1061-L1063
and then
https://github.com/valhalla/valhalla/blob/c9c241873bab2155c814d5d04ab740f492427b06/src/mjolnir/convert_transit.cc#L593-L596
When connecting transit stops to the graph, new directed edges connected to this stop will inherit the access mask from the stop node:
https://github.com/valhalla/valhalla/blob/c9c241873bab2155c814d5d04ab740f492427b06/src/mjolnir/transitbuilder.cc#L233-L258
And finally, for some reason, access mask on the stop node in then reset (probably because this stop can be traversed on transit):
https://github.com/valhalla/valhalla/blob/c9c241873bab2155c814d5d04ab740f492427b06/src/mjolnir/transitbuilder.cc#L299-L300
So far, so good! A routing request with `"type":"wheelchair"` in pedestrian costing won't be able to walk those transfer edges, so no boarding / unboarding will be possible when transitioning from pedestrian graph to transit graph and vice versa.
But the multimodal algorithm, doesn't consider the pedestrian costing for in-station transfers: it just look for the next departure at this stop:
https://github.com/valhalla/valhalla/blob/c9c241873bab2155c814d5d04ab740f492427b06/src/thor/multimodal.cc#L391-L404
(the `tc->wheelchair()` here will be used to exclude if needed stop pairs from GTFS trips without `wheelchair_accessible`, which is not related to `wheelchair_boarding`.
**What I did:**
Don't reset access mask on the stop node, keep access mask inherited from `wheelchair_boarding`.
This doesn't break the transit costing because it does not evaluate access mask on nodes:
https://github.com/valhalla/valhalla/blob/c9c241873bab2155c814d5d04ab740f492427b06/src/sif/transitcost.cc#L560-L563
Then in multimodal algorithm, check access for the stop with **pedestrian costing** to check if boarding / unboarding is allowed for in-station transfers.
```cpp
// In station transfer mean changing vehicle.
// First check if pedestrian costing allow traversing this node:
// Unboarding from the first vehicle, boarding in the second one
if (!pc->Allowed(nodeinfo)) {
continue;
}
```
This work in my use case, but there might be unwanted side effects, and better options.
Contributor guide
Assessment
This issue has not been assessed yet.