Skip to content

Proposal: Support stop assignments in GTFS-RT #219

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

Merged
merged 14 commits into from
Nov 12, 2020

Conversation

barbeau
Copy link
Collaborator

@barbeau barbeau commented Apr 29, 2020

Background

Several producers and consumers have expressed the need to reflect platform assignments within stations in real-time. However, the GTFS-RT spec currently does not officially support this use case. The spec is unclear whether changing stop_id to a value other than what is defined in GTFS stop_times.txt for a given stop_sequence is an error [1].

Proposal

This proposal adds a new message and field StopTimeProperties.platform_id StopTimeProperties.assigned_stop_id (within StopTimeUpdate) which can be used to specify assignments to platform stop_ids within the same parent station as the stop originally defined in static GTFS changes to the stop within the trip (see Oct 27, 2020 Update below).

This pull request is a subset of the GTFS-ServiceChanges v3.1 spec:
https://bit.ly/gtfs-service-changes-v3_1

Because platform assignments are currently implemented by a few producers and at least one consumer by changing the StopTimeUpdate stop_id [2], this feature could be adopted prior to the rest of the entire ServiceChanges spec. with minimal changes to existing feeds.

This proposal uses the terminology platform_id assigned_stop_id for a new field, instead of (re)using stop_id for several reasons:

  1. The only targeted use case for this new field is changing stop_ids within a station - producers cannot put any stop_id in this field and expect consumers to be able to process this change to the trip geometry quickly. If the field is named stop_id, producers and consumers may start using the field for other use cases of changing stops within a trip (e.g., detours). Therefore, the field is narrowly named platform_id instead of stop_id to make the use case very clear, even if the spec documentation isn't read. (see Oct 27, 2020 Update below)
  2. ServiceChanges defines a more robust solution for detours that can change/add stops within the trip by adding a new Trip object with new StopTime objects to the real-time feed. However, it takes consumers longer to process these new trips due to necessary pre-processing, and therefore this approach is not suitable for platform assignments that must be processed in the same order-of-magnitude of time as arrival predictions. Therefore, platform assignments should be implemented separately from more complex detours.
  3. Re-using the existing StopTimeUpdate stop_id field to assign platforms causes issues with feed quality and validation - it's not clear whether the change from the static GTFS stop_id is intentional or an error. Using a new field platform_id assigned_stop_id makes the intent to assign a platform explicit and unambiguous. (see Oct 27, 2020 Update below)

To further clarify the spec, this proposal also adds documentation saying StopTimeUpdate stop_id and stop_sequence pairings must match static GTFS - in other words, it clarifies that these fields are selectors to specify the stop, and cannot be modified in real-time. EDIT Per further discussion in this thread, enforcing stop_id/stop_sequence pairing matching GTFS is no longer proposed in this PR - it can be discussed along with the larger set of ServiceChanges v3.1.

Future proposals may add other fields defined in GTFS stop_times.txt to the StopTimeProperties message (e.g., pickup_type, drop_off_type, stop_headsign, shape_dist_traveled) so they can be changed in real-time. See the ServiceChanges proposal for more info.

@paulswartz @skinkie I believe you are both producers of the existing unofficial method of platform assingments. Thoughts on the above? Could you switch to using StopTimeProperties.platform_id StopTimeProperties.assigned_stop_id instead?

cc @tleboulenge

Announced on the Google Group at https://groups.google.com/forum/#!topic/gtfs-realtime/3sTrsi2Sw5U.

Oct 27, 2020 Update

