← Back to all sparks
G

gtfsio

DEVOPS
Velocity0.0

Read and Write General Transit Feed Specification (GTFS) Files

gtfsio's job is absorbing the ways real transit feeds violate their own specification.

gtfstransit-datar-packagedata-importspecification-compliance
Current state
A low-level R package for reading and writing GTFS transit feeds, deliberately scoped to I/O with the analysis left to packages built on top of it such as gtfstools. Releases are roughly annual. Almost every entry is a fix for a feed that does not match what the specification implies: files without a .zip extension, non-text files inside the archive, subdirectories, blank CSV lines, 64-bit integers in the first row.
Where it's heading
The package has stabilised into a maintenance rhythm around two axes. One is defensive reading — each release absorbs another malformed-feed case and turns a hard failure into a warning plus a sensible default. The other is keeping the bundled specification current, which moved from a get_gtfs_standard() function to a gtfs_reference dataset that is simply refreshed, most recently to the April 2026 revision. The 1.0.0 introduction of custom-classed gtfsio_error conditions was the one structural decision, letting downstream packages catch specific failures rather than parsing message strings.
Prediction
Expect continued annual releases pairing a refreshed gtfs_reference with whatever new feed malformation has been reported; nothing here suggests the package will expand past its I/O remit.

Recent moves

  1. 2mo ago

    Handles non-zip URLs on Windows, subdirectories and blank CSV lines

    Three more malformed-feed cases absorbed: URLs without a .zip suffix now download on Windows, feeds containing subdirectories raise a warning, and blank lines in CSV files are skipped. The bundled gtfs_reference is refreshed to the 2026-04-27 revision, the maintenance step that now accompanies each release.

    View source ↗
  2. 1y ago

    GeoJSON files read as JSON; gtfs_reference dataset replaces get_gtfs_standard()

    Adds GeoJSON support to import_gtfs() and replaces the get_gtfs_standard() function with a gtfs_reference dataset, which turns specification updates into data refreshes rather than code changes. Internal path handling moves to fs.

    View source ↗
  3. 2y ago

    Large round numbers no longer exported in scientific notation

    Stops export_gtfs() writing large round numbers in scientific notation. The notes are candid that the specification permits it, but the output broke workflows in other applications consuming the files — a good illustration of this package optimising for what downstream tools actually accept rather than what the spec allows.

    View source ↗
  4. 3y ago

    Non-text files in a feed no longer break unzipping

    Fixes import_gtfs() appending a .txt extension to non-text files inside a feed, which caused unzip errors; such files are now ignored with an informative warning. Paths and URLs pointing at zip files without the .zip extension are also accepted. Both are the same pattern — tolerate the feed, tell the user.

    View source ↗
  5. 4y ago

    Custom-classed error conditions for downstream catching

    Introduces gtfsio_error(), giving every error from an exported function a class inheriting from both gtfsio_error and a per-function class, so downstream packages can catch specific failures instead of matching message text. Also fixes a bit64 warning by reading the header row as character. The most structural decision in the package's history, and it came with a potentially breaking change to file and field handling.

    View source ↗
  6. 4y ago

    summary method and encoding parameter added

    Adds a summary.gtfs method and an encoding parameter for feeds with strings in a native encoding, plus a fix for table names occasionally carrying their full path. Contributed largely from outside, which is typical of the package's early development.

    View source ↗