grote/osm2gtfs

Support hail_and_ride / GTFS Flex

amenk opened this issue · 16 comments

amenk commented

Are the plans to support GTFS flex and hail_and_ride tagging?

I think it would be a good addition to osm2gtfs 👍

But IMHY we should wait for it is fully integrated into the official GTFS spec.

For the record :

What is meant by hail_and_ride? Fixed itinerary without fixed stop positions or flexible itinerary? I have seen both solutions, rural bus services in Norway are generally fixed itinerary without fixed stop positions, while some minor places have "taxibus" services where you call a number or via app, and your location + destination is added to current itinerary.

amenk commented

It's about Addis Ababa minibus service. The routes are fixed, but they let you hop on and off anywhere on that route.

Does OTP support GTFS flex in any way, because that is what we e generating for..

amenk commented

Does OTP support GTFS flex in any way, because that is what we e generating for..

http://docs.opentripplanner.org/en/latest/Flex/

amenk commented

For minibus in Addis Ababa it would be

https://github.com/MobilityData/gtfs-flex/blob/master/spec/reference.md#request-stops

3 - Must coordinate with driver to arrange continuous stopping behavior.

continuous_pickup=3
continuous_drop_off=3

in stop_times.txt

amenk commented

We might need to fork transitfeed, because it does not support that fields

https://github.com/google/transitfeed/blob/master/transitfeed/stoptime.py#L48

amenk commented

I made some tests with OTP and manually adding to stoptimes.txt

"trip_id","arrival_time","departure_time","stop_id","stop_sequence","stop_headsign","pickup_type","drop_off_type","shape_dist_traveled","timepoint","continuous_pickup","continuous_drop_off"
24,"06:00:00","06:00:00","node/7037142417",1,,,,,,0,0
24,"06:04:54","06:04:54","node/7110438109",2,,,,,,0,0

....

And router-config.jsom

{
  "useFlexService": true,
  "routingDefaults": {
    "flexCallAndRideReluctance": 3,
    "flexMaxCallAndRideSeconds": 7200,
    "flexFlagStopExtraPenalty": 180,
    "flexMinPartialHopLength": 1
  }
}

The flexMinPartialHopLength setting is important.

I get this result:

Selection_261

So it seems to work from a OTP point of view.

We just have to find out how to add those columns in OSM2GTFS

@xamanu Do you see a way without messing with the transitfeed package?

It could be added somehow in a dirty way with some CSV Manipulation, but I think it would be better to

  • either extend transitfeed with those capabilities and propose these changes as PR to the upstream repository
  • or we might want to consider stopping to rely on transitfeed at all anymore (longer discussion, but there might be some good arguments), and this could bring in this way of flexibility.
amenk commented

I am wondering if it would be enough to subclass StopTime from Transitfeed.

transitfeed does not seem to care much about PRs ... so we might as well maintain an own fork for OSM2GTFS before completely reinventing the wheel?

amenk commented

I looks like it's possible to change behaviour of transitfeed with an extension

We could create a class with the following (stub):

from transitfeed.stoptime import StopTime

class FlexStopTime(StopTime):

  _OPTIONAL_FIELD_NAMES = ['stop_headsign', 'pickup_type',
	                   'drop_off_type', 'shape_dist_traveled', 'timepoint',
	                   'continuous_pickup', 'continuous_drop_off']

And call UpdateClass('StopTime', FlexStopTime) on the factory.

Remark:

Simply calling

    feed._gtfs_factory.UpdateClass('StopTime', FlexStopTime)

in osm2gtfs.py does not work (it seems to use a different factory instance later)

@amenk this is cool. Is there a place where to check the current (not working) state?

amenk commented

@xamanu Just pushed it - I made some more progress. It's possible with monkey patching to inject the new Factory of the newly created transitfeedflex module https://github.com/AddisMap/osm2gtfs/compare/develop...AddisMap:develop-flex?expand=1

It looked promissing, the flags are in the CSV and I was able to hard-coded set them. But then I did not succeed in passing the flag around to the proper class, if the route is a hail_and_ride route

Good you got it to work! We really have to rethink how/whether to use transitfeed anymore.

amenk commented
amenk commented

now I got it working :-)

AddisMap@b4bf0b9