Home

Awesome

gtfs-blocks-to-transfers

Converts GTFS blocks, defined by setting trip.block_id into a series of trip-to-trip transfers (GTFS specification). Uses configurable heuristics to predict whether two trips are connected as in-seat transfers or as vehicle continuations only. This tool also validates predefined trip-to-trip transfers in transfers.txt.

Usage: ./convert.py <input feed> <directory for output>

Install

The easiest way to install the tool is to clone this repository, then run pip install -e .

If that doesn't work, try to run python3 manual_install.py.

How it works

Throughout this tool, sets of service days are used to relate trips. They are defined in service_days.py, and are represented as a bitmap per service_id, with bit n set to 1 if that service operates on the nth day since the beginning of the feed. The term trip's service days refers to the service days for trip.service_id. If the first departure of a trip is after 24:00:00, the service days are stored as-if the trip began the next day between 00:00:00 and 23:59:59.

For each block defined in the feed, convert_blocks.py finds the most likely continuations for each trip, starting the search after the final arrival time of the trip. The program searches for a matching continuation for all of the trip's service days, greedily selecting continuation trips in order of wait time. Some days may remain unmatched if a configurable threshold is exceeded (config.TripToTripTransfers.max_wait_time). classify_transfers.py uses heuristics to assign transfer_type=4 (in-seat transfer) or transfer_type=5 to each continuation.

Generated transfers are combined with predefined transfers from transfers.txt in simplify_graph.py. If necessary, this step will split trips such that for any given from_trip_id, each of the potential to_trip_id, will operate on a disjoint set of service days. For example bus 50 could continue to bus 15 on Monday through Thursday, but continue to bus 20 on Fridays. Both generated and predefined transfers are validated to ensure they are unambiguous and conform to the specification.

simplify_export.py converts the continuation graph back to a series of transfers, resuing the feed's existing trip_ids and service_ids when an exact match can be found, or creating new entities if required. This step will preserve trip-to-trip transfers that don't represent vehicle continuations (e.g. transfer_type=2 used to estimate walk time between two vehicles).

Heuristics

An in-seat transfer is likely if:

Riders probably won't be able to, or want to, to stay on board if:

You can adjust thresholds or entirely disable a heuristic in blocks_to_transfers/config.py. Configuration can also be provided as a JSON string with the --config argument.

Special continuations

Precise rules can also be added to enable or disable in-seat transfers for particular stops and routes within a feed.

A rule is a JSON object consisting of three parts:

The following selectors are supported:

When a transfer matches multiple rules, the last rule wins. For transfers predicted from blocks, special continuation rules override all heuristics except max_wait_time. Rules never apply to predefined transfers specified using transfers.txt.

For example, to enable in-seat transfers only for routes 20 and 99 the following configuration can be set:

{
    "SpecialContinuations": [
        {
            "match": [
                {"all": true}
            ],
            "op": "modify",
            "transfer_type": 5
        },
        {
            "match": [
                {"through": {"route": "20"}},
                {"through": {"route": "99"}}
            ],
            "op": "modify"
            "transfer_type": 4
        }
    ]
} 

Advanced