google/transit

Travel rules within the same zone

Closed this issue ยท 12 comments

This issue relates to the GTFS-Flex proposal, and is opened following a series of roundtable discussion to resolve the outstanding issues with the proposal. These discussions were hosted by MobilityData and attended by various stakeholders within the GTFS community.

You can find the GTFS-Flex proposal here: https://github.com/MobilityData/gtfs-flex/blob/master/spec/reference.md


This is probably one of the main outstanding issues since it affects how trips are modeled in GTFS-Flex.

Currently a single record is sufficient to describe travel within a single zone, where the example below describes a service called OnDemand that picks up and drops off riders anywhere within ZoneA between 8:00 AM and 8:00 PM.

stop_times.txt

trip_id stop_id stop_sequence start_pickup_dropoff_window end_pickup_dropoff_window pickup_type drop_off_type
OnDemand ZoneA 1 08:00:00 20:00:00 2 2

However, this is not in line with the definition of stop_times.stop_sequence

Order of stops for a particular trip. The values must increase along the trip but do not need to be consecutive.

This also might not be very intuitive/human readable since a trip within the same zone is not described in two records (from - to)
To address this, one option is to require two records in stop_times.txt to describe travel within a single zone, for example:

stop_times.txt

trip_id stop_id stop_sequence start_pickup_dropoff_window end_pickup_dropoff_window pickup_type drop_off_type
OnDemand ZoneA 1 08:00:00 20:00:00 2 2
OnDemand ZoneA 2 08:00:00 20:00:00 2 2

The above example makes the specification more explicit (travel within ZoneA means a trip from ZoneA to ZoneA) which leaves less room for ambiguity.

An example of this ambiguity is that currently, if a service allows riders to travel within the same zone, data producers can either use one record in stop_times.txt, or can use two records (from ZoneA to ZoneA). There is nothing in the spec to prevent one of the options.

Additional complexities may arise when modeling intercity buses, which allow riders to travel from one zone to another, but forbid them from traveling within the same zone.
With the current GTFS-Flex proposal, these services can be described in more than one way:

  1. Using a single record in stop_times.txt alongside multiple trips (see example)
  2. Using two records in stop_times.txt (the first forbids pickups but allows drop offs and the second permits pickups and forbids drop offs)

The proposal to forbid travel within the same record in stop_times.txt, and thus always requiring two records to define travel could eliminate these ambiguities in the specification.

gcamp commented

To me, this is my main problem with the current flex specification. Strong +1

After a lot of thought and discussion, I can say that Trillium agrees with this change! +1

I'm still unclear on exactly why this should change, because the argument above is founded on the current way being uninuitive, and I disagree with that analysis and think the current way is as/more intuitive. I don't think we have a significant survey sample size to say. The current flex spec is not "not in line with the definition of 'stops.stop_times'" so much as that definition would require adjustment for clarity, including if we implement this change. (If we implement this change, either in that definition or in the definition of 'start_pickup_dropoff_window', etc. we'll need to explicitly make a note that the stop_id should be repeated and stop sequence increased if a trip can happen within one zone.)

I'm also a bit confused because unless I'm missing something the conversation in MobilityData/gtfs-flex#65 ended with a different conclusion, that the spec should be clarified in the opposite fashion, leading to this PR:
https://github.com/MobilityData/gtfs-flex/pull/66/files

Finally, I don't see discussion here about the deviated-fixed use case, where travel within a deviation area is allowed, and now we would be requiring that for those services, all of the deviation areas be duplicated, so we have in the stop times file

stop
deviation area
deviation area (repeat)
stop
deviation area
deviation area (repeat)
stop

which seems pretty messy, but I guess no worse than messy.

And as discussed in MobilityData/gtfs-flex#65, we can accomplish the same effect by clarifying the spec and using the pickup_type and drop_off_type.

If we move forward with this change, our repeated deviation areas are still going to have pickup_type and drop_off_type. Will those fields continue to be valuable and will their values still mean what they're supposed to mean if we force publishers to add a repeated area? The repetition of the area is required to indicate drop_off from a pickup in the same area is allowed-->do we also force the publisher to indicate drop_off_type = 1 for the first, and pickup_type = 1 for the second? Do we spell that out in the spec? if we don't, what ambiguities are created?

Ultimately, I don't think I would "-1" this change, but I'm still not convinced it's valuable or necessary.

I think the strongest arguments for this is that it makes the rule explicit, avoids the problem of having two ways describe one kind of service (because you could still describe intrazone travel with two stop_times.txt records while single stop_time intrazone travel also exists), and mirrors the way GTFS-Schedule trip behavior has historically been interpreted.

I don't see repeated deviation areas being a huge issue. As @tsherlockcraig said, just messier, i.e., more rows in stop_times.txt.

@tsherlockcraig:

repeated deviation areas are still going to have pickup_type and drop_off_type. Will those fields continue to be valuable and will their values still mean what they're supposed to mean if we force publishers to add a repeated area? The repetition of the area is required to indicate drop_off from a pickup in the same area is allowed-->do we also force the publisher to indicate drop_off_type = 1 for the first, and pickup_type = 1 for the second? Do we spell that out in the spec? if we don't, what ambiguities are created?

For deviation, yes, you'll need the first instance to be pickup=2 (to account for trips from this zone to subsequent stops/zones or same zone) and drop-off=1 (to avoid trip planners from having two identical records to have to choose from). The second instance would be pickup=1 (avoiding identical records) and drop-off=2/3 (to account for drop-off from a previous stop/zone or same zone). Yes, this all would need to be spelled out in the specโ€“and that's a good thing! Ambiguity on implementation is IMO Flex's biggest issue.

Whatever is eventually decided, we'll need to adjust the spec for clarity.

Whatever is eventually decided, we'll need to adjust the spec for clarity.

100% agreed.

(because you could still describe intrazone travel with two stop_times.txt records while single stop_time intrazone travel also exists)

This can also already be done today with fixed route service. You can repeat a stop, and the google validator (but not the spec itself!) will I believe point out that this doesn't make any sense, because no one would travel to the same stop, when it's just a single fixed route bus stop. But that's exactly the point--it does make sense when there's an area within which a rider might be both picked up and dropped off.

So, we all have the same goal, but clarity can be achieved with language changes either way. I still don't see any clear argument for the change other than increased clarity/intuitiveness, and I personally don't buy those arguments. But again, I'm not going to -1 flex if this gets passed. (Is there anyone who would vote -1 or not adopt if it didn't?)

Having asked for clarification about exactly this topic over at MobilityData/gtfs-flex#65 I'm quite satisfied with the conclusion we came to: by default intra-zone travel is allowed.

This makes the most common case, a taxi-like service, very easy to model and allows the more complicated one, no intra-zone travel, possible.

The downside of this approach are the non-increasing stop sequences. To that I would answer that Flex already majorly deviates from the GTFS Static semantics and therefore the non-increasing stop sequences don't weigh in quite as much.

Therefore I lean towards keep the current definition and merging MobilityData/gtfs-flex#66 to clarify.

Let me be clear however that this opinion is not strongly held and I can live with two stop times per zone.

I think we all agree that clarifying this question one way or another is needed.

Hmm, after having read #335 I kinda see the advantages of not allowing intra-zone travel by default as it makes the most complex case (a limited drop-off window with longer pick up one) more pleasant to model.

Whether this outweighs the benefits of having intra-zone travel by default is hard to say.

NomeQ commented

Based on the Cal-ITP flex feeds, which encompass mostly the simplest cases for small dial-a-ride, this change would be neutral at worst, and positive at best. IMO, for simple services, one additional row in stop_times is a small price to pay for increased clarity on more complex feeds.

One particular example in favor that I've seen multiple times. Dial-a-ride service with two service areas, a regular area (area_A) and an expanded medical area (area_B). Intra-zone travel in area_A is allowed, but trips to area_B must begin in area_A. By the existing spec, there are at least three ways to represent this service. The following is, I believe, allowable, and yet it is not particularly intuitive:

trip_id stop_id stop_sequence pickup_type drop_off_type
1 area_A 1 2 2
1 area_B 2 1 2

One additional note that is perhaps more appropriate for another location (feel free to relocate it) is that this case is common enough where pickups in area_B are only allowable as part of a round-trip. Is this discussed anywhere? Would the above example be sufficient to represent a case where trips for B->A are only allowable if part of a round-trip?

Would the above example be sufficient to represent a case where trips for B->A are only allowable if part of a round-trip?

Yup! Return legs should not be expressed with Flex data because:

  • their existence is predicated on the rider first having taken an A->B trip.
  • they are only valid for the rider who took that trip.
  • they are negotiated between the agency and rider, often outside the published service parameters.

Thanks for a great conversation! This was one of the main outstanding issues in GTFS-Flex and we seem to have come to a consensus. I take it that we are in favour of forbidding travel within the same zone.

I am happy to make the change on the GTFS-Flex repository.
We propose the following change to stop_times.stop_sequence (added wording in bold):

Order of stops for a particular trip. The values must increase along the trip but do not need to be consecutive. Travel within the same area or GeoJSON location requires two records in stop_times.txt with the same stop_id and consecutive values of stop_sequence.
Example: The first location on the trip could have a stop_sequence=1, the second location on the trip could have a stop_sequence=23, the third location could have a stop_sequence=40, and so on.

+1 though I would add the bolded text after the "Example: ..." sentence, since that example directly relates to the sentence before the bolded text.

I am closing this issue with MobilityData/gtfs-flex@6e5268d incorporating the change discussed in this issue.

The changes are now reflected in the MobilityData/gtfs-flex repo.