Skip to content

GTFS Segments: A fast and efficient library to generate bus stop spacings

License

Notifications You must be signed in to change notification settings

UTEL-UIUC/gtfs_segments

Repository files navigation

DOI Tests Documentation Status PyPI version Downloads image

Elsevier Stargazers Issues MIT License

Logo

GTFS Segments

A fast and efficient library to generate bus stop spacings

Table of Contents
  1. About The Project
  2. Getting Started
  3. Usage
  • Roadmap
  • Contributing
  • License
  • Contact
  • Acknowledgments
  • About The Project

    The gtfs-segments is a Python (3.9+) package that represents GTFS data for buses in a concise tabular manner using segments. The distribution of bus stop spacings can be viewed by generating histograms. The stop spacings can be visualized at the network, route, or segment level. The segment data can be exported to well-known formats such as .csv or .geojson for further analysis. Additionally, the package provides commands to download the latest data from @mobility data sources.

    The package condenses the raw GTFS data by considering the services offered only on the busiest day(in the data). More discussion on the interpretation of different weightings for stop spacings, and the process in which the package condenses information can be seen in our paper. The usage of the package is detailed in documentation. The stop spacings dataset containing over 540 transit providers in the US generated using this package can be found on Harvard Dataverse.

    (back to top)

    Getting Started

    Prerequisites

    The major dependencies of this library are the following packages.

    • numpy
    • shapely
    • pandas
    • scipy
    • geopandas
    • matplotlib
    • contextily

    The detailed list of package dependencies can be found in requirements.txt

    Installation

    Option A

    Use pip to install the package.

    pip install gtfs-segments

    ℹ️ Windows users may have to download and install Microsoft Visual C++ distributions. Follow these instructions.

    📓 Google Colab : You can install and use the gtfs-segments via google colab. Here is a tutorial to help you get started. Make a copy and get started with your work!

    Option B

    1. Clone the repo

      git clone https://github.com/UTEL-UIUC/gtfs_segments.git
    2. Install geopandas using the following code. Read more here

      conda create -n geo_env -c conda-forge python=3.11 geopandas
      conda activate geo_env
    3. Install the gtfs_segments package

      cd gtfs_segments
      python setup.py install

    (back to top)

    Usage

    ℹ️ For documentation, please refer to the Documentation

    Import the package using

    import gtfs_segments

    Get GTFS Files

    Fetch all sources

    from gtfs_segments import fetch_gtfs_source
    sources_df = fetch_gtfs_source()
    sources_df.head()
    sources

    Fetch source by name/provider/state

    from gtfs_segments import fetch_gtfs_source
    sources_df = fetch_gtfs_source(place ='Chicago')
    sources_df
    sources

    Automated Download

    from gtfs_segments import download_latest_data
    download_latest_data(sources_df,"output_folder")

    Manual Download

    Download the GTFS .zip files from @transitfeeds or @mobility data.

    Get GTFS Segments

    from gtfs_segments import get_gtfs_segments
    segments_df = get_gtfs_segments("path_to_gtfs_zip_file")
    # [Optional] Run in parallel using multiple CPU cores
    segments_df = get_gtfs_segments("path_to_gtfs_zip_file", parallel = True)

    Alternatively, filter a specific agency by passing agency_id as a string or multiple agencies as list ["SFMTA",]

    segments_df = get_gtfs_segments("path_to_gtfs_zip_file",agency_id = "SFMTA")
    segments_df
    
    data
    Table generated by gtfs-segments using data from San Francisco’s Muni system. Each row contains the following columns:
    1. segment_id: the segment's identifier, produced by gtfs-segments
    2. stop_id1: the identifier of the segment's beginning stop. The identifier is the same one the agency has chosen in the stops.txt file of its GTFS package.
    3. stop_id2: The identifier of the segment's ending stop.
    4. route_id: The same route ID listed in the agency's routes.txt file.
    5. direction_id: The route's direction identifier.
    6. traversals: The number of times the indicated route traverses the segment during the "measurement interval." The "measurement interval" chosen is the busiest day in the GTFS schedule: the day which has the most bus services running.
    7. distance: The length of the bus segment in meters.
    8. geometry: The segment's LINESTRING (a format for encoding geographic paths). All geometries are re-projected onto Mercator (EPSG:4326/WGS84) to maintain consistency.
    9. traversal_time: The time (in seconds) that it takes for the bus to traverse the segment.
    10. speed: The speed of the bus (in kmph) while traversing the segment. Default to np.inf♾ in case traversal_time is zero.

    Each row does not represent one segment. Rather, each row maps to a combination of a segment, a route that includes that segment, and a direction. For instance, a segment included in eight routes will appear as eight rows, which will have the same information except for route_id and traversals (since some routes might traverse the segment more than others). This choice enables filtering by route and preserves how many times each route traverses each segment during the measurement interval. The direction identifier is used for very rare cases (mostly loops) in which a route visits the same two stops, in the same order, but in different directions.

    Visualize Spacings

    Visualize stop spacings at network, route and segments levels along with basemaps and stop locations.

    ℹ️ For more information on visualization refer to the Visualization Tutorial

    ℹ️ Alternatively, use view_spacings_interactive to view the stop spacings interactively.

    from gtfs_segments import view_spacings
    view_spacings(segments_df,route = ['8'],segment = ['6364-3725-1'],basemap=True)
    data

    Heatmap

    View the heatmap of stop spacings ("distance" as metric). Use Diverging colormaps to highlight narrow and wide spacings. Set light_mode = False for Dark mode.

    from gtfs_segments import view_heatmap
    f = view_heatmap(df, cmap='RdBu', light_mode=True)
    data
    view_heatmap(df, cmap="YlOrRd", interactive=True, light_mode=False)
    data

    Plot Distributions

    from gtfs_segments import plot_hist
    plot_hist(segments_df, max_spacing = 1200)
    histogram
    Optionally save figures using
    plot_hist(segments_df,file_path = "spacings_hist.png",save_fig = True)

    Summary Statistics

    Get Network Summary Stats

    from gtfs_segments import summary_stats
    summary_stats(segments_df,max_spacing = 3000,export = True,file_path = "summary.csv")
    histogram

    Get Route Summary Stats

    from gtfs_segments import get_route_stats,get_bus_feed
    feed = get_bus_feed('path_to_gtfs.zip')
    get_route_stats(feed)
    histogram

    Here each row contains the following columns:

    1. route: The route_id for the route of interest
    2. direction: The direction_id of the route
    3. route_length: The total length of the route. Units: Kilometers (Km)
    4. total time: The total scheduled time to travel the whole route. Units: Hours (Hr)
    5. headway: The average headway between consecutive buses for the route. A NaN indicates only 1 trip. Units: Hours (Hr)
    6. peak_buses: The 15-minute interval where the route has the maximum number of buses concurrently running.
    7. average_speed: The average speed of the bus along the route. Units: Kmph
    8. n_bus_avg: The average number of buses concurrently running
    9. bus_spacing: The average spacing (in distance) between consecutive buses. Units: Kilometers (Km)
    10. stop_spacing: The average distance between two consecutive stops. Units: Kilometers (Km)

    Download Segments Data

    Download the data as either .csv or .geojson

    from gtfs_segments import export_segments
    export_segments(segments_df,'filename', output_format ='geojson')
    # Get csv without geometry
    export_segments(segments_df,'filename', output_format ='csv',geometry = False)

    (back to top)

    Roadmap

    • Add interactive visualization with folium
    • Log trips that do not have shapes
    • Visualize catchment areas for stops

    See the open issues for a full list of proposed features (and known issues).

    (back to top)

    License

    Distributed under the MIT License. See LICENSE.txt for more information.

    Citing gtfs-segments

    If you use gtfs-segments in your research please use the following BibTeX entry:

    @article{Devunuri_GTFS_Segments_A_2024,
    author = {Devunuri, Saipraneeth and Lehe, Lewis},
    doi = {10.21105/joss.06306},
    journal = {Journal of Open Source Software},
    month = mar,
    number = {95},
    pages = {6306},
    title = {{GTFS Segments: A Fast and Efficient Library to Generate Bus Stop Spacings}},
    url = {https://joss.theoj.org/papers/10.21105/joss.06306},
    volume = {9},
    year = {2024}
    }

    Alternative: Check the Cite this repository

    Citing stop spacings paper

    If you use stop spacings paper in your research please use the following BibTeX entry:

    @article{Devunuri2024,
      title = {Bus Stop Spacing Statistics: {{Theory}} and Evidence},
      shorttitle = {Bus Stop Spacing Statistics},
      author = {Devunuri, Saipraneeth and Lehe, Lewis J. and Qiam, Shirin and Pandey, Ayush and Monzer, Dana},
      year = {2024},
      month = jan,
      journal = {Journal of Public Transportation},
      volume = {26},
      pages = {100083},
      issn = {1077-291X},
      doi = {10.1016/j.jpubtr.2024.100083},
      url = {https://www.sciencedirect.com/science/article/pii/S1077291X24000031},
      urldate = {2024-03-07},
      keywords = {Bus stop,GTFS,Public Transit,Stop Spacings,Transit Planning}
    }

    (back to top)

    Contributing

    Contributions are what makes the open-source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.

    If you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the tag "enhancement". Don't forget to give the project a star! Thanks again!

    1. Fork the Project
    2. Create your Feature Branch (git checkout -b feature/AmazingFeature)
    3. Commit your Changes (git commit -m 'Add some AmazingFeature')
    4. Push to the Branch (git push origin feature/AmazingFeature)
    5. Open a Pull Request

    For more information refer to CONTRIBUTING.md

    Contact

    Saipraneeth Devunuri - @praneethDevunu1 - [email protected]

    Project Link: https://github.com/UTEL-UIUC/gtfs_segments

    Acknowledgments

    • Parts of the code use the Partridge library
    • Do check out gtfs_functions which was an inspiration for this project
    • Shoutout to Mobility Data for compiling GTFS from around the globe and constantly maintaining them

    (back to top)