- Description
- Reading and writing GTFS feeds
- How to add library to your project
- Used third-party tools
- Contributing
- Resources
The just_gtfs library implements reading and writing static transit data in GTFS - General Transit Feed Specification.
Its main features:
- Fast reading and writing of GTFS feeds
- Support for extended GTFS route types
- Simple working with GTFS
Date
andTime
formats - Header-only
- Written in C++17
- Tested on GCC and Clang
Library provides main class for working with GTFS feeds: gtfs::Feed
. It also provides classes for each of the 17 GTFS entities: Route
, Stop
, Pathway
, Translation
and others.
GTFS csv files are mapped to the corresponding C++ classes. Every GTFS entity can be accessed through gtfs::Feed
corresponding getters & setters.
📌 All GTFS entities are managed in the same way. So here is the example for working with agencies
.
Method of the Feed
class for reading agency.txt
:
Result read_agencies()
Method for reading reading not only agencies but all GTFS entities. Path to the feed is specified in the Feed
constructor:
Result read_feed()
Method for getting reference to the Agencies
- std::vector
of all Agency
objects of the feed:
const Agencies & get_agencies()
Method for finding agency by its id. Returns std::optional
so you should check if the result is std::nullopt
:
std::optional<Agency> get_agency(const Id & agency_id)
Method for adding agency to the feed:
void add_agency(const Agency & agency)
Method for writing agencies to the agency.txt
file to gtfs_path
.
Result write_agencies(const std::string & gtfs_path)
Method for writing all GTFS entities (not only agencies, but stops, stop times, calendar etc):
Result write_feed(const std::string & gtfs_path)
📌 There are similar methods for all other GTFS entities for getting the list of entities, finding and adding them. For some of them additional methods are provided. For example, you can find all the stop times for current stop by its id:
StopTimes get_stop_times_for_stop(const Id & stop_id)
Or you can find stop times for the particular trip:
StopTimes get_stop_times_for_trip(const Id & trip_id, bool sort_by_sequence = true)
📌 Provide gtfs::Feed
the feed path, read it and work with GTFS entities such as stops and routes:
Feed feed("~/data/SFMTA/");
if (feed.read_feed() == ResultCode::OK)
{
Stops stops = feed.get_stops();
std::cout << "Stops count in feed: " << stops.size() << std::endl;
for (const Stop & stop: stops)
{
std::cout << stop.stop_id << std::endl;
}
Route route = feed.get_route("route_id_1009");
if (route)
{
std::cout << route->route_long_name << std::endl;
}
}
GTFS feed can be wholly read from directory as in the example above or you can read GTFS files separately. E.g., if you need only shapes data, you can avoid parsing all other files and just work with the shapes.
📌 Read only shapes.txt
from the feed and work with shapes:
Feed feed("~/data/SFMTA/");
if (feed.read_shapes() == ResultCode::OK)
{
Shapes all_shapes = feed.get_shapes();
Shape shape = feed.get_shape("9367");
for (const ShapePoint & point: shape)
{
std::cout << point.shape_pt_lat << " " << point.shape_pt_lon << std::endl;
}
}
📌 If you already filled the feed
object with data that suits you, you can write it to the corresponding path:
Feed feed;
// Fill feed with agencies, stops, routes and other required data:
feed.add_trip(some_trip);
feed.add_attribution(attr);
feed.write_feed("~/data/custom_feed/");
- For including just_gtfs to your own project as a submodule: use branch "for-usage-as-submodule" which consists of a single header.
- Another way of including just_gtfs to your project: just_gtfs is completely contained inside a single header and therefore it is sufficient to copy include/just_gtfs/just_gtfs.h to your include paths. The library does not have to be explicitly build.
- For building library and running tests:
Clone just_gtfs with
git clone --recursive
or rungit submodule update --init --recursive --remote
after cloning. In the just_gtfs project directory build the project and run unit tests:
cmake .
make
ctest --output-on-failure --verbose
The library makes use of the C++17 features and therefore you have to use the appropriate compiler version.
- doctest for unit testing.
Please open a Github issue with as much of the information as you're able to specify, or create a pull request according to our guidelines.