Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/derhuerst/generate-gtfs-flex

Given a GTFS Static feed, add GTFS Flex v2 to model on-demand public transport service.
https://github.com/derhuerst/generate-gtfs-flex

gtfs gtfs-flex public-transport transit

Last synced: 5 days ago
JSON representation

Given a GTFS Static feed, add GTFS Flex v2 to model on-demand public transport service.

Awesome Lists containing this project

README

        

# generate-gtfs-flex

Given a [GTFS Static](https://gtfs.org/reference/static) feed, **add [GTFS Flex v2](https://github.com/MobilityData/gtfs-flex/blob/e1832cfea5ddb9df29bd2fc50e80b0a4987695c1/spec/reference.md) to model on-demand public transport service.**

[![ISC-licensed](https://img.shields.io/github/license/derhuerst/generate-gtfs-flex.svg)](license.md)

*Note:* In order to get the behaviour we want (pickup only at stops but flexible drop-off within 300m), **we currently don't follow the spec as intended**; See [#5](https://github.com/derhuerst/generate-gtfs-flex/issues/5) and [#6](https://github.com/derhuerst/generate-gtfs-flex/pull/6) for details.

## Installation

```shell
npm install derhuerst/generate-gtfs-flex
# or
docker pull docker.io/derhuerst/generate-gtfs-flex
```

## Getting started

The scripts in this repo are written to be used with any GTFS feed. But there's also a file [`herrenberg-flex-rules.js`](herrenberg-flex-rules.js), which specifies the on-demand lines in [Herrenberg, Germany](https://en.wikipedia.org/wiki/Herrenberg) (part of [VVS](https://www.vvs.de)).

The following steps will demonstrate how to use the scripts with `herrenberg-flex-rules.js`, in order to patch the [VVS GTFS feed](https://www.openvvs.de/dataset/e66f03e4-79f2-41d0-90f1-166ca609e491) with GTFS-Flex data. You must have [Node.js](https://nodejs.org/) installed (which includes the [`npm` CLI](https://docs.npmjs.com/cli/v7)).

```bash
# set up an empty npm project
mkdir flex
cd flex
npm init --yes

# download and unzip 2022-01-17 VVS GTFS feed
# get the latest feed at https://www.opendata-oepnv.de/ht/de/organisation/verkehrsverbuende/vvs/startseite?tx_vrrkit_view%5Bdataset_name%5D=soll-fahrplandaten-vvs&tx_vrrkit_view%5Bdataset_formats%5D%5B0%5D=ZIP&tx_vrrkit_view%5Baction%5D=details&tx_vrrkit_view%5Bcontroller%5D=View
wget 'https://www.opendata-oepnv.de/dataset/d1768457-c717-45ea-8e26-dd1e759d5ffe/resource/ebc2eaae-9a03-4ace-8df7-28df10a80993/download/google_transit.zip' -O vvs.gtfs.zip
unzip -d vvs-gtfs vvs.gtfs.zip

# install generate-gtfs-flex as a development dependency
npm install --save-dev derhuerst/generate-gtfs-flex

# patch GTFS-Flex data into the VVS GTFS feed
npm exec --offline generate-locations-geojson \
node_modules/generate-gtfs-flex/herrenberg-flex-rules.js \
vvs-gtfs/{routes,trips,stops,stop_times}.txt \
>vvs-gtfs/locations.geojson
npm exec --offline generate-booking-rules-txt \
node_modules/generate-gtfs-flex/herrenberg-flex-rules.js \
vvs-gtfs/routes.txt \
>vvs-gtfs/booking_rules.txt
npm exec --offline patch-trips-txt \
node_modules/generate-gtfs-flex/herrenberg-flex-rules.js \
vvs-gtfs/{routes,trips,stops,stop_times}.txt \
| sponge vvs-gtfs/trips.txt
npm exec --offline patch-routes-txt \
node_modules/generate-gtfs-flex/herrenberg-flex-rules.js \
vvs-gtfs/routes.txt \
| sponge vvs-gtfs/routes.txt
npm exec --offline patch-stop-times-txt \
node_modules/generate-gtfs-flex/herrenberg-flex-rules.js \
vvs-gtfs/{routes,trips,stops,stop_times}.txt \
| sponge vvs-gtfs/stop_times.txt
```

*pro tip:* If you install the package globally (via `npm install derhuerst/generate-gtfs-flex -g`), npm will put the scripts into your [`$PATH`](https://en.wikipedia.org/wiki/PATH_(variable)), so instead of running `./node_modules/.bin/…`, you'll be able to just use them as documented below.

## Usage

```
Usage:
generate-locations-geojson
Examples:
generate-locations-geojson flex-rules.js \
gtfs/{routes,trips,stops,stop_times}.txt >gtfs/locations.geojson
```

```
Usage:
generate-booking-rules-txt
Examples:
generate-booking-rules-txt flex-rules.js gtfs/routes.txt >gtfs/booking_rules.txt
```

```
Usage:
patch-routes-txt
Examples:
patch-routes-txt flex-rules.js gtfs/routes.txt >gtfs/routes.patched.txt
```

```
Usage:
patch-trips-txt
Examples:
patch-trips-txt flex-rules.js \
gtfs/{routes,trips,stops,stop_times}.txt >gtfs/trips.patched.txt
```

```
Usage:
patch-stop-times-txt
Examples:
patch-stop-times-txt flex-rules.js \
gtfs/{routes,trips,stops,stop_times}.txt >gtfs/stop_times.patched.txt
```

*Note:* Currently, `generate-gtfs-flex` inserts all trips & `stop_times` rows affected by any of the rules *twice*: One on-demand trip stopping directly at the stops, one trip stopping at Flex areas.

### with Docker

You can use the [`docker.io/derhuerst/generate-gtfs-flex` Docker image](https://hub.docker.com/r/docker.io/derhuerst/generate-gtfs-flex). It will call the tools documented above on a GTFS feed that you mount into the container:

```shell
docker run -v /path/to/gtfs:/gtfs --rm -it docker.io/derhuerst/generate-gtfs-flex
```

**⚠️ This will overwrite the original `routes.txt`, `trips.txt` & `stop_times.txt` files.**

### with your own GTFS feed & GTFS-Flex rules

You can use the scripts in this repo with *any* GTFS feed. As an example, we're going to patch [`sample-gtfs-feed`](https://github.com/public-transport/sample-gtfs-feed)'s `A` ("Ada Lovelace Bus Line") route to have flexible on-demand drop-offs.

```shell
# as above, initialise an empty npm project & install generate-gtfs-flex
mkdir sample-gtfs-feed-with-flex
cd sample-gtfs-feed-with-flex
npm init --yes
npm install --save-dev sample-gtfs-feed derhuerst/generate-gtfs-flex
```

We're going to write a file `flex-rules.js` that exports a list of GTFS-Flex *rules*. Each of these rules is a function that must, when given a `routes.txt` entry/row, return either `null` to leave it unchanged or return a GTFS-Flex *spec* (check out [the schema](lib/flex-spec-schema.json)) to patch it:

```js
const pickupTypes = require('gtfs-utils/pickup-types')
const dropOffTypes = require('gtfs-utils/drop-off-types')
const bookingTypes = require('gtfs-utils/booking-types')

const adaLovelaceFlexibleDropOff = (route) => {
if (route.route_id !== 'A') return null // leave route unchanged
return {
id: 'A-flexible-drop-off', // ID of the GTFS-Flex spec
radius: .200, // flexible drop-off within 200m of a stop
pickup_type: pickupTypes.MUST_PHONE_AGENCY,
drop_off_type: dropOffTypes.MUST_COORDINATE_WITH_DRIVER,
bookingRule: {
// ID of the GTFS-BookingRules booking_rules.txt entry/row to be generated
booking_rule_id: 'flexible-drop-off',
booking_type: bookingTypes.SAME_DAY,
prior_notice_duration_min: 30,
message: 'Get dropped off right at home! Please call 30min before.',
booking_url: 'https://example.org/flex'
},
}
}

module.exports = [
adaLovelaceFlexibleDropOff,
]
```

We can now patch the GTFS-Flex *rules* into `sample-gtfs-feed`'s GTFS feed:

```shell
# copy the GTFS feed first, so that we don't mutate node_modules
# Note: You can benefit from copy-on-write using `-c` (BSD/macOS) or `--reflink=auto` (GNU/Linux).
cp -r node_modules/sample-gtfs-feed/gtfs gtfs

npm exec --offline generate-locations-geojson \
flex-rules.js gtfs/{routes,trips,stops,stop_times}.txt \
>gtfs/locations.geojson
npm exec --offline generate-booking-rules-txt \
flex-rules.js gtfs/routes.txt \
>gtfs/booking_rules.txt
npm exec --offline patch-routes-txt \
flex-rules.js gtfs/routes.txt \
| sponge gtfs/routes.txt
npm exec --offline patch-trips-txt \
flex-rules.js gtfs/{routes,trips,stops,stop_times}.txt \
| sponge gtfs/trips.txt
npm exec --offline patch-stop-times-txt \
flex-rules.js gtfs/{routes,trips,stops,stop_times}.txt \
| sponge gtfs/stop_times.txt
```

## Contributing

If you have a question or need support using `generate-gtfs-flex`, please double-check your code and setup first. If you think you have found a bug or want to propose a feature, use [the issues page](https://github.com/derhuerst/generate-gtfs-flex/issues).