Giter Site home page Giter Site logo

neroden / timetable_kit Goto Github PK

View Code? Open in Web Editor NEW
34.0 7.0 2.0 25.07 MB

A Python toolkit for generating human-readable timetables from GTFS data; uses PANDAS and gtfs_kit

License: GNU Affero General Public License v3.0

Python 89.03% CSS 6.53% HTML 3.82% Shell 0.63%
gtfs html-timetables public-transport public-transportation timetable trains transit transportation trip-planning metro pandas python static-gtfs transit-data

timetable_kit's Introduction

Timetable Kit

Timetable Kit (timetable_kit) is a Python toolkit for generating human-readable timetables from General Transit Feed Specification (GTFS) <https://en.wikipedia.org/wiki/GTFS> data.

The user provides a "prototype" timetable in CSV form (with stations/stops along the left column and train numbers/trip numbers along the top row), along with a TOML file specifying options. Then timetable_kit fills in the times and other info (from GTFS) and produces either HTML & CSS, PDF, or a plaintext CSV file.

Development status

Timetable_kit remains under active development. It is quite usable to create Amtrak timetables and VIA Rail Canada timetables.

It has not yet been generalized to create timetables in general.

Interfaces are moderately stable. New options continue to be added in spec files. Command line options remain in a state of flux. The interface will change as needs are discovered while creating particular timetables.

Directory Structure

In keeping with the universal, if bizarre, Python package source directory structure, the entire package is in a subdirectory called timetable_kit.

The only exceptions are HOWTO, certain build files, this file, and LICENSE.

In particular, data resources and documentation are largely inside the package directory at this time. This may change.

Dependencies

Timetable Kit requires Python 3.11, because it uses "Self." Even if you removed those, it requires Python 3.10, because it uses the match/case statement, and it uses it very, very intensively.

It relies on GTFS Kit <https://github.com/mrcagney/gtfs_kit> to parse GTFS.

Like GTFS Kit, it uses PANDAS <https://pandas.pydata.org> to do the heavy lifting. It was most recently tested with PANDAS 2.1.4.

Timetable Kit also requires the jinja2 package. Jinja2 templates are used extensively.

It uses Weasyprint to convert HTML timetables to PDF timetables.

It uses tomlkit to read & write the TOML files.

It uses xdg-base-dirs to find out where to store its data.

One of the tools uses the LXML module to parse Amtrak's station web pages.

It's packaged as a package with Poetry, so presumably requires Poetry to install.

Further Documentation

Look in the HOWTO file for information on setting this up as an editable module. Look in the timetable_kit folder for the README.rst there for further info on using the program.

Authors

Copyright 2021, 2022, 2023 Nathanael Nerode.

SpartanTT Copyright 2023 Matt Bailey, Mirko Velimirovic, Nathanael Nerode.

Some fonts, icons, and logos are from other sources and have their own authors, copyrights, and licenses, noted in their directories or files.

Licenses

The timetable_kit software is licensed under GNU Affero GPL v.3 or later. A copy of this is in the LICENSE file.

Produced timetables might contain some copyrightable material from timetable_kit.

Any copyrighted material from timetable_kit which appears in generated timetables and stylesheets is addtionally licensed under the Creative Commons Attribution 4.0 International License. To view a copy of this license, visit http://creativecommons.org/licenses/by/4.0/ or send a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.

The font SpartanTT is licensed under the Open Font License 1.1. See fonts/OFL.txt for more information. https://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL

Some fonts and icons are from other sources and have their own copyrights and licenses. They are all free, libre, and open-source. See their subdirectories for more information.

Connecting service logos in the timetable_kit/connecting_services/logos directory may be subject to other copyrights and some might not be free, libre, or open-source. They are mostly trademarks, used strictly to refer to the appropriate transit service or agency, which is legal to do without asking permission under trademark law. They can be disabled (replaced with alternate text references) by removing the reference to the logo file in the connecting_services/connecting_services.csv file.

Examples

This are some (probably out of date) timetables made using timetable_kit.

image

image

image

image

image

image

image

image

timetable_kit's People

Contributors

astrofloof avatar juckins avatar neroden avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

timetable_kit's Issues

Output file naming conventions

consider naming output files (html or pdf) to match specification files - cz.tt-spec would produce cz.html or cz.pdf (rather than tt_cz.html)

Tracking issue for shorthand tt-spec bug

The shorthand handling code generates a dataframe full of NaN which breaks timetable generation shortly after (strings are expected). Fixed by #14 where a simple .fillna("") is used to replace NaN with empty space as intended.

potentially wrong handling of GTFS Time values

GTFS Time is not defined relative to midnight, but relative to noon - 12h. While that makes "writing" GTFS feeds easier, it makes processing a lot harder.

Expected functionality

As explained in my note about GTFS Time values, with the Europe/Berlin time zone (+1h standard time to +2 DST shift occurs at 2021-03-28T02:00+01:00), I expect

  • the departure_time of 00:30 of a trip running on 2021-03-28 to happen at 1616884200/2021-03-28T00:30+02:00, not at 1616887800/2021-03-28T00:30+01:00;
  • the departure_time of 06:30 of a trip running on 2021-03-28 to happen at 1616905800/2021-03-28T06:30+02:00, not at 1616909400/2021-03-28T06:30+01:00.

Describe the bug

I'm not familiar with this code base, but it seems that timetable_kit is affected by this problem on those days that the DST <-> standard time switch occurs on. I assume that wrong departure times will be generated.

I tried to find some places in the code base:

  • stop_tz = stop_df.iloc[0].stop_timezone
    zonediff = text_presentation.get_zonediff(
    stop_tz, agency_tz, reference_date
    )
    # Get the day change for the reference stop (format is explained in text_presentation)
    departure = text_presentation.explode_timestr(
    timepoint.departure_time, zonediff
    )
    offset = departure.day
    # Finally, get the calendar (must be unique)
    calendar = today_feed.calendar[
    today_feed.calendar.service_id == my_trip.service_id
    ]
    # And fill in the actual string
    daystring = text_presentation.day_string(
    calendar, offset=offset
    )
  • def explode_timestr(timestr: str, zonediff: int = 0) -> TimeTuple:
    """
    Given a GTFS timestr, return a TimeTuple.
    TimeTuple is a namedtuple giving 'day', 'pm', 'hour' (12 hour), 'hour24' ,'min', 'sec'.
    zonediff is the number of hours to adjust to convert to local time before exploding.
    """
    try:
    longhours, mins, secs = [int(x) for x in timestr.split(":")]
    longhours += zonediff # this is the timezone adjustment
    except:
    # Winnipeg-Churchill timetable has NaNs -- don't let it get here!
    raise GTFSError("Timestr didn't parse right", timestr)
    # Return all-zeroes to identify where it happened
    # return TimeTuple(day=0,pm=0,hour=0,hour24=0,min=0,sec=0)
    # Note: the following does the right thing for negative hours
    # (which can be created by the timezone adjustment)
    # It will give -1 days and positive hours24.
    [days, hours24] = divmod(longhours, 24)
    [pm, hours] = divmod(hours24, 12)
    my_time = TimeTuple(day=days, pm=pm, hour=hours, hour24=hours24, min=mins, sec=secs)
    # could do as dict, but seems cleaner this way
    return my_time

related: https://gist.github.com/derhuerst/574edc94981a21ef0ce90713f1cff7f6
related: google/transit#15

Tracking bug for "VIA style" timetable layouts

@AstroFloof , we can discuss this here.

I've been doing a large code refactor. I have 24-hour times up and working, and I should have alternating light grey and white backgrounds working soon. Changing the font is straightforward. Adding English and French commentary text will be straightforward enough. For both of these it will be more obvious how to do it once I switch the config files from JSON to TOML, which I'm planning to do. If other things are considered necessary for this project, let me know...

allow full route/train names

in tt-spec file, allow full name of route/train name for output - cz -> 'California Zephyr'; cono -> 'City of New Orleans'; empire -> 'Empire Service'

('No trip_id for ', '534')

Hello! I was playing around with timetable kit today, and when I was trying to generate some timetables, I ran into this error. For some reason, only train 534 will not generate the timetable. Can you help me resolve this?

Below is the command I used and the output

timetable.py --spec capitol-corridor-weekday-eb.csv capitol-corridor-weekday-eb.json -o output -a Extreme

Output

Using input_dir .
Using GTFS file C:\Users\Extreme\AppData\Roaming\Python\Python310\site-packages\timetable_kit\amtrak\gtfs
Feed loaded
Feed initialized
Feed patched, hopefully
Producing timetable for capitol-corridor-weekday-eb.csv
ttspec_csv_path capitol-corridor-weekday-eb.csv / ttspec_json_path capitol-corridor-weekday-eb.json
tt-spec JSON file loaded
Fonts and icons copied to output
Working with reference date 20220610.
tt-spec capitol-corridor-weekday-eb loaded and augmented
Feed filtered by reference date.
Feed filtered by trip_short_name.
Finding duplicate tsns, if any:
Calendar:
     service_id  monday  tuesday  wednesday  thursday  friday  saturday  sunday start_date  end_date
536     2846775       1        1          1         1       1         0       0   20220531  20220701
542     2846741       1        1          1         1       1         0       0   20220531  20220701
552     2846783       1        1          1         1       1         0       0   20220531  20220701
560     2846746       1        1          1         1       1         0       0   20220531  20220701
567     2846753       1        1          1         1       1         0       0   20220531  20220701
571     2846837       1        1          1         1       1         0       0   20220531  20220701
574     2846791       1        1          1         1       1         0       0   20220531  20220701
580     2846799       1        1          1         1       1         0       0   20220531  20220701
590     2846765       1        1          1         1       1         0       0   20220531  20220701
596     2846807       1        1          1         1       1         0       0   20220531  20220701
737     2849830       1        1          1         1       1         1       1   20220520  20230708
1797    2848293       1        1          1         1       1         0       0   20220531  20220701
1800    2848325       1        1          1         1       1         0       0   20220531  20220701
1822    2848329       1        1          1         1       1         0       0   20220531  20220701
1825    2848301       1        1          1         1       1         0       0   20220531  20220701
Believed valid from 20220531 to 20220701
[['column-options'], [], [], ['ardp'], [], [], [], [], [], [], [], [], [], [], []]
Traceback (most recent call last):
  File "C:\Users\Extreme\Downloads\timetable_kit-main_2\timetable_kit-main\timetable_kit\timetable.py", line 592, in trip_from_train_spec_local
    my_trip_id = train_spec_to_trip_id[train_spec]
KeyError: '534'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "C:\Users\Extreme\Downloads\timetable_kit-main_2\timetable_kit-main\timetable_kit\timetable.py", line 1616, in <module>
    main()
  File "C:\Users\Extreme\Downloads\timetable_kit-main_2\timetable_kit-main\timetable_kit\timetable.py", line 1598, in main
    produce_several_timetables(
  File "C:\Users\Extreme\Downloads\timetable_kit-main_2\timetable_kit-main\timetable_kit\timetable.py", line 1521, in produce_several_timetables
    produce_timetable(
  File "C:\Users\Extreme\Downloads\timetable_kit-main_2\timetable_kit-main\timetable_kit\timetable.py", line 1347, in produce_timetable
    (timetable, styler_table, header_styling_list) = fill_tt_spec(
  File "C:\Users\Extreme\Downloads\timetable_kit-main_2\timetable_kit-main\timetable_kit\timetable.py", line 655, in fill_tt_spec
    stations_max_dwell_map = make_stations_max_dwell_map(
  File "C:\Users\Extreme\Downloads\timetable_kit-main_2\timetable_kit-main\timetable_kit\timetable.py", line 500, in make_stations_max_dwell_map
    trip_id = trip_from_train_spec_fn(train_spec).trip_id
  File "C:\Users\Extreme\Downloads\timetable_kit-main_2\timetable_kit-main\timetable_kit\timetable.py", line 594, in trip_from_train_spec_local
    raise InputError("No trip_id for ", train_spec) from e
timetable_kit.errors.InputError: ('No trip_id for ', '534')

Possible station list edge case

This may be an Amtrak GTFS issue, but I've noticed that in the Crescent timetables posted on narprail.org, the suburban New Jersey stops (Princeton Jct, New Brunswick, Metropark) for train 20 are not listed. I believe those stops were added in Oct 2021. If not a GTFS issue, this could be an edge case where a train pair makes different stops in each direction.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.