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

Add variable fares by time or day #357

Merged
Merged
Changes from 26 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
94d15cb
Added timeframes
omar-kabbani Aug 4, 2022
bfc2b12
Add date-based fares
omar-kabbani Aug 5, 2022
713e91c
Update timeframes.txt description
isabelle-dr Nov 14, 2022
5a8ca38
Change end time from required to optional
isabelle-dr Nov 14, 2022
0b7c9e2
Records with the same timeframe id must cover a 24h period
isabelle-dr Nov 14, 2022
fd2eb13
no overlap
isabelle-dr Nov 14, 2022
991ccba
remove requirement on 24h coverage and overlapping
isabelle-dr Nov 15, 2022
d2e89a6
fix typo
isabelle-dr Nov 21, 2022
710be10
Revert changes in timeframes.end_time
isabelle-dr Nov 23, 2022
f9a4a1d
move service_id to timeframes.txt
isabelle-dr Mar 10, 2023
84da99f
Move timeframes to the fares v2 section
isabelle-dr Mar 10, 2023
b8aad98
rename timeframe_id to timeframe_group_id
isabelle-dr Mar 10, 2023
438dbf2
Merge branch 'master' into GTFS-Fares-v2-time-variable-fares
isabelle-dr Mar 15, 2023
d68c3fd
place timeframes.txt with other Fares v2 files
isabelle-dr Mar 15, 2023
50e60c8
Rename from/to fields + change empty semantics
isabelle-dr Mar 21, 2023
d42bfdf
add line break
isabelle-dr Mar 21, 2023
50a080d
Add timeframes description
isabelle-dr Mar 23, 2023
19dae72
Make timeframe fields required
isabelle-dr Mar 23, 2023
0222fff
service_id references calendar or calendar_dates
isabelle-dr Mar 23, 2023
27f5c06
Add requirements
isabelle-dr Mar 23, 2023
9bd26d0
typo
isabelle-dr Mar 23, 2023
acd9d0d
Update timeframe fields description
isabelle-dr Apr 4, 2023
a182e6c
end time is not included in the interval
isabelle-dr Apr 4, 2023
e8463ce
Add timeframe_type field
isabelle-dr Apr 4, 2023
477ab30
Overlapping time frames must not be defined
isabelle-dr Apr 5, 2023
c34bfed
introduce override
isabelle-dr Apr 5, 2023
d4afc6e
improve override description
isabelle-dr Apr 7, 2023
55679c9
Revert "improve override description"
isabelle-dr Apr 7, 2023
189822f
improve override description
isabelle-dr Apr 7, 2023
f0e18a8
update timeframe fields description
isabelle-dr Apr 7, 2023
0aedadc
remove timeframe fields for no exact matched found
isabelle-dr Apr 11, 2023
91bda27
Update descriptions for empty values:
isabelle-dr Apr 11, 2023
af4b67b
Both values need to be empty or neither should be empty
isabelle-dr May 24, 2023
fe45e7e
Change to local time semantics
isabelle-dr May 24, 2023
045258f
Changed name start/end_timeframe_group_id
tzujenchanmbd May 24, 2023
ad54f36
Remove timeframe_type & priority fields
tzujenchanmbd May 24, 2023
518578b
revise "start" to "end"
tzujenchanmbd May 25, 2023
f33a935
Remove "initial" after Gavriel's comment
isabelle-dr Jun 25, 2023
4bf749f
Remove unnecessary empty description
tzujenchanmbd Jul 19, 2023
0007c89
Changes based on Jeremy's feedback
tzujenchanmbd Jul 20, 2023
1a65d75
Modify empty wording
tzujenchanmbd Jul 20, 2023
12c3bb7
Move overlapping requirement out of service_id description
isabelle-dr Jul 27, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 29 additions & 4 deletions gtfs/spec/en/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ This document defines the format and structure of the files that comprise a GTFS
- [calendar\_dates.txt](#calendar_datestxt)
- [fare\_attributes.txt](#fare_attributestxt)
- [fare\_rules.txt](#fare_rulestxt)
- [timeframes.txt](#timeframestxt)
- [fare\_media.txt](#fare_mediatxt)
- [fare\_products.txt](#fare_productstxt)
- [fare\_leg\_rules.txt](#fare_leg_rulestxt)
Expand Down Expand Up @@ -110,6 +111,7 @@ This specification defines the following files:
| [calendar_dates.txt](#calendar_datestxt) | **Conditionally Required** | Exceptions for the services defined in the [calendar.txt](#calendartxt). <br><br>Conditionally Required:<br> - **Required** if [calendar.txt](#calendartxt) is omitted. In which case [calendar_dates.txt](#calendar_datestxt) must contain all dates of service. <br> - Optional otherwise. |
| [fare_attributes.txt](#fare_attributestxt) | Optional | Fare information for a transit agency's routes. |
| [fare_rules.txt](#fare_rulestxt) | Optional | Rules to apply fares for itineraries. |
| [timeframes.txt](#timeframestxt) | Optional | Date and time periods to use in fare rules for fares that depend on date and time factors. |
| [fare_media.txt](#fare_mediatxt) | Optional | To describe the fare media that can be employed to use fare products. <br><br>File [fare_media.txt](#fare_mediatxt) describes concepts that are not represented in [fare_attributes.txt](#fare_attributestxt) and [fare_rules.txt](#fare_rulestxt). As such, the use of [fare_media.txt](#fare_mediatxt) is entirely separate from files [fare_attributes.txt](#fare_attributestxt) and [fare_rules.txt](#fare_rulestxt). |
| [fare_products.txt](#fare_productstxt) | Optional | To describe the different types of tickets or fares that can be purchased by riders.<br><br>File [fare_products.txt](#fare_productstxt) describes fare products that are not represented in [fare_attributes.txt](#fare_attributestxt) and [fare_rules.txt](#fare_rulestxt). As such, the use of [fare_products.txt](#fare_productstxt) is entirely separate from files [fare_attributes.txt](#fare_attributestxt) and [fare_rules.txt](#fare_rulestxt). |
| [fare_leg_rules.txt](#fare_leg_rulestxt) | Optional | Fare rules for individual legs of travel.<br><br>File [fare_leg_rules.txt](#fare_leg_rulestxt) provides a more detailed method for modeling fare structures. As such, the use of [fare_leg_rules.txt](#fare_leg_rulestxt) is entirely separate from files [fare_attributes.txt](#fare_attributestxt) and [fare_rules.txt](#fare_rulestxt). |
Expand Down Expand Up @@ -345,6 +347,21 @@ For examples that demonstrate how to specify a fare structure with [fare_rules.t
| `destination_id` | Foreign ID referencing `stops.zone_id` | Optional | Identifies a destination zone. If a fare class has multiple destination zones, create a record in [fare_rules.txt](#fare_rules.txt) for each `destination_id`.<hr>*Example: The `origin_id` and `destination_id` fields could be used together to specify that fare class "b" is valid for travel between zones 3 and 4, and for travel between zones 3 and 5, the [fare_rules.txt](#fare_rules.txt) file would contain these records for the fare class:* <br>`fare_id,...,origin_id,destination_id` <br>`b,...,3,4`<br> `b,...,3,5` |
| `contains_id` | Foreign ID referencing `stops.zone_id` | Optional | Identifies the zones that a rider will enter while using a given fare class. Used in some systems to calculate correct fare class. <hr>*Example: If fare class "c" is associated with all travel on the GRT route that passes through zones 5, 6, and 7 the [fare_rules.txt](#fare_rules.txt) would contain these records:* <br> `fare_id,route_id,...,contains_id` <br> `c,GRT,...,5` <br>`c,GRT,...,6` <br>`c,GRT,...,7` <br> *Because all `contains_id` zones must be matched for the fare to apply, an itinerary that passes through zones 5 and 6 but not zone 7 would not have fare class "c". For more detail, see [https://code.google.com/p/googletransitdatafeed/wiki/FareExamples](https://code.google.com/p/googletransitdatafeed/wiki/FareExamples) in the GoogleTransitDataFeed project wiki.* |

### timeframes.txt

File: **Optional**

Primary key (*)

Used to describe fares that can vary based on the time of day, the day of the week, or a particular day in the year. Timeframes can be associated with fare products in `fare_leg_rules.txt`.

| Field Name | Type | Presence | Description |
| ------ | ------ | ------ | ------ |
| `timeframe_group_id` | ID | **Required** | Identifies a timeframe or set of timeframes. |
| `start_time` | Time | **Required** | Start time for the interval. The interval includes the start time. |
| `end_time` | Time | **Required** | End time for the interval. The interval does not include the end time. |
| `service_id` | Foreign ID referencing `calendar.service_id` or `calendar_dates.service_id` | **Required** | Identifies a set of dates that a timeframe is in effect. <br>There must not be overlapping time intervals for the same `timeframe_group_id` and `service_id` values. |

### fare_media.txt

File: **Optional**
Expand Down Expand Up @@ -380,7 +397,7 @@ To describe the different types of tickets or fares that can be purchased by rid

File: **Optional**

Primary Key (`network_id, from_area_id, to_area_id, fare_product_id`)
Primary Key (`network_id, from_area_id, to_area_id, start_timeframe_group_id, end_timeframe_group_id, fare_product_id`)

Fare rules for individual legs of travel.

Expand All @@ -391,14 +408,18 @@ To process the cost of a leg:
1. The file `fare_leg_rules.txt` must be filtered by the fields that define the characteristics of travel, these fields are:
- `fare_leg_rules.network_id`
- `fare_leg_rules.from_area_id`
- `fare_leg_rules.to_area_id`<br/>
- `fare_leg_rules.to_area_id`
- `fare_leg_rules.start_timeframe_group_id`
- `fare_leg_rules.end_timeframe_group_id`<br/>
<br/>

2. If the leg exactly matches a record in `fare_leg_rules.txt` based on the characteristics of travel, that record must be processed to determine the cost of the leg.
3. If no exact matches are found, then empty entries in `fare_leg_rules.network_id`, `fare_leg_rules.from_area_id`, and `fare_leg_rules.to_area_id` must be checked to process the cost of the leg:
<br/>

3. If no exact matches are found, then empty entries in `fare_leg_rules.network_id`, `fare_leg_rules.from_area_id`, `fare_leg_rules.to_area_id`, `fare_leg_rules.start_timeframe_group_id`, and `fare_leg_rules.end_timeframe_group_id` must be checked to process the cost of the leg:
- An empty entry in `fare_leg_rules.network_id` corresponds to all networks defined in `routes.txt` excluding the ones listed under `fare_leg_rules.network_id`
- An empty entry in `fare_leg_rules.from_area_id` corresponds to all areas defined in `areas.area_id` excluding the ones listed under `fare_leg_rules.from_area_id`
- An empty entry in `fare_leg_rules.to_area_id` corresponds to all areas defined in `areas.area_id` excluding the ones listed under `fare_leg_rules.to_area_id`<br/>
- An empty entry in `fare_leg_rules.to_area_id` corresponds to all areas defined in `areas.area_id` excluding the ones listed under `fare_leg_rules.to_area_id`
<br/>

4. If the leg does not match any of the rules described above, then the fare is unknown.
Expand All @@ -411,7 +432,11 @@ To process the cost of a leg:
| `network_id` | Foreign ID referencing `routes.network_id` | Optional | Identifies a route network that applies for the fare leg rule.<br><br>If there are no matching `fare_leg_rules.network_id` values to the `network_id` being filtered, empty `fare_leg_rules.network_id` will be matched by default.<br><br> An empty entry in `fare_leg_rules.network_id` corresponds to all networks defined in `routes.txt` excluding the ones listed under `fare_leg_rules.network_id` |
| `from_area_id` | Foreign ID referencing `areas.area_id` | Optional | Identifies a departure area.<br><br>If there are no matching `fare_leg_rules.from_area_id` values to the `area_id` being filtered, empty `fare_leg_rules.from_area_id` will be matched by default. <br><br>An empty entry in `fare_leg_rules.from_area_id` corresponds to all areas defined in `areas.area_id` excluding the ones listed under `fare_leg_rules.from_area_id` |
| `to_area_id` | Foreign ID referencing `areas.area_id` | Optional | Identifies an arrival area.<br><br>If there are no matching `fare_leg_rules.to_area_id` values to the `area_id` being filtered, empty `fare_leg_rules.to_area_id` will be matched by default.<br><br> An empty entry in `fare_leg_rules.to_area_id` corresponds to all areas defined in `areas.area_id` excluding the ones listed under `fare_leg_rules.to_area_id` |
| `start_timeframe_group_id` | Foreign ID referencing `timeframes.timeframe_group_id` | Optional | Defines the timeframe for the departure of the fare leg.<br><br>For a fare leg rule that specifies a `start_timeframe_group_id`, that rule will match a particular leg if there exists at least a row in `timeframes.txt` where all of the following conditions are true:<br>- The row’s `timeframe_group_id` is equal to the `start_timeframe_group_id` value.<br>- The set of service days identified by the row’s `service_id` contains the service day of the leg’s departure trip.<br>- The departure time of the leg, relative to the service day per [GTFS Time field type](#field-types) conventions, is greater than or equal to the rows `start_time` value and less than the `end_time` value.<br><br>If there are no matching `fare_leg_rules.start_timeframe_group_id` values to the `timeframe_group_id` being filtered, empty `fare_leg_rules.start_timeframe_group_id` will be matched by default. <br><br>An empty `fare_leg_rules.start_timeframe_group_id` indicates that the start time of the leg does not affect the fare. |
| `end_timeframe_group_id` | Foreign ID referencing `timeframes.timeframe_group_id` | Optional | Defines the timeframe for the arrival of the fare leg.<br><br>For a fare leg rule that specifies a `end_timeframe_group_id`, that rule will match a particular leg if there exists at least a row in `timeframes.txt` where all of the following conditions are true:<br>- The row’s `timeframe_group_id` is equal to the `end_timeframe_group_id` value.<br>- The set of service days identified by the row’s `service_id` contains the service day of the leg’s departure trip.<br>- The arrival time of the leg, relative to the service day per [GTFS Time field type](#field-types) conventions, is greater than or equal to the rows `start_time` value and less than the `end_time` value.<br><br>If there are no matching `fare_leg_rules.end_timeframe_group_id` values to the `timeframe_group_id` being filtered, empty `fare_leg_rules.end_timeframe_group_id` will be matched by default. <br><br>An empty `fare_leg_rules.end_timeframe_group_id` indicates that the end time of the leg does not affect the fare. |
| `timeframe_type` | Enum | **Conditionally Required** | Defines the type of fare validation to be associated with `timeframes.start_time` and `timeframes.end_time`.<br><br>Valid options are:<br>`0` - In vehicle.<br>`1` - At fare gate or on platform.<br><br>Conditionally Required:<br>- **Required** if either `start_timeframe_group_id` or `end_timeframe_group_id` is defined.<br>- **Forbidden** otherwise.|
| `fare_product_id` | Foreign ID referencing `fare_products.fare_product_id` | **Required** | The fare product required to travel the leg. |
| `override` | Non-negative integer | Optional | When multiple entries in `fare_leg_rules.txt` match, the one with the highest `override` value will be selected.<br><br>An empty value for `override` is treated as zero.|

### fare_transfer_rules.txt

Expand Down