Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GTFS-Fares v2: One route behaviour #346

Closed
omar-kabbani opened this issue Aug 9, 2022 · 8 comments · Fixed by #439
Closed

GTFS-Fares v2: One route behaviour #346

omar-kabbani opened this issue Aug 9, 2022 · 8 comments · Fixed by #439
Labels
Change: Addition New function proposed to the specification. Extension: GTFS-Fares Issues and Pull Requests that focus on GTFS-Fares Extension GTFS Schedule Issues and Pull Requests that focus on GTFS Schedule Status: Discussion Issues and Pull Requests that are currently being discussed and reviewed by the community. Status: Pull Request Created Issues that have been transferred to the Pull Request stage. Support: Needs Review Needs support to review proposal.

Comments

@omar-kabbani
Copy link
Contributor

Hey everyone - we have been working with one route behaviour and we have identified a few issues that we want to run by the community.

The definition of routes.as_route is not very concise, our intention with the sentence “transferring within the network is ignored for fare transfer calculations” was that riders can transfer within a network without any form of fare processing (no taps, no ticket validation, no fees, etc.). Riders can simply get off the vehicle from the first service and get on the other one, for example: transferring between subway lines generally does not involve any fare processing since riders do not exit the fare paid zone. However, for most services, this is not the case, generally, transferring between different bus or train services requires some form of fare validation (even if the transfer is free).

Even if we go with the subway example, modeling the entire network as a single route means that riders transferring will not go through any fare validation. However, this is too general, and can be interpreted a a rider can get out at any station, walk to another station on a different line, and then get in without any form of fare processing. The specification needs to explicitly define exactly where riders can transfer without having to go through fare processing.

Having said that, we propose removing routes.as_route entirely and keeping transfers.as_route with the following changes:

  • Change the name to within_fare_paid_zone.
  • Change the description to “Indicates if the transfer for the specified from_stop_id and to_stop_id pair does not require any fare processing, payment, or validation”.
  • This would be at the network level, since GTFS-Fares v2 is centred around fare legs and networks. Additionally, these types of transfers are almost always restricted to transfers within the same network. Hence, we suggest adding a field for network_id that is required if this field is in use.

These changes do not contradict the rules in fare_transfer_rules.txt since they define how transfers are processed between different fare leg groups. Whereas this proposal adds a flag that transfers between routes at a given stop do not require fare processing (as if both routes behaved as a single route).

Please let us know your thoughts on these changes.

@npaun
Copy link
Contributor

npaun commented Aug 10, 2022

When Transit evaluated the original Fares v2 draft proposal, we found that transfers.as_route added a lot of confusion and complexity to the spec.

routes.as_route, however, is helpful for metro systems which use origin/destination-based ticketing. In these systems the rider pays based on their entry and exit points, regardless of the journey within the system. BART is a prominent example. If desired, this field could be renamed to within_fare_paid_zone, or something like use_od_ticketing.

Regardless of its name, I'd suggest the following wording for its definition:

Combine all contiguous legs using routes with the same network_id into a single leg representing the subjourney. Fare calculation is based on the origin and destination of that subjourney.

Since as_route is a property of the entire network, it may be worth placing it in a new file (e.g. fare_networks.txt) in order to improve the normalization of data, rather than keeping it in routes.txt.

@omar-kabbani
Copy link
Contributor Author

The BART example you described can be represented using fare_leg_rules.txt without the need for as_route, no?
If the origin and destination are defined in from_area_id and to_area_id and a fare_product_id is assigned to that OD pair, that should sufficiently represent the fare structure.

The field as_route is more about describing trips that do not require any form of fare processing to transfer. Just like how riders can transfer between the Montreal metro's 4 lines at any of the 4 transfer stations without any form of fare processing or validation. They simply get off a train, go to a different platform, and board another train. Hence the 4 metro lines can be considered as one route, since transfer rules are ignored.

The complexity that arises with treating all 4 lines as a single route is that technically, a rider can exit at a non-transfer station on the orange line, walk a few blocks to a non-transfer station on the green line, and enter without any form of fare processing or validation (again, technically, since all 4 lines are treated as a single route). This is why we proposed removing routes.as_route entirely and sticking with transfers.as_route. That way, we describe the transfers between the 4 lines specifically at the 4 transfer stations. So transfer rules are ignored when transferring between the 4 lines only at the 4 transfer stations.

@npaun
Copy link
Contributor

npaun commented Aug 15, 2022

Hi Omar,

BART's pricing can't be calculated by simply adding up the costs of the legs when transfers are involved. Consider the following trip: Take the Yellow line from Colma to Balboa Park ($3.60), then transfer to the Blue line and travel from Balboa Park to Coliseum ($5.10). Adding up the price of the legs would yield a cost of $8.70, but looking at the official pricing rules, it turns out any trip from Colma to Coliseum costs $5.20. There are several other places where you could transfer in order to go between those two stations, and calculations involving summing the price of legs would yield other incorrect results.

