Skip to content

Proposal: Additional (Trip) Notices #620

Open

Description

@sebastianknopf

Describe the problem

Many data standards like NeTEx and HRDF offer data structures to provide additional human-readable notes assigned to trips in order to inform about specials not covered in technical properties or which shall be communicated in a certain, explicit wording to the passener. GTFS does this actually not, some data providers use informational service alerts for that (e.g. travic.app states additional notes under 'service alerts'). However, service alerts belong to the realtime data and are (for my understanding) meant to inform about unplanned changes. The additional notes I mean are already known during conceptual planning and belong not really to the scope of realtime data.

Use cases

Adding any arbitrary, non-technical, but already known notice to a trip, e.g.:

  • "Bike reservation recommended"
  • "Special Train - Dedicated fare is required"
  • "Express Bus - Please note the special trip times"
  • "Sesonal Trip - Runs during the XYZ festival"

Proposed solution

First draft:

  • Add a file notices.txt (notice_id, display_text, [tts_text])
  • Add a file trip_notices.txt (trip_id, notice_id)

Before I investigate more time here, I'd like to hear some of your opinions regarding this topic. I believe, I am not the only one having this issue.

Additional information

We must be careful when imolementing an extension like that, because it might lead to 'misuse' of the notices instead of filling already existing technical fields properly.

Activity

  1. skinkie commented on Apr 6, 2026

    @skinkie
    Contributor
  2. doconnoronca commented on Apr 6, 2026

    @doconnoronca
    Contributor

    Why not add new columns to trips rather then create new tables?

  3. skinkie commented on Apr 6, 2026

    @skinkie
    Contributor

    Why not add new columns to trips rather then create new tables?

    Because notices are not limited to trips. Because the cardinality does not match. So many reasons...

  4. sebastianknopf commented on Apr 6, 2026

    @sebastianknopf
    Author

    What about doing this similar to translations.txt?

    Good point! That could look like this:

    Column Type Required Comment
    notice_id Text Yes Required for uniquely identifying a notice for translations.
    table_name Enum Conditionally Required Identifies a table for which the notice is valid. Valid for routes, trips and stops. Required if an record_id is set.
    record_id Text Optional Primary key for the table specified in table_name. For routes use route_id, for trips use trip_id and for stops use stop_id. Can be left out for having a 'general notice' for the whole timetable.
    display_text Text Yes Text to be displayed within the notice.

    This way, we'd have a simple way to...

    • ... add notices for routes, trips and stops; could also be extended in future for other entity types
    • ... have multiple notices on one entity
    • ... to translate also the notices, if translations.txt will also be extended to use notices.txt

    The only thing missing is normalisation, but I think, keeping it simple could be more straigt forward here. I think, this would cover around 90% of all cases where an additional notice would be used in practice.

    Why not add new columns to trips rather then create new tables?

    As @skinkie said, this would not meet the requirement for having multiple notices on one entity and looks more like a customer based extension. I'd have implemented it like that way, but at first I want to discuss whether others may have the same requirements which could be adpted into the standard for all. If this is not the case, I could implement a system specific solution too.

  5. skinkie commented on Apr 6, 2026

    @skinkie
    Contributor

    @sebastianknopf exactly. And this makes it virtually analogue to NoticeAssignment in NeTEx :-)

  6. sebastianknopf commented on Apr 6, 2026

    @sebastianknopf
    Author

    @felixguendling, @BredeD as you have reacted in positive way, would you also like to give us your opinion here? I'm happy you like the idea, but my perspective of things might not be the one-and-only one.

  7. felixguendling commented on Apr 6, 2026

    @felixguendling

    Looking at how and where those notices are used in existing apps, you often want to:

    • show an icon for the notice, for example:
      • wifi icon for "free wifi"
      • bike icon for information about bike carriage (pricing, allowed not)
      • fork+knife icon for restaurant
      • etc.
    • group notices that belong together (e.g. notices regarding bike together)

    Example from Deutsche Bahn:
    Image

    It might make sense to standardize some very commonly used notice types to help developers show icons in those cases.

    It could also be connected to my images.txt proposal to give the feed publisher control over which icon gets displayed: #585

    Another thing we do internally in our data model in order to make it more compact is to group notices. Trip segments only reference a "notice group ID" instead of referencing every single notice. If notices are used a lot, this can make a significant difference in data model size. This could also apply here.

    Also, the proposal here only allows to attach notices to trips where other models (NeTEx + HRDF) allow to do this on a trip segment. Of course you could argue that you can split a trip into several trips and reconnect them (with block_id or transfer_type=4) every time the notice group changes (e.g. typically at Deutsche Bahn when the board restaurant opens/closes). We already have this problem when attributes like wheelchair support or bikes allowed change along the trip. So maybe it would make sense to make a decision for all these (very similar) problems.

  8. Brickblock1 commented on Apr 6, 2026

    @Brickblock1

    Column Type Required Comment
    notice_id Text Yes Required for uniquely identifying a notice for translations.

    Should this be required if only used for translation?

    table_name Enum Conditionally Required Identifies a table for which the notice is valid. Valid for routes, trips and stops. Required if an record_id is set.

    This would not make it possible to assign a notice to a particular stop of a certain trip which may be desirable for example in the instense a train is too short for a platform served by multiple different trips.

    display_text Text Yes Text to be displayed within the notice.

    I think also having a short summary text would add value. I believe NeTEx allows for this and it could save space on the screen whilst also closer mirroring the alerts in GTFS-RT.

  9. sebastianknopf commented on Apr 11, 2026

    @sebastianknopf
    Author

    Thank you for your feedback at all! I found there're two major points to be respected at all.

    Also, the proposal here only allows to attach notices to trips where other models (NeTEx + HRDF) allow to do this on a trip segment.

    Good point! I think, splitting the trip an re-connecting it with transfer_type=4 is not the optimal solution and could also lead to different problems. That would mean, that we need to extend the notice assignment similar to the translations, where we set a record_id and a record_sub_id when referencing an entity with composed primary key. This way, we could also reference stop times and consuming applications are able to group the assigned notices to the entire trip legs.

    This would not make it possible to assign a notice to a particular stop of a certain trip which may be desirable for example in the instense a train is too short for a platform served by multiple different trips.

    This would also be possible by assigning a certain stop time; as we have an precise match between a certain trip and a certain stop.

    I think also having a short summary text would add value. I believe NeTEx allows for this and it could save space on the screen whilst also closer mirroring the alerts in GTFS-RT.

    I personally don't see that in the scope, especially as the notcies should be really only short notices as @felixguendling shows in his example and no excessive texts. I thought about providing an additional URL field for a second, but I think this is the same anyway. This is at least what I know from the timetable software products I recently worked with.

    However, if a feed contains many assigned notices, we should think about a higher degree of normalization anyway, for example by using an additional notice_assignment.txt where we could assign one single defined notice to many other different entities. This could decrease the feed size significantly, when notices are used.

    So, I'm ending up with this draft here:

    notices.txt

    Column Type Required Comment
    notice_id Text Yes (PK) Required for uniquely identifying a notice for translations.
    notice_group_id Text No Optional group ID to group notices together. Could be referenced in notice_assignments.txt
    display_text Text Yes Text to be displayed within the notice.

    notice_assignments.txt

    Column Type Required Comment
    notice_id Text Conditionally Required Unique ID referencing the notice. Required if no notice_group_id is referenced.
    notice_group_id Text Conditionally Required ID of the notice group to be referenced. Required if no notice_id is set.
    table_name Enum Required Identifies a table for which the notice is valid. Valid for routes, trips, stops and stop_times.
    record_id Text Required Primary key for the table specified in table_name. For routes use route_id, for trips use trip_id, for stops use stop_id and for referencing a stop time, set it to the trip_id.
    record_sub_id Text Conditionally Required Required for referencing a certain stop_time, in that case record_id defines the trip_id and record_sub_id defines the stop_sequence the notice or notice group should be assigned to.
    start_date Date Optional Start date for when the notice or notice group shall be assigned.
    end_date Date Optional End date for when the notice or notice group shall be assigned.

    We're reflecting following changes:

    • New: Notices are normalized and only defined once for a single GTFS feed
    • New: Notices can also be assigned to certain stop times
    • New: We have a start date and an end date to be set optionally for a date restricted validity
    • Removed: We can not define a 'general notice' for the whole timetable anymore. However, I think this is not needed at all, as it would most times be misused instead of using the calendar or trip definitions properly.

    I'm looking forward to read about your opinions!

  10. doconnoronca commented on Apr 11, 2026

    @doconnoronca
    Contributor

    The examples mentioned above might be better covered by my vehicles.txt proposal I've been working on. It lets you describe features for vehicles such as buses and rail cars, including bike spaces, wifi and even food availability.

  11. felixguendling commented on Apr 11, 2026

    @felixguendling

    Required for referencing a certain stop_time

    I think it would help to clearly define that the attributes apply for the segment. Stop times are stop based, but notices only make sense if they apply to the part between two stops. Therefore, setting a notice on the last stop time wouldn't make sense (because there's no segment after that).

    start_date
    end_date

    If we are almost there, we could even make it an optional service_id.

    notice_group_id

    I think this will compact notices in the German NeTEx really nicely when converting to GTFS. At the moment it's not stated what happens if notice_group_id and notice_id are both set in notice_assignments.txt. I think we can excluded this case.


    Another thing that NeTEx allows and what I see in the Swiss NeTEx and what I would wish to be used in the German NeTEx is a marker that tells the system if this notice is supposed to be advertised to the customer. I think in Switzerland there might be information for the system in the train that controls the announcements, e.g. "Exit to the left" which is usually not shown in journey planners. Of course, GTFS is a customer facing format supposed to be used for journey planners, so actually this internal information should probably be removed in the first place. But I could imagine that such a flag might come handy for some data publishers?

  12. Brickblock1 commented on Apr 11, 2026

    @Brickblock1

    I think it would help to clearly define that the attributes apply for the segment. Stop times are stop based, but notices only make sense if they apply to the part between two stops. Therefore, setting a notice on the last stop time wouldn't make sense (because there's no segment after that).

    If that were the case you wouldn't be able to represent cases like the one below where the ability to transfer is only shown at the last stop.

    Image Image

    This could also be relevant if a single intermediate stop does for example not have level boarding. Simply setting the first and last stop of the notice to be the same should be enough in that case.

  13. felixguendling commented on Apr 11, 2026

    @felixguendling

    I don't really understand what you want to show us in the screenshot.

    if a single intermediate stop does for example not have level boarding

    That sounds like something you would want to consider during routing. So this is not supposed to be handled by notices. Maybe that's also something to mention: notices are just (free text) annotations that usually are not expected to impact routing. Wheelchair boarding, accessibility of pathways, etc. should not be handled with notices as long as there are other options that will directly improve routing results.

    If that were the case you wouldn't be able to represent cases like the one below where the ability to transfer is only shown at the last stop

    I agree that this case is not covered right now. But then I would also propose to clearly define in the spec what notices are about (the trip? the stop? both?) and when to show them to the user. The example notices from Deutsche Bahn I posted above are attached to the trip segments, not stops.

  14. sebastianknopf commented on Apr 12, 2026

    @sebastianknopf
    Author

    Okay, I didn't have in mind, that we have a difference between a stop time and a trip leg in technical details. Tahnking for bringing that back again, @felixguendling. But as @Brickblock1 mentioned too, wouldn't that be able to represent by defining the first stop sequence and the last stop sequence and make it up to the consuming system to display that in a trip leg? Am I misunderstanding something?

    If we are almost there, we could even make it an optional service_id.

    Absolutely, setting an optional service_id would make all benefits from service usable for notices too.

    Maybe that's also something to mention: notices are just (free text) annotations that usually are not expected to impact routing. Wheelchair boarding, accessibility of pathways, etc. should not be handled with notices as long as there are other options that will directly improve routing results.

    I think this is very important to mention! Notices are at most an annotation, when a proper technical field exists, which could be used for the consuming system. The notices are really just meant to provide a way for arbitrary, non-routing-affecting information to the passenger in a non-technical way. Hence, I think, we also should provide too many different options for providing notices in a GTFS feed, as they also may be misused instead of filling the proper technical fields correctly. I saw this at least in practice too often.

    In general, I think we shouldn't look at too many edge cases at all, but focus on where the notices are currently used in practice.

  15. felixguendling commented on Apr 12, 2026

    @felixguendling

    first stop sequence and the last stop sequence and make it up to the consuming system to display that in a trip leg? Am I misunderstanding something?

    Yes, that would work.

  16. 14 remaining items

  17. felixguendling commented on May 8, 2026

    @felixguendling

    Maybe a more generic naming already helps? record_sub_id_1, record_sub_id_2 could work.
    I think service_id could even apply to stops as well. E.g. if you want to "warn" users that there is a festival, etc.

  18. Brickblock1 commented on May 8, 2026

    @Brickblock1

    I'd say it's also useful for routes, more so than for trips even.

    The only alternative I can come up with for segments of trips as their own thing (similar to NeTEx JourneyPart) which would have the benefit of allowing other properties to have different values rather than just notices but that seems overly complicated, and rather illogical for single stop sequence notices.

  19. leonardehrenfried commented on May 8, 2026

    @leonardehrenfried
    Contributor

    I have updated the proposal to include translations: master...leonardehrenfried:transit:notices

    I will have a think if I can come up with something nicer for the segments but so far i like from/to_stop_sequence the best (well, i think it's the least bad).

    I will open a PR at some stage.

  20. leonardehrenfried commented on May 8, 2026

    @leonardehrenfried
    Contributor

    The only alternative I can come up with for segments of trips as their own thing (similar to NeTEx JourneyPart) which would have the benefit of allowing other properties to have different values rather than just notices but that seems overly complicated, and rather illogical for single stop sequence notices.

    I actually just understood what you meant by this: a new file trip_segments.txt (or whatever) which has the fields trip_segment_id, trip_id, from_stop_seq, to_stop_seq.

    I agree that it feels quite heavy ("NeTExy"?), but it has the benefit of being able to be added later because it would be a new table_name. Personally, I would consider it.

    Not sure how the community feels about the increase in the number of files.

  21. sebastianknopf commented on May 8, 2026

    @sebastianknopf
    Author

    Thank you @leonardehrenfried for moving this forward! I decided to give it a little time to be read by the community and have different opinions about that topic here. However, I see, I am not the only one with this problem so far. Thank you also for starting the preparation for a PR already. If this becomes more tangible, I also think I could provide some test data.

    Not sure how the community feels about the increase in the number of files.

    I also thought about that. But as it keeps GTFS still focused on informational purposes and the files are all optional, I think this is quite normal for a growing community standard. Hence, I see no problem here personally. I rather see a standardized way to cope with that issue (which affects even more users than I thought!), instead of having to deal with several 'custom' extensions living out there.

  22. leonardehrenfried commented on May 11, 2026

    @leonardehrenfried
    Contributor

    The more I think about it, the more I like having trip_segments as its own entity, because it also allows us to express boarding restrictions for bikes (for example) in a compact way. It also neatly solves the abstraction uglyness in notice_assignments.

  23. leonardehrenfried commented on May 21, 2026

    @leonardehrenfried
    Contributor

    I have distilled this issue into a concrete proposal: #638

    Let's continue there.

  24. leonardehrenfried commented on Jun 19, 2026

    @leonardehrenfried
    Contributor

    During code review of my current OTP implementation for trips and routes, my Norwegian colleagues brought up the following use case, that they use quite a bit in their NeTEx data: notices that are attached to a single stop_time (StopPointInJourneyPattern), because they don't apply to a segment from sequence A to B, but for example to all the "smaller" stops in the trip, but not the larger interchange points.

    They recommended that we keep our options open and assign to individual stop times, not segments.

    However, in GTFS there are no (materialized) patterns so this will be more verbose.

  25. felixguendling commented on Jun 19, 2026

    @felixguendling

    assign to individual stop times, not segments

    Your proposal already contains an inclusive range from_stop_sequence and to_stop_sequence. So setting from_stop_sequence == to_stop_sequence would cover this use case?

  26. leonardehrenfried commented on Jun 19, 2026

    @leonardehrenfried
    Contributor

    I guess and it would be no more verbose than having something like a stop_time_notices.txt.

  27. optionsome commented on Jun 22, 2026

    @optionsome

    Should the notice have a header and description like alerts have? I think it would be useful for our use cases. I can ask around if I can find a data producer to produce notice data in Finland.

  28. optionsome commented on Jun 22, 2026

    @optionsome

    Here is an example of a use case for the notice data:
    Image

    We get requests from different cities every once in a while to add these kind of notices for some of their lines and we would prefer if those could be put in the data instead of us having to maintain these in our UI code.

  29. leonardehrenfried commented on Jun 22, 2026

    @leonardehrenfried
    Contributor

    I think I would prefer a title field to people putting weird formatting strings or HTML into the main text.

  30. optionsome commented on Jun 23, 2026

    @optionsome

    I realized we would also need some "URL" field to complete the screenshotted use case as you can click the box which then redirects to some information page.

  31. leonardehrenfried commented on Jun 23, 2026

    @leonardehrenfried
    Contributor

    If you commit to becoming a data producer for the proposal (even vaguely) I can add those fields to it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Change type: FunctionalRefers to modifications that significantly affect specification functionalities.GTFS ScheduleIssues and Pull Requests that focus on GTFS Schedule

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions