-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
Current limitations
At the moment transfers are only calculated during graph building, this limits the flexibility of transfers considerably. For example transfers are only calculated when they are considered to be the best connection between one stop and a second stop on a trip pattern in the scheduled data. The trip patterns however can change with real time updates, for example extra trips can be added that use previously unused stops. At the moment this is solved by calculating more transfers than necessary during graph building, which is not optimal.
Additionally, issue #6533 needs a way to update transfers based on a flag that is set on one of its edges.
Proposed solution
For this reason, a new service that enables the recalculation of transfers during runtime shall be implemented. Design decisions for this service will be documented here.
Current structure of transfers
-
PathTransferis build during graph building. It optimizes by only considering the best connection from one stop to a second stop on a trip pattern in the scheduled data. It can refer toAreaStop,GroupStoporRegularStop -
Transferis created during start up fromPathTransferand lives in theRaptorTransitData. It can only refer toRegularStop -
RaptorTransferis then generated for the default request and stored in a cache. The cache assumes that the list ofTransferstays the same. The cache key holds information about street relevant routing options (like accessibility).
Additionally there is the ConstrainedTransfer. It reflects transfer constraints specified in the GTFS or Netex Data, so it will not be directly impacted by the updates.
Desired structure of transfers
Renaming
PathTransfer shall be renamed to RegularTransfer, right in line with RegularStop. Right now it is not quite clear what a PathTransfer referencing AreaStop or GroupStop is, so this might be adjusted accordingly.
Transfer module
In order to have only one place where transfers can live and be modified, a new top level transfer module, similar to the street and transit modules will be introduced. The module is responsible for holding and modifying all transfers. This includes RegularTransfer and ConstrainedTransfer.
Updating transfers consistently
Since transfers will be mutable, a similar snapshot mechanic as for the transit data will have to be implemented. For this the working idea is to introduce a SnapshotFramework that will be used by both the transit updaters and the transfer updaters. This framework will have to make sure that transfers and transit used by raptor are at all times both consistent in themselves and also compatible to each other.
When transfers are updated, the RaptorTransfers need to be updated as well. There are two possible solutions for this:
- create a complete new set of
RaptorTransfers for the default request. This is less error prone and the transfers that are used together will lie together in memory. Transfer creation might be too expensive however. - only update transfers that need to be updated, but for all cached request options. This is more error prone,
RaptorTransfers that are used together will not necessarily be together in memory, but updating is faster.
Classes modeling a transfer
Instead of the three layers described in the first section (PathTransfer, Transfer, RaptorTransfer) we should only be needing two layers:
RegularTransfer: This will be used in the transfer module and in the snapshotRaptorTransfer: This is a request option specific raptor representation
Recalculating Transfers
There are several use cases that would have to update a transfer.
Elevator status change
All transfers that include a stop near the elevator in question will have to be updated (finding the correct stops reasonably fast via indexing is not in scope of this issue)
For each elevator relevant stop:
- do an A* search to calculate all updated transfers
- replace all transfers having the relevant stop as a from stop with the newly calculated ones
Workflow
- refactor existing code into the transfer module structure
- extract transit snapshot mechanics into a framework (only refactoring)
- introduce transfer snapshot mechanics using the framework
- implement A* searches for transfer updates