# Experimental support of public transport from GTFS

## Introduction to the experimental public transport feature

At the moment our app does not have full support for public transport. What we have now:

- Scarce transit data collected from OSM which includes subway, light rail, monorail and train routes and stops. Let's call it the [OSM transit](SUBWAY_GENERATION.md) from now on.
- The "Subway layer" for visual representation of the OSM transit.
- "Subway navigation" - OSM transit routing.

:bus: But you can turn on the experimental feature of [GTFS](https://developers.google.com/transit/gtfs/reference) public transport and use it inside the Organic Maps app. It includes all [transit types definded by GTFS specification:](https://developers.google.com/transit/gtfs/reference/extended-route-types) bus, train, ferry, aerial lifts of different kinds, trolleybus and much more. Let's call this version of transit data **GTFS transit** from now on.

To mix in the experimental GTFS transit into the OSM transit data you should follow these steps:

1. Run the pipeline for downloading and preparing GTFS data about public transport.
2. Switch to the new version of the transit routing section in maps: build maps with the GTFS transit section with the help of special options for generator_tool.

After completing these steps you will have maps with:

:star: Proper public transport navigation. You'll have the opportunity to build public transport routes with transfers from one type of public transport to another (e.g. bus -> train, monorail -> subway, etc). The route is built according to the transit schedules, days off and exceptions in timetables.

:star: "Subway layer" with old OSM transit data but in new visual representation. It differs from the current layer in handling parallel segments of different routes with the same color. In current version we draw separate polyline for each route. It looks a little bit messy, and the new version fixes this: we collapse single-colored parallel routes into one line.

Most of the data collisions between OSM and GTFS sources are excluded, because we filter all subway data from GTFS on purpose. There still could be collisions in light rail, monorail and train data, but it is not a problem: on the "Subway layer" we show data only from OSM. In routing we choose optimal route from GTFS and OSM.

**Why is this feature experimental?** The main reason is that it is not properly tested. Also it lacks new user interfaces for filtering public transport by type, setting departure time and routing "follow mode".

## Instructions for turning on full public transport support

1. Run the python script for collecting GTFS feeds from two GTFS aggregators: [Transitland](https://www.transit.land/) and [OpenMobilityData.](http://transitfeeds.com/feeds) You can find the script in omim/tools/python/transit/gtfs/. It is called download_gtfs.py. It crawls all the feeds from these aggregators, loads feed zips and extracts as subdirectories to the specified directory.

Example:

```
python3 download_gtfs.py --path=dir_for_storing_feeds --mode=fullrun --source=all --transitland_api_key=YOUR_KEY_FOR_TRANSITLAND_API
```

In this example all accessible feeds from Transitland and OpenMobilityData will be downloaded to the `dir_for_storing_feeds` directory. But if you don't want to create key for Transitland API you can run this tool for crawling OpenMobilityData only:

```
python3 download_gtfs.py --path=dir_for_storing_feeds --mode=fullrun --source=mobilitydb
```

After completing this step you will have directory containing subdirectories with GTFS feeds.

2. Build and run the C++ tool for filtering, combining and transforming GTFS feeds (downloaded on the previous step) to the intermediate json files. Later they will be passed to the generator_tool for creating transit section in new format. You can find the tool in `omim/transit/world_feed/gtfs_converter.` The tool is` gtfs_converter.`

It can be run in two modes: for handling GTFS-only or for merging data from GTFS and OSM.

Example of running `gtfs_converter` for merging GTFS and OSM data:

```
./gtfs_converter --path_mapping=mapping.txt --path_mapping_edges=mapping_edges.txt --path_gtfs_feeds=dir_for_storing_feeds --path_subway_json=subway_latest.json --path_json=result_json_dir --path_resources=omim/data
```

Example of running `gtfs_converter` for saving only GTFS data (without OSM):

```
./gtfs_converter --path_mapping=mapping.txt --path_mapping_edges=mapping_edges.txt --path_gtfs_feeds=dir_for_storing_feeds --path_json=result_json_dir --path_resources=omim/data
```

:exclamation: GTFS data often changes: some routes are cancelled, some stops are built, timetables constantly change. **If you're planning to build maps periodically, more than once, then you must take care of the safety of files with transit entities ids which are generated by `gtfs_converter.`** The goal is to make transit entities consistent between re-runs of the tool so that routing between old regions and the new ones doesn't fail. It is better to backup files specified as `path_mapping` and `path_mapping_edges`. When you run `gtfs_converter` the first time these files are created. Subsequent launches update existing files.

After completing this step you will have directory with line-by-line jsons in the directory specified by `path_json` option of `gtfs_converter.`

3. In map_generator.ini uncomment `SUBWAY_URL` parameter and set `TRANSIT_URL` parameter to the directory created on the previous step. Example:

```
TRANSIT_URL: file:///home/result_json_dir
```

Run generator tool [as usual](../tools/python/maps_generator) with this ini config. After it is done you'll have mwms with transit section in experimental GTFS format.

:checkered_flag: Use the resulting mwms in your app. Enjoy the experimental public transport in Organic Maps!

## If you have questions

Feel free to ask [mesozoic-drones](https://github.com/mesozoic-drones), you can also do it by mail: mesozoic.drones@gmail.com