You could handle the Montreal example with an ordinary fare transfer rule: from_leg_group=metro, to_leg_group=metro, fare_product_id=free-transfer.

@omar-kabbani
Copy link
Contributor Author

Hey everyone - just a reminder that MobilityData is hosting a roundtable discussion on Wednesday 24 August at 11:00 AM ET to discuss the outstanding items regarding one-route behaviour. If you would like to attend, please react to this message or send an email to [email protected] and we will send you the invite.

For a summary and more details, please check out this post.

@omar-kabbani
Copy link
Contributor Author

This proposal was discussed on a call with @npaun and @jsteelz from Transit, their main concerns are listed below:

  • From a practical perspective, trip planning applications are not likely not going ask riders to exit a subway station, walk a few blocks, and enter another station (as described in my post here)
  • There are a few instances of out-of-station transfers, but are not very common. These should be represented in GTFS - whether under the as_route proposal described in this issue - or under a different proposal
  • Transit's interpretation of as_route is that a set of routes behave as a single route, and transfer rules are ignored (the BART scenario described by @npaun here and here). Basically describing networks that operate on an origin/destination basis where transfers do not matter, the only factor that affects pricing is where the rider taps on and off. Having a fare_product_id for A→C does not fix this if the only way to go from A to C is A→B→C (a trip planning app will by default sum the fares of A→B and B→C unless there is a flag like as_route.

I think both functionalities need to be in GTFS, and it is a matter of agreeing on the field names.
I think no_fare_validation would be a good name for the STM example and use_od_ticketing would be a good name for the BART example.

@isabelle-dr isabelle-dr added the GTFS Schedule Issues and Pull Requests that focus on GTFS Schedule label Nov 4, 2022
@bdferris-v2
Copy link
Collaborator

I want to call out that there is an alternative proposal from Google for as_route-like functionality that we think might be better for long-term use:

https://bit.ly/gtfs-fares-v2-fare-leg-join-rules-proposal

That doc is a long way of saying: I see the need for as_route-like functionality but I'm not a big fan of the spec proposal itself.

@npaun
Copy link
Contributor

npaun commented Feb 28, 2023

We're also in favour of adopting the fare_leg_join_rules.txt proposal here at Transit.

@2martens
Copy link

2martens commented Apr 1, 2023

I find the goal of this proposal very interesting. In Germany it is the default that there is no technical validation on transfers. Nevertheless, transfers might be fare-relevant but are not technically enforced. On random controls though, you need a valid ticket.

Some examples from Hamburg, Germany:

  • S31 from Altona to Sternschanze, transfer to U3 to Kellinghusenstraße: transfers within rail do not count as fare border and along the travelled routes is no fare border. Therefore, the lowest valid fare level is a short trip (Kurzstrecke)
  • U3 from Kellinghusenstraße to Barmbek, passing through Borgweg: Borgweg is a fare border. As you have crossed one fare border, you end up with regional trip (Nahbereich).
  • U3 from Sternschanze to Kellinghusenstraße, transfer to bus line 22 to Siemersplatz: you cross no fare border but the transfer to/from bus counts as fare border. Hence, it is also regional trip.
  • U2 from Niendorf Markt to Hauptbahnhof Nord (central station): you pass two or more fare borders and subsequently the rings begin to matter. In that case the journey starts in ring B and ends in ring A, therefore, the fare level is Hamburg AB. Once you reach the ring-level of fare levels, the transfers are no longer fare-relevant.
  • sometimes fare borders are not at passenger stops but between them on so called dummy stations (e.g. on ring change from ring B to ring C)
  • to complicate matters further, transfers to/from buses within the inner city area do NOT count as fare borders

This leads me to the question: how on earth can I model that with Fares V2?

@emmambd emmambd added the Extension: GTFS-Fares Issues and Pull Requests that focus on GTFS-Fares Extension label May 10, 2023
@tzujenchanmbd tzujenchanmbd added Status: Discussion Issues and Pull Requests that are currently being discussed and reviewed by the community. Change: Addition New function proposed to the specification. Support: Needs Review Needs support to review proposal. labels Jan 24, 2024
@tzujenchanmbd tzujenchanmbd added the Status: Pull Request Created Issues that have been transferred to the Pull Request stage. label Apr 2, 2024
@isabelle-dr isabelle-dr linked a pull request Apr 25, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Change: Addition New function proposed to the specification. Extension: GTFS-Fares Issues and Pull Requests that focus on GTFS-Fares Extension GTFS Schedule Issues and Pull Requests that focus on GTFS Schedule Status: Discussion Issues and Pull Requests that are currently being discussed and reviewed by the community. Status: Pull Request Created Issues that have been transferred to the Pull Request stage. Support: Needs Review Needs support to review proposal.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants