conveyal / r5

Developed to power Conveyal's web-based interface for scenario planning and land-use/transport accessibility analysis, R5 is our routing engine for multimodal (transit/bike/walk/car) networks with a particular focus on public transit
https://conveyal.com/learn
MIT License
290 stars 74 forks source link

add-trips modification #94

Closed mattwigway closed 7 years ago

mattwigway commented 8 years ago

Here is the modification to add a trip pattern. The geometry is not needed on the r5 side, just the stop positions.

{
  "name": "New Trip Pattern",
  // is this pattern bidirectional
  "bidirectional": true
  "type": "add-trip-pattern",

  // this is the geometry of the trip pattern
  "stops": [
      [
        -94.55696582794188,
        39.07907466816786
      ],
      [
        -94.55677592470957,
        39.08266780313968
      ],
     // this is the ID of an existing stop rather than a newly-created one
      "kcata:45210",
      [
        -94.55906867980957,
        39.085637256644695
      ]
  ],

  // Timetables for the pattern, may be repeated to have e.g. multiple frequency entries
  "timetables": [
    {
      // when the trip or frequency entry starts
      "startTime": 25200,
      // if a frequency entry, when it ends (otherwise should be omitted)
      "endTime": 79200,
      // is this a frequency entry
      "frequency": true,
      // headway
      "headwaySecs": 600,
      // days service is active, starting with Monday
      "days": [
        true,
        true,
        true,
        true,
        true,
        false,
        false
      ],
      // the hop times between the stops
      "hopTimes": [
        96,
        348,
        181
      ],
      // the dwell times at each stop
      "dwellTimes": [
        0,
        0,
        0,
        0
      ]
    },
    // repeat as desired
    {
      "startTime": 25200,
      "endTime": 72000,
      "dwellTime": 0,
      "frequency": true,
      "headwaySecs": 900,
      "days": [
        false,
        false,
        false,
        false,
        false,
        true,
        true
      ],
      "hopTimes": [
        80,
        290,
        150
      ],
      "dwellTimes": [
        0,
        0,
        0,
        0
      ]
    }
  ],
}
abyrd commented 8 years ago

Are we going to support anything other than frequency entries? If so what does a fully-specified timetable look like? The term "timetables" might be a little misleading if these are usually frequency entries.

The objects in the "timetables" array of this modification type are very similar to those in the "entries" array of convertToFrequency. As things evolve, we should probably try to make them as similar as possible to avoid confusion. In fact... couldn't a "convert to frequency" just be an "add trip pattern" with an extra field to say which existing route or trips it's supposed to replace?

As in other modifications, I'm wondering if we need a separate boolean field to indicate that something is a frequency, or the simple presence of a headwaySecs field is enough to signal that.

abyrd commented 8 years ago

If we were to do what I suggested above and merge the frequency conversion and add pattern modifications, then sourceTrip would just be another way to specify timetables/frequencies (copy them from another trip).

mattwigway commented 8 years ago

Well the source trip is the source only for times, not frequencies, as well as the pattern. It's different than an add trip pattern in that the convert to frequency modification specified here affects all of the patterns on a route.

abyrd commented 8 years ago

Yeah even if they could somehow be merged, I'm not sure it's a win for clarity. I was just considering our options.

abyrd commented 8 years ago

The stops array above is of mixed type. Its elements are either arrays of 2 floating point numbers (for stops that are specified only as coordinates) or strings (for stops that are specified by ID). Jackson deserialization will not like this, and even if we can get it to work we probably don't want to. So instead we'll make the stops array an array of objects like so:

"stops": [
      {
        "lat": -94.55696582794188,
        "lon": 39.07907466816786
      },
      {
        "lat": -94.55677592470957,
        "lon": 39.08266780313968
      },
     // This is the ID of an existing stop rather than a newly-created one.
     // Either a stop ID or a coordinate pair must be specified but not both.
      {
        "id": "kcata:45210"
      },
      {
        "lat": -94.55906867980957,
        "lon": 39.085637256644695
      }
  ]

This doesn't allow us to create a new stop and reference it in multiple modifications (e.g. to use the same stop in multiple new patterns) but we don't have a strong need for that yet, so it's not supported.

abyrd commented 8 years ago

For now we are not going to support add-trip-pattern modifications that specify entire timetables. We are only supporting adding frequency based patterns. When mocking up a new transit system, it's very unlikely that we know the entire timetable, and specifying it in so much detail is probably an error in modeling methodology. If you really have such a detailed schedule, you should probably just export a whole new GTFS.

abyrd commented 8 years ago

We're also going to get rid of the separate boolean field that states whether each timetable is a frequency entry. In fact since we're only supporting frequencies (not timetables) we'll rename the top level field from "timetables" to "frequencies" while we're at it. Removing a few other fields that are only useful on the client side, this leaves us with:

{
  "type": "add-trips",
  "comment": "New Trip Pattern",
  // Add two patterns instead of one: one in the given sequence and one in the reverse sequence.
  "bidirectional": true
  "stops": [
      {
        "lat": -94.55696582794188,
        "lon": 39.07907466816786
      },
     // This is the ID of an existing stop rather than a newly-created one.
     // Either a stop ID or a coordinate pair must be specified but not both.
      {
        "id": "kcata:45210"
      },
      {
        "lat": -94.55906867980957,
        "lon": 39.085637256644695
      }
  ],
  // One or more frequency entries for the pattern.
  "frequencies": [
    {
      // when the frequency entry starts, in seconds after GTFS midnight
      "startTime": 25200,
      // when the frequency entry ends, in seconds after GTFS midnight
      "endTime": 79200,
      // headway
      "headwaySecs": 600,
      // Which days the service is active
      // We are intentionally not allowing service start and end dates for simplicity.
      "monday": true,
      "tuesday": true,
      "wednesday": true,
      "thursday": true,
      "friday": true,
      "saturday": true,
      "sunday": true,
      // the hop times between the stops
      "hopTimes": [
        96,
        348,
        181
      ],
      // the dwell times at each stop
      "dwellTimes": [
        0,
        0,
        0,
        0
      ]
    }
    // repeat as desired for more frequency entries
  ]
}
abyrd commented 8 years ago

The expression "trip pattern" may not be familiar to all our users. And since we've dropped the ability to add scheduled trips, maybe we're arguably adding a frequency-based route.