Changes based on community feedback. See #219 (comment) for details. Summary:

  • Field name change of platform_id -> assigned_stop_id - The feature is no longer constrained to just platforms within stations (see next point).
  • Use more generic language to define when assigned_stop_id can be used (versus requiring changes to be only within a station). This broadens potential uses cases of the field without being as prescriptive. There is intentional use of the word "should" vs. "must" in some cases to allow for deviation from the platform assignments use case.
  • Add that you can assign a stop without providing real-time predictions by using StopTimeUpdate.schedule_relationship = NO_DATA (based on @sunny-lirr question above)
  • Require that StopTimeUpdate.stop_sequence be used as the selector (based on @skinkie feedback above in moving towards using stop_sequence as the selector in Proposal: Support stop assignments in GTFS-RT #219 (comment))
  • Don't block use of StopTimeUpdate.stop_id being populated with other values in case others want to have unofficial GTFS-realtime feeds that changes stop_id to represent a different stop (e.g., @skinkie with Bliksem Labs B.V. wants to be able to define detours by populating TripUpdates with the entire stop sequence list, aka "GTFS-realtime full"). Therefore, this proposal doesn't block the current use or potential future adoption of a "GTFS-realtime full" if the community would desire this.

[1] #81, CUTR-at-USF/gtfs-realtime-validator#297
[2] https://groups.google.com/d/msg/gtfs-realtime/BZOfsVeI2Cc/gIUjGbkCBAAJ

* Add .proto changes for platform_id
* Add documentation saying stop_id and stop_sequence pairings should match static GTFS
* Add platform_id documentation in Markdown files
@barbeau barbeau added the GTFS Realtime Issues and Pull Requests that focus on GTFS Realtime label Apr 29, 2020
@skinkie
Copy link
Contributor

skinkie commented Apr 29, 2020

-1 it has previously been indicated that changes in stop_id for tripUpdates are allowed if the stop_id falls within the same parent_station. Currently a stop has a both a stop_id and platform_code field. Introducing an extra field platform_id creates even more complex processing, because the stop_id cause should be handled anyway.

@paulswartz
Copy link
Contributor

We could provide this, but we'd need to continue to also change stop_id until larger consumers like Apple and Google commit to supporting a new field.

@gcamp
Copy link
Contributor

gcamp commented Apr 29, 2020

Currently a stop has a both a stop_id and platform_code field. Introducing an extra field platform_id creates even more complex processing, because the stop_id cause should be handled anyway.

Adding platform_id actually simplifies the processing for consumer because it makes the intent very clear about what is happening and it avoid additional processing if the stop_id doesn't match.

Currently Transit doesn't support that unofficial extension since, well, its unofficial.

@skinkie
Copy link
Contributor

skinkie commented Apr 29, 2020

Adding platform_id actually simplifies the processing for consumer because it makes the intent very clear about what is happening and it avoid additional processing if the stop_id doesn't match.

It doesn't simplify anything if you also want to implement a detour in the same software. Why an if-then-else case if you could just replace a stop. We both know why planners using transfer patterns can't use a trip pattern that falls outside of a parent_station. Hence it does not make sense to explicitly support it, if the software that already supports it, added the restriction in the first place.

@gcamp
Copy link
Contributor

gcamp commented Apr 29, 2020

It doesn’t simplify anything if you also want to implement a detour in the same software. Why an if-then-else case if you could just replace a stop.

It’s also about making the spec understandable. Even if this is specified in the documentation changing the stop_id is far from obvious to a newcomer. My point was also that stop_id sometime doesn’t match due to errors, and this avoid processing for if this wasn’t intentional.

We both know why planners using transfer patterns can’t use a trip pattern that falls outside of a parent_station.

I’m not sure what this means. I don’t think it really matters in the context since the both unofficial spec and the proposition restrict to inside the parent_station.

@skinkie
Copy link
Contributor

skinkie commented Apr 29, 2020

It’s also about making the spec understandable. Even if this is specified in the documentation changing the stop_id is far from obvious to a newcomer. My point was also that stop_id sometime doesn’t match due to errors, and this avoid processing for if this wasn’t intentional.

A newcomer shouldn't have to worry about implementation details of dinosaurs. Even @barbeau is adding the restriction "platform changes must fall within the same parent_station" as something that is completely understandable, which is not the case. For a newcomer it should be as easy as "you can replace a stop within a trip by changing its stop_id". This proposal adds complexity because it forces the consumer and producer to check both changes in stop_id and changes in platform_id, where the latter actually references to an existing stop_id which then falls within the same parent_station but has a different platform code. "Just replace the stop_id" makes a lot more sense. And if there are systems that can't handle this... too bad for them, it's 2020, update your code.

We both know why planners using transfer patterns can’t use a trip pattern that falls outside of a parent_station.

I’m not sure what this means. I don’t think it really matters in the context since the both unofficial spec and the proposition restrict to inside the parent_station.

Please educate yourself why this proposal and the unofficial spec enforce this limitation. Otherwise ask @barbeau to add it to the documentation. We could again start a discussion in the same terms as the Travel Restrictions where it was kind of clear that the producer should be able to describe something simple in simple terms, and the consumer should do the hard work.

@tsherlockcraig
Copy link

Please educate yourself

Hi @skinkie -- I don't know you and I suspect you're a nice fellow in many contexts. However, in this community, to be frank, you are often coming across as insensitive and unhelpful to me, and I suspect to others. I need to take this moment to call you out and ask for you to change your behavior, as a fellow community member that wants to work together on the best solutions.

This is not a helpful response you've given to @gcamp . If you're here to shut ideas down, then you need to be here to communicate why. "Please educate yourself" is a rude and antisocial reply. If there is education needed, and you are the one saying no, it is your job to do the education--and it's not education it is advocacy for your own point of view. Others have their own and they are just as valid as yours.

So take a step back, apologize, provide an a real answer to Guillaume's question, and then take another step back and think about how to implement this advice in the future. We are all hurting and we are all trying to save the world. Please grant others some compassion--it is absolutely critical to community in this time.

Thanks for your consideration and efforts.

@skinkie
Copy link
Contributor

skinkie commented Apr 29, 2020

image

@thomastrillium if @gcamp is making an argument in favor for a change that @barbeau is proposing. But does not know why @barbeau is using the wording as he does. The kind reply is "please educate yourself" not: "you are stupid for not knowing this". In a reply #219 (comment) I have exactly laid out what the problem is for the current providers, which he does not quote in his reply. So did you miss it as well?

We are here in a discussion forum where everyone is invited to participate. Sadly I am under the impression that some of the ideas proposed here are not proposed to make this standard any better, or more useful, but rather introduce complexity to justify problems that some paying MobilityData members have.

@Bertware
Copy link

It’s also about making the spec understandable. Even if this is specified in the documentation changing the stop_id is far from obvious to a newcomer. My point was also that stop_id sometime doesn’t match due to errors, and this avoid processing for if this wasn’t intentional.

@gcamp agreed that the spec is a little unclear if you don't know of this feature, I always thought stop_id had to match the original one. This is probably due to the wording. From the spec:

Must be the same as in stops.txt in the corresponding GTFS feed. Either stop_sequence or stop_id must be provided within a StopTimeUpdate - both fields cannot be empty.

This suggests that stop_id and stop_sequence serve the same purpose of identifying the stop in the journey. However, as I understood just now, we could simply use sequence_id as the identifier (as Trafiklab is already doing today) and change stop_id.

A newcomer shouldn't have to worry about implementation details of dinosaurs. Even barbeau is adding the restriction "platform changes must fall within the same parent_station" as something that is completely understandable, which is not the case. For a newcomer it should be as easy as "you can replace a stop within a trip by changing its stop_id". This proposal adds complexity because it forces the consumer and producer to check both changes in stop_id and changes in platform_id, where the latter actually references to an existing stop_id which then falls within the same parent_station but has a different platform code. "Just replace the stop_id" makes a lot more sense.

Agreeing on this one as well. I do not see the benefit of having a separate field, since, in this proposal, stop_id would become static and always match the static feed. In that case it feels like it's a more limited alternative to stop_sequence, as it can't identify a stop on a trip in case the same stop is visited twice.

When looking at both options, they would cause the following situation on client side:

  • using stop_id: Simply look if it has changed compared to the static feed.
  • using platform_id: Simply look if platform_id has changed compared to the static feed. Don't ever look at stop_id.

As a producer, I'd ask why the stop_id is still there in case plaform_id is used. It doesn't seem to serve any purpose in this case, except for those who want to save a tiny bit of work client side as stop_sequence doesn't need to be looked up in order to get the original stop_id. It could also serve as a way to identify the stop on a trip, but stop_sequence is better at that anyway.

Regarding the original arguments:

  1. Therefore, the field is narrowly named platform_id instead of stop_id to make the use case very clear, even if the spec documentation isn't read.

In my opinion this is a matter of clearly declaring this in the documentation.

even if the spec documentation isn't read.

The spec needs to be read. I'd argue that there are more fields that aren't 100% clear if you don't read the spec.

  1. It's not clear whether the change from the static GTFS stop_id is intentional or an error.

If stop_id is defined as able to change, it's intentional. If stop_id can include errors, platform_id can as well. In both cases the client expects them to be correct to the truth.

At this point I'd rather improve the documentation for stop_id than to introduce a new field.

@skinkie
Copy link
Contributor

skinkie commented Apr 30, 2020

As a producer, I'd ask why the stop_id is still there in case plaform_id is used. It doesn't seem to serve any purpose in this case, except for those who want to save a tiny bit of work client side as stop_sequence doesn't need to be looked up in order to get the original stop_id. It could also serve as a way to identify the stop on a trip, but stop_sequence is better at that anyway.

I initially thought this trick would work (6 years ago) and more recently made the same mistake. But sadly there is no "good" way to overcome to go back from stop_sequence to a stop_id. The assumption that a stop_id is present only once in a trip does not hold. GTFS supports this, Google human feed validation even marks it as an issue if the headsign does not change at this point. This suggest that stop_sequence is the way to go. It could be argued that it is an efficient way of doing this (if the producer would guard gapless stop sequences and won't introduce logic bombs that would fill a preallocated array).

But imagine that you want to change your add a stop to your trip in the realtime feed, this is outside of the scope of this discussion, because the intercity train now also calls at a local station. The only way to resolve this in a consumer system would be to trust the order of StopTimeUpdates in the feed and that the position of the newly introduced stop can be established at all. This is also not enforced in the standard.

@barbeau
Copy link
Collaborator Author

barbeau commented Apr 30, 2020

This proposal adds complexity because it forces the consumer and producer to check both changes in stop_id and changes in platform_id, where the latter actually references to an existing stop_id which then falls within the same parent_station but has a different platform code.

To clarify, part of this proposal is locking stop_id so it can't be changed in real-time - stop_id/stop_sequence pairing must match static GTFS. So consumers only need to check platform_id. Any mismatch of stop_id/stop_sequence gets thrown out as an error.

Feed quality is an issue industry-wide, and generally speaking IMHO having overloaded fields and implicit data changes that can't easily be differentiated from errors is part of this problem. Hence the proposal here to explicitly define a new field platform_id to handle dynamic changes, and restricting stop_id and stop_sequence to act only as identifiers of stops, not containers for new values.

@skinkie
Copy link
Contributor

skinkie commented Apr 30, 2020

To clarify, part of this proposal is locking stop_id so it can't be changed in real-time - stop_id/stop_sequence pairing must match static GTFS.

I am against locking to the scheduled stop_id, because this is a very easy way to update stop_id within the current GTFS-RT structure, in realtime. Supported by multiple clients including OTP and RRRR.

@Bertware
Copy link

Bertware commented Apr 30, 2020

Feed quality is an issue industry-wide, and generally speaking IMHO having overloaded fields and implicit data changes that can't easily be differentiated from errors is part of this problem. Hence the proposal here to explicitly define a new field platform_id to handle dynamic changes, and restricting stop_id and stop_sequence to act only as identifiers of stops, not containers for new values.

I still don't see how it would be easier to find errors in the proposed platform_id field compared to the stop_id field. stop_id is only conditionally required, so you could even say that you only need to include a stop_id in case of a changed stop when using stop_sequence to identify the stop in the trip. This is already possible today with the current spec (which would only need some minor adjustments to clarify that stop_id in fact can point to a different platform).

As you're talking about simplifying things to prevent errors, I'd say the stop_sequence documentation is prone to cause issues as "stop_sequence is required for trips that visit the same stop_id more than once (e.g., a loop) to disambiguate which stop the prediction is for." might cause issues with companies thinking they'll never face loops until an agency which uses their software starts using loops. Simply requiring the stop_sequence and making stop_id optional (to handle dynamic changes) would resolve this. While this is a different issue I feel it's relevant to keep in mind, as using stop_sequence as the identifier in all cases would simplify this issue.

I might not be aware of some issues/downsides of stop_sequence, feel free to correct me in case this doesn't work for all operators/cases.

@barbeau
Copy link
Collaborator Author

barbeau commented Apr 30, 2020

@Bertware I believe the original reason that stop_id was allowed as a stand-alone stop identifier without stop_sequence in a StopTimeUpdate was that it simplifies producer implementations - the AVL system doesn't need to know as much about the static GTFS. I know of at least one major AVL provider in North America who didn't include stop_sequence in their initial TripUpdate implementation due to this reason (although they have since included it in later releases). Producers would need to chime in to identify if this is still an issue today.

@skinkie
Copy link
Contributor

skinkie commented Apr 30, 2020

@barbeau I agree. Having the stop sequence in an AVL feed is not common. Therefore most of our code loads the static data to obtain it.

@stevenmwhite
Copy link
Contributor

stevenmwhite commented Apr 30, 2020 via email

@barbeau
Copy link
Collaborator Author

barbeau commented Apr 30, 2020

@stevenmwhite I actually wasn't referring to Syncromatics, so make that "at least two" 😉

@paulswartz
Copy link
Contributor

@barbeau

To clarify, part of this proposal is locking stop_id so it can't be changed in real-time - stop_id/stop_sequence pairing must match static GTFS. So consumers only need to check platform_id. Any mismatch of stop_id/stop_sequence gets thrown out as an error.

This make it harder for producers to migrate, as we'll break functionality if any of our consumers are still using the old specification. I'd prefer to have both supported, so we can continue to provide the old stop_id change for a while along with the new platform_id as consumers update to the new specification.

@barbeau
Copy link
Collaborator Author

barbeau commented Apr 30, 2020

@paulswartz If this proposal is adopted we'll work with existing consumers to have a deprecation period of their existing behavior to allow current implementers of the unofficial method to switch over. The existing spec can be interpreted either way so I see this as a clarification of behavior.

@jxeeno
Copy link
Contributor

jxeeno commented May 3, 2020

Echoing some of the thoughts here. I too, would like to see a more explicit way of identifying when platform / track changes are provided. As a consumer, it's not always clear to us whether it's an intended platform change or some other reason e.g. GTFS-R being out of sync with GTFS (static).

But for backwards compatibility reasons, I don't think platform_id is the way to go necessarily.
Since many consumers already handle the platform change with stop_id change, this will break implementations on both consumer and producer sides. I'm not a producer, but I suspect there'll be hold out in implementing this change simply because some agency's internal consumers would also need to be updated. And not everyone builds things in-house :)

I'd prefer seeing the inverse -- a new field for the schedule_stop_id and make both stop_id and schedule_stop_id mandatory when there is a platform change. That way, we aren't breaking existing implementations whilst still being explicit about both the platform change and the stop time it affects.

@skinkie
Copy link
Contributor

skinkie commented May 3, 2020

I'd prefer seeing the inverse -- a new field for the schedule_stop_id and make both stop_id and schedule_stop_id mandatory when there is a platform change.

The problem with the scheduled_stop_id is that it can occur more than once within a trip. Hence is it not an unique property to identify a StopTimeUpdate, but rather an attribute that is likely to be resolved by a consumer when it is not provided.

@jxeeno
Copy link
Contributor

jxeeno commented May 3, 2020

The problem with the scheduled_stop_id is that it can occur more than once within a trip. Hence is it not an unique property to identify a StopTimeUpdate, but rather an attribute that is likely to be resolved by a consumer when it is not provided.

Yeah, agree. The way I see it is the problem exists either way with platform_id, schedule_stop_id or the current implicit platform change using stop_id. But that should already be resolved by stop_sequence being a required field in the spec when there's a multi visit.

stop_sequence is required for trips that visit the same stop_id more than once (e.g., a loop) to disambiguate which stop the prediction is for.

Both consumers and providers should already be handling loops / multi visits by using stop_sequence as the unique identifier when sending/applying existing well-defined attributes like delays or schedule relationships. So when a theoretical schedule_stop_id is supplied, a consumer would basically interpret it as a flag for a platform change rather than using it as the identifier for the scheduled stop.

@skinkie
Copy link
Contributor

skinkie commented May 3, 2020

So when a theoretical schedule_stop_id is supplied, a consumer would basically interpret it as a flag for a platform change rather than using it as the identifier for the scheduled stop.

This part is something I don't get. Why would a consumer need a "flag" to know there is a change? The consumer is likely to have the schedule loaded. We currently don't have such flag because we assume that a schedule is available at the consumer.

@tleboulenge
Copy link

+1
IMO the main benefit of this change is spec clarity, as expressed in (3) of the original message. It looks like we more or less all agree the current meaning of stop_id here is very ambiguous and confusing, and most of us certainly understood it wrongly at some point. Therefore it seems a good idea to suggest a change to clarify this, and the suggested change does just that.

There is no hidden agenda behind this change, and it doesn't enable or modify a feature that didn't exist before.

It looks to me that a field that can be at times a selector and at times a modifier (with no way to distinguish between those cases except by looking up both values in the most current GTFS) is a major problem.
The solution to that problem is to have fields that are only selectors (in the proposed change, that would be stop_sequence and stop_id) and fields that are only modifiers (platform_id).

This would result in the message being more explicit, clearly express the intent, easier to validate and therefore would lead to better feature adoption and less broken data.

@skinkie Do you disagree this is a problem to start with, or do you disagree with the suggested solution to that problem?

@skinkie
Copy link
Contributor

skinkie commented May 4, 2020

@tleboulenge given the GTFS datamodel, there is no difference between a station/stop and a platform. Therefore modelling a field that in GTFS-RT that suggests that only mutations within the same station are allowed in this field, while effectively a stop is mutated (not a platform) does not make sense to me. Especially since the mutation of a stop (any) should be allowed anyway. Some current consumers that are able to have mutations do not allow mutations beyond parent station mutations (ex. Google) have a technical limitation for this others (ex. OTP, RRRR) do not. A client must have a GTFS loaded (otherwise something trivial as stop labels cannot be shown) therefore a client is always be able to compare if a stop_id mutation is effectively a platform change or a station change. So the answer is both.

// To assign a stop without providing any real-time arrival or departure predictions, populate this field and set
// StopTimeUpdate.schedule_relationship = NO_DATA.
// If this field is populated, StopTimeUpdate `stop_sequence` must be populated and StopTimeUpdate `stop_id`
// should not be populated. Platform assignments should be reflected in other GTFS-realtime fields as well
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why shouldn't stop_id be populated?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was based on your feedback that we should move towards using stop_sequence as the selector for stops - see #219 (comment).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This language seems to conflict with the language below about using both stop_id and assigned_stop_id below. I think you could drop the part about "and StopTImeUpdate stop_id..." and only keep the part about stop_sequence being required?

Copy link
Collaborator Author

@barbeau barbeau Nov 4, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@paulswartz Ah, sorry, my mistake - thanks for pointing it out. I made the change you asked for in the spec language but missed this comment in the .proto file - I've updated it in 81e8804 and 43d960d to match the spec language.

@gcamp Just a heads up that this changed since you already voted.

@barbeau
Copy link
Collaborator Author

barbeau commented Oct 27, 2020

I'd like to thank everyone for leaving feedback on this proposal. I've updated the proposal in 5f003fa based on this feedback to try and address everyone's concerns.

I'd encourage you to check out the diff above, but here is a high-level summary:

  • Field name change of platform_id -> assigned_stop_id - The feature is no longer constrained to just platforms within stations (see next point).
  • Use more generic language to define when assigned_stop_id can be used (versus requiring changes to be only within a station). This broadens potential uses cases of the field without being as prescriptive. There is intentional use of the word "should" vs. "must" in some cases to allow for deviation from the platform assignments use case.
  • Add that you can assign a stop without providing real-time predictions by using StopTimeUpdate.schedule_relationship = NO_DATA (based on @sunny-lirr question above)
  • Require that StopTimeUpdate.stop_sequence be used as the selector and that StopTimeUpdate.stop_id be empty when using this new field assigned_stop_id (based on @skinkie feedback above in moving towards using stop_sequence as the selector in Proposal: Support stop assignments in GTFS-RT #219 (comment))
  • Don't block use of StopTimeUpdate.stop_id being populated with other values in case others want to have unofficial GTFS-realtime feeds that changes stop_id to represent a different stop (e.g., @skinkie with Bliksem Labs B.V. wants to be able to define detours by populating TripUpdates with the entire stop sequence list, aka "GTFS-realtime full"). Therefore, this proposal doesn't block the current use or potential future adoption of a "GTFS-realtime full" if the community would desire this.

Feedback is welcome!

@paulswartz
Copy link
Contributor

paulswartz commented Oct 28, 2020

* Require that StopTimeUpdate.stop_sequence be used as the selector and that StopTimeUpdate.stop_id be empty when using this new field `assigned_stop_id` (based on @skinkie feedback above in moving towards using `stop_sequence` as the selector in [#219 (comment)](https://github.com/google/transit/pull/219#issuecomment-675767164))

This seems like it breaks backwards compatibility with the existing behavior (changing stop_id to the platform stop ID). Maybe something like "if a stop_id is provided, it must match the assigned_stop_id"?

@barbeau
Copy link
Collaborator Author

barbeau commented Oct 28, 2020

This seems like it breaks backwards compatibility with the existing behavior (changing stop_id to the platform stop ID). Maybe something like "if a stop_id is provided, it must match the assigned_stop_id"?

@paulswartz Yes, that's a good point. What about if we change the language to the following to still express the preference towards leaving stop_id empty for producers that haven't been using the current unofficial legacy method:

If StopTimeProperties.assigned_stop_id is populated, it is preferred to omit stop_id and use only stop_sequence. If StopTimeProperties.assigned_stop_id and stop_id are populated, stop_id must match assigned_stop_id.

Avoid breaking current unofficial use of stop_id for platform assignment
@barbeau
Copy link
Collaborator Author

barbeau commented Oct 28, 2020

Based on @paulswartz 👍 above, I've updated the proposal to reflect the above language for stop_id in ce1d8b5.

@barbeau
Copy link
Collaborator Author

barbeau commented Nov 3, 2020

I'd like to call for a vote on adding this proposal as an experimental field in GTFS-realtime.

tl;dr - this feature allows producers to assign a stop for a given StopTimeUpdate in real-time, with the primary intended use case being platform assignments within a station. However, some flexibility in assignments is allowed for additional uses of real-time assignments as long as new stop does not result in a significantly different trip experience for the end user than the stop_id defined in GTFS stop_times.txt (see the diff in the PR for full description!).

Vote will be closed on Tuesday Nov 10th at 23:59:59 UTC.

@tleboulenge, @lauramatson, @paulswartz, @skinkie, @gcamp - please be sure to vote again, thanks!

@gcamp
Copy link
Contributor

gcamp commented Nov 3, 2020

+1 for Transit

@harringtonp
Copy link

harringtonp commented Nov 3, 2020

Coming to this late, haven't read through all the arguments but have looked at the changes.

I would have thought that the assigned_stop_id would have to be different to the stop_id and wouldn't have seen any reason to change the existing mechanism of supplying either the stop_id or stop_sequence or both in the StopTimeUpdate

Correct me if I'm wrong but the stated reason for the addition seems to be to allow for last minute changes from the usual stop to another close by stop. Presumably both stops are sufficiently close (as cited in the platform change example) that they can be walked in a couple of minutes.

Taking a stop centric application, a user will typically bookmark a stop they frequently use. When looking for next departures all trips that use that actual stop are listed. If a trip that regularly uses that stop has moved to an alternative close by stop the user will undoubtedly want to know about it and it should still show in the listing. By providing both the original and assigned stop id, developers have a possibility of making the user aware of the new location. Without any reference to the original stop id there is no chance of this. This would likely happen if the original stop id was replaced with the assigned stop id.

I realise the original stop id can be derived as usual using the trip id and stop sequence but why would you prevent a producer from placing the stop id in StopTimeUpdate too. I get adding StopTimeProperties but don't get why any changes are needed to the existing StopTimeUpdate fields.

@barbeau
Copy link
Collaborator Author

barbeau commented Nov 3, 2020

Correct me if I'm wrong but the stated reason for the addition seems to be to allow for last minute changes from the usual stop to another close by stop. Presumably both stops are sufficiently close (as cited in the platform change example) that they can be walked in a couple of minutes.

@harringtonp Correct - although the primary use case that this proposal addresses is platform assignments in real-time, which is an expected change that users don't consider to be "unusual".

By providing both the original and assigned stop id, developers have a possibility of making the user aware of the new location. Without any reference to the original stop id there is no chance of this....I realise the original stop id can be derived as usual using the trip id and stop sequence but why would you prevent a producer from placing the stop id in StopTimeUpdate too

One issue with requiring that the RT stop_id always match the static stop_id is that Google currently has an unofficial "extension" to RT that allows producers to indicate platform assignments via the stop_id field - so the stop_id and stop_sequence fields already don't match static GTFS for some producers. The goal of this proposal is to standardize the platform assignments feature in a more predictable way that doesn't break backwards compatibility for early adopters of the custom extension. If we require that RT stop_id always matches static, there isn't a migration path for existing producers of the unofficial extension. I realize that it creates an extra step for consumers to retrieve the original static stop_id using stop_sequence, but it seems a reasonable trade-off given that stop_sequence can already be used by itself (without stop_id) to key a StopTimeUpdate on a stop. Generally speaking, in the future I'd like to move towards using stop_sequence as a required key for StopTimeUpdates because it's unambiguous, versus stop_id which can appear several times in a trip (e.g., in loop/lasso routes).

When looking for next departures all trips that use that actual stop are listed. If a trip that regularly uses that stop has moved to an alternative close by stop the user will undoubtedly want to know about it and it should still show in the listing.

The new language is intentionally loose enough to handle nearby moved stops, although it's really to the producer's discretion at how it's used. The guidance in the proposal language is that "The new assigned_stop_id should not result in a significantly different trip experience for the end user than the stop_id defined in GTFS stop_times.txt. In other words, the end user should not view this new stop_id as an "unusual change" if the new stop was presented within an app without any additional context."

The field is intentionally experimental so it can be revised as producers and consumers learn more as it's implemented.

@paulswartz
Copy link
Contributor

One small comment on the text: +1 from MBTA.

@barbeau barbeau changed the title Proposal: Support platform assignments within station in GTFS-RT Proposal: Support stop assignments in GTFS-RT Nov 4, 2020
@tleboulenge
Copy link

+1 for Google.

I think @harringtonp brings an interesting case there (ability to map original_stop_id to assigned_stop_id for all trips), I'm curious to see if we can bring an elegant solution to that (and other existing constraints).

@john-burge-sys
Copy link

+1 for Trapeze Group

@barbeau
Copy link
Collaborator Author

barbeau commented Nov 12, 2020

The vote is closed, and here are the results:

So with 4 "yes" votes this proposal passes as an experimental feature! 🎉 Thanks to everyone who participated in the discussion.

@barbeau barbeau merged commit 480ad2e into google:master Nov 12, 2020
@barbeau barbeau deleted the platform-changes branch November 12, 2020 16:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
GTFS Realtime Issues and Pull Requests that focus on GTFS Realtime
Projects
None yet
Development

Successfully merging this pull request may close these issues.