Compare commits

..

No commits in common. "master" and "updated-readme" have entirely different histories.

8 changed files with 26 additions and 192 deletions

View file

@ -1,34 +0,0 @@
name: "CLA Assistant"
on:
issue_comment:
types: [created]
pull_request_target:
types: [opened,closed,synchronize]
jobs:
CLAssistant:
runs-on: ubuntu-latest
steps:
- name: "CLA Assistant"
if: (github.event.comment.body == 'recheck' || github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA') || github.event_name == 'pull_request_target'
# Alpha Release
uses: cla-assistant/github-action@v2.1.0-alpha
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PERSONAL_ACCESS_TOKEN : ${{ secrets.PERSONAL_ACCESS_TOKEN }}
with:
path-to-signatures: 'signatures/version1/cla.json'
path-to-document: 'https://github.com/mapsme/just_gtfs/blob/master/MIT_CLA.md'
# branch should not be protected
branch: 'master'
allowlist: mesozoic-drones,tatiana-yan,bot*
#below are the optional inputs - If the optional inputs are not given, then default values will be taken
#remote-organization-name: enter the remote organization name where the signatures should be stored (Default is storing the signatures in the same repository)
#remote-repository-name: enter the remote repository name where the signatures should be stored (Default is storing the signatures in the same repository)
#create-file-commit-message: 'For example: Creating file for storing CLA Signatures'
#signed-commit-message: 'For example: $contributorName has signed the CLA in #$pullRequestNo'
#custom-notsigned-prcomment: 'pull request comment with Introductory message to ask new contributors to sign'
#custom-pr-sign-comment: 'The signature to be committed in order to sign the CLA'
#custom-allsigned-prcomment: 'pull request comment when all contributors has signed, defaults to **CLA Assistant Lite bot** All Contributors have signed the CLA.'

View file

@ -11,8 +11,5 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Werror")
enable_testing()
add_library(just_gtfs INTERFACE)
target_include_directories(just_gtfs INTERFACE ${CMAKE_CURRENT_LIST_DIR}/include)
add_subdirectory(tests)
add_subdirectory(benchmarks)

View file

@ -1,59 +0,0 @@
## Individual Contributor License Agreement (CLA)
**Thank you for submitting your contributions to this project.**
By signing this CLA, you agree that the following terms apply to all of your past, present and future contributions
to the project.
### License.
You hereby represent that all present, past and future contributions are governed by the
[MIT License](https://opensource.org/licenses/MIT)
copyright statement.
This entails that to the extent possible under law, you transfer all copyright and related or neighboring rights
of the code or documents you contribute to the project itself or its maintainers.
Furthermore you also represent that you have the authority to perform the above waiver
with respect to the entirety of you contributions.
### Moral Rights.
To the fullest extent permitted under applicable law, you hereby waive, and agree not to
assert, all of your “moral rights” in or relating to your contributions for the benefit of the project.
### Third Party Content.
If your Contribution includes or is based on any source code, object code, bug fixes, configuration changes, tools,
specifications, documentation, data, materials, feedback, information or other works of authorship that were not
authored by you (“Third Party Content”) or if you are aware of any third party intellectual property or proprietary
rights associated with your Contribution (“Third Party Rights”),
then you agree to include with the submission of your Contribution full details respecting such Third Party
Content and Third Party Rights, including, without limitation, identification of which aspects of your
Contribution contain Third Party Content or are associated with Third Party Rights, the owner/author of the
Third Party Content and Third Party Rights, where you obtained the Third Party Content, and any applicable
third party license terms or restrictions respecting the Third Party Content and Third Party Rights. For greater
certainty, the foregoing obligations respecting the identification of Third Party Content and Third Party Rights
do not apply to any portion of a Project that is incorporated into your Contribution to that same Project.
### Representations.
You represent that, other than the Third Party Content and Third Party Rights identified by
you in accordance with this Agreement, you are the sole author of your Contributions and are legally entitled
to grant the foregoing licenses and waivers in respect of your Contributions. If your Contributions were
created in the course of your employment with your past or present employer(s), you represent that such
employer(s) has authorized you to make your Contributions on behalf of such employer(s) or such employer
(s) has waived all of their right, title or interest in or to your Contributions.
### Disclaimer.
To the fullest extent permitted under applicable law, your Contributions are provided on an "as is"
basis, without any warranties or conditions, express or implied, including, without limitation, any implied
warranties or conditions of non-infringement, merchantability or fitness for a particular purpose. You are not
required to provide support for your Contributions, except to the extent you desire to provide support.
### No Obligation.
You acknowledge that the maintainers of this project are under no obligation to use or incorporate your contributions
into the project. The decision to use or incorporate your contributions into the project will be made at the
sole discretion of the maintainers or their authorized delegates.

View file

@ -5,7 +5,6 @@
[![C++](https://img.shields.io/badge/c%2B%2B-17-informational.svg)](https://shields.io/)
[![MIT license](https://img.shields.io/badge/License-MIT-blue.svg)](https://lbesson.mit-license.org/)
![](https://github.com/mapsme/just_gtfs/workflows/C%2FC%2B%2B%20CI/badge.svg)
[![](https://github.com/sindresorhus/awesome/blob/main/media/mentioned-badge.svg)](https://github.com/CUTR-at-USF/awesome-transit)
[![contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](https://github.com/mapsme/just_gtfs/issues)

View file

@ -455,7 +455,6 @@ public:
inline Time() = default;
inline explicit Time(const std::string & raw_time_str);
inline Time(uint16_t hours, uint16_t minutes, uint16_t seconds);
inline Time(size_t seconds);
inline bool is_provided() const;
inline size_t get_total_seconds() const;
inline std::tuple<uint16_t, uint16_t, uint16_t> get_hh_mm_ss() const;
@ -517,8 +516,8 @@ inline Time::Time(const std::string & raw_time_str) : raw_time(raw_time_str)
return;
const size_t len = raw_time.size();
if (!(len >= 7 && len <= 9) || raw_time[len - 3] != ':' || raw_time[len - 6] != ':')
throw InvalidFieldFormat("Time is not in [[H]H]H:MM:SS format: " + raw_time_str);
if (!(len == 7 || len == 8) || (raw_time[len - 3] != ':' && raw_time[len - 6] != ':'))
throw InvalidFieldFormat("Time is not in [H]H:MM:SS format: " + raw_time_str);
hh = static_cast<uint16_t>(std::stoi(raw_time.substr(0, len - 6)));
mm = static_cast<uint16_t>(std::stoi(raw_time.substr(len - 5, 2)));
@ -544,13 +543,6 @@ inline Time::Time(uint16_t hours, uint16_t minutes, uint16_t seconds)
time_is_provided = true;
}
inline Time::Time(size_t seconds)
: time_is_provided(true), total_seconds(seconds),
hh(seconds / 3600), mm((seconds % 3600) / 60), ss(seconds % 3600)
{
set_raw_time();
}
inline bool Time::is_provided() const { return time_is_provided; }
inline size_t Time::get_total_seconds() const { return total_seconds; }
@ -652,7 +644,7 @@ using CurrencyCode = std::string;
using LanguageCode = std::string;
// Helper enums for some GTFS fields ---------------------------------------------------------------
enum class StopLocationType : int8_t
enum class StopLocationType
{
StopOrPlatform = 0,
Station = 1,
@ -662,7 +654,7 @@ enum class StopLocationType : int8_t
};
// The type of transportation used on a route.
enum class RouteType : int16_t
enum class RouteType
{
// GTFS route types
Tram = 0, // Tram, Streetcar, Light rail
@ -760,20 +752,20 @@ enum class RouteType : int16_t
HorseDrawnCarriage = 1702
};
enum class TripDirectionId : bool
enum class TripDirectionId
{
DefaultDirection = 0, // e.g. outbound
OppositeDirection = 1 // e.g. inbound
};
enum class TripAccess : int8_t
enum class TripAccess
{
NoInfo = 0,
Yes = 1,
No = 2
};
enum class StopTimeBoarding : int8_t
enum class StopTimeBoarding
{
RegularlyScheduled = 0,
No = 1, // Not available
@ -781,31 +773,31 @@ enum class StopTimeBoarding : int8_t
CoordinateWithDriver = 3 // Must coordinate with driver to arrange
};
enum class StopTimePoint : bool
enum class StopTimePoint
{
Approximate = 0,
Exact = 1
};
enum class CalendarAvailability : bool
enum class CalendarAvailability
{
NotAvailable = 0,
Available = 1
};
enum class CalendarDateException : int8_t
enum class CalendarDateException
{
Added = 1, // Service has been added for the specified date
Removed = 2
};
enum class FarePayment : bool
enum class FarePayment
{
OnBoard = 0,
BeforeBoarding = 1 // Fare must be paid before boarding
};
enum class FareTransfers : int8_t
enum class FareTransfers
{
No = 0, // No transfers permitted on this fare
Once = 1,
@ -813,13 +805,13 @@ enum class FareTransfers : int8_t
Unlimited = 3
};
enum class FrequencyTripService : bool
enum class FrequencyTripService
{
FrequencyBased = 0, // Frequency-based trips
ScheduleBased = 1 // Schedule-based trips with the exact same headway throughout the day
};
enum class TransferType : int8_t
enum class TransferType
{
Recommended = 0,
Timed = 1,
@ -827,7 +819,7 @@ enum class TransferType : int8_t
NotPossible = 3
};
enum class PathwayMode : int8_t
enum class PathwayMode
{
Walkway = 1,
Stairs = 2,
@ -838,13 +830,13 @@ enum class PathwayMode : int8_t
ExitGate = 7
};
enum class PathwayDirection : bool
enum class PathwayDirection
{
Unidirectional = 0,
Bidirectional = 1
};
enum class AttributionRole : bool
enum class AttributionRole
{
No = 0, // Organization doesnt have this role
Yes = 1 // Organization does have this role
@ -896,7 +888,7 @@ struct Stop
Text stop_code;
Text stop_desc;
Text stop_url;
StopLocationType location_type = StopLocationType::StopOrPlatform;
StopLocationType location_type = StopLocationType::GenericNode;
Text stop_timezone;
Text wheelchair_boarding;
Id level_id;
@ -1007,14 +999,6 @@ struct FareAttributesItem
size_t transfer_duration = 0; // Length of time in seconds before a transfer expires
};
inline bool operator==(const FareAttributesItem & lhs, const FareAttributesItem & rhs)
{
return std::tie(lhs.fare_id, lhs.price, lhs.currency_type, lhs.payment_method, lhs.transfers,
lhs.agency_id, lhs.transfer_duration) ==
std::tie(rhs.fare_id, rhs.price, rhs.currency_type, rhs.payment_method, rhs.transfers,
rhs.agency_id, rhs.transfer_duration);
}
// Optional dataset file
struct FareRule
{
@ -1356,7 +1340,6 @@ private:
inline void write_translations(std::ofstream & out) const;
inline void write_attributions(std::ofstream & out) const;
protected:
std::string gtfs_directory;
Agencies agencies;
@ -1857,7 +1840,7 @@ inline Result Feed::add_fare_attributes(const ParsedCsvRow & row)
item.currency_type = row.at("currency_type");
set_field(item.payment_method, row, "payment_method", false);
set_field(item.transfers, row, "transfers");
set_field(item.transfers, row, "transfers", false);
// Conditionally optional:
item.agency_id = get_value_or_default(row, "agency_id");
@ -2795,12 +2778,9 @@ inline void Feed::write_fare_attributes(std::ofstream & out) const
for (const auto & attribute : fare_attributes)
{
std::vector<std::string> fields{
wrap(attribute.fare_id), wrap(attribute.price), attribute.currency_type,
wrap(attribute.payment_method),
// Here we handle GTFS specification corner case: "The fact that this field can be left
// empty is an exception to the requirement that a Required field must not be empty.":
attribute.transfers == FareTransfers::Unlimited ? "" : wrap(attribute.transfers),
wrap(attribute.agency_id), wrap(attribute.transfer_duration)};
wrap(attribute.fare_id), wrap(attribute.price), attribute.currency_type,
wrap(attribute.payment_method), wrap(attribute.transfers), wrap(attribute.agency_id),
wrap(attribute.transfer_duration)};
write_joined(out, std::move(fields));
}
}

View file

@ -1,20 +0,0 @@
{
"signedContributors": [
{
"name": "nilsnolde",
"id": 25637358,
"comment_id": 1441674396,
"created_at": "2023-02-23T12:23:33Z",
"repoId": 250751634,
"pullRequestNo": 18
},
{
"name": "Osyotr",
"id": 8740768,
"comment_id": 2089322842,
"created_at": "2024-05-02T00:13:58Z",
"repoId": 250751634,
"pullRequestNo": 21
}
]
}

View file

@ -1,4 +1,3 @@
fare_id,price,currency_type,payment_method,transfers,transfer_duration
p,1.25,USD,0,0,
a,5.25,USD,1,1,
x,20,USD,0,,60
a,5.25,USD,0,0,

View file

@ -23,14 +23,6 @@ TEST_CASE("Time in HH:MM:SS format")
CHECK_EQ(stop_time.get_total_seconds(), 39 * 60 * 60 + 45 * 60 + 30);
}
TEST_CASE("Time in HHH:MM:SS format")
{
Time stop_time("103:05:21");
CHECK_EQ(stop_time.get_hh_mm_ss(), std::make_tuple(103, 5, 21));
CHECK_EQ(stop_time.get_raw_time(), "103:05:21");
CHECK_EQ(stop_time.get_total_seconds(), 103 * 60 * 60 + 5 * 60 + 21);
}
TEST_CASE("Time from integers 1")
{
Time stop_time(14, 30, 0);
@ -52,7 +44,6 @@ TEST_CASE("Invalid time format")
CHECK_THROWS_AS(Time("12/10/00"), const InvalidFieldFormat &);
CHECK_THROWS_AS(Time("12:100:00"), const InvalidFieldFormat &);
CHECK_THROWS_AS(Time("12:10:100"), const InvalidFieldFormat &);
CHECK_THROWS_AS(Time("12:10/10"), const InvalidFieldFormat &);
}
TEST_CASE("Time not provided")
@ -310,7 +301,7 @@ TEST_CASE("Read GTFS feed")
CHECK_EQ(feed.get_attributions().size(), 1);
CHECK_EQ(feed.get_calendar().size(), 2);
CHECK_EQ(feed.get_calendar_dates().size(), 1);
CHECK_EQ(feed.get_fare_attributes().size(), 3);
CHECK_EQ(feed.get_fare_attributes().size(), 2);
CHECK_EQ(feed.get_fare_rules().size(), 4);
CHECK(!feed.get_feed_info().feed_publisher_name.empty());
CHECK_EQ(feed.get_levels().size(), 3);
@ -395,7 +386,7 @@ TEST_CASE("Stops")
CHECK_EQ(stops[0].stop_id, "FUR_CREEK_RES");
CHECK(stops[0].stop_desc.empty());
CHECK_EQ(stops[0].stop_name, "Furnace Creek Resort (Demo)");
CHECK_EQ(stops[0].location_type, StopLocationType::StopOrPlatform);
CHECK_EQ(stops[0].location_type, StopLocationType::GenericNode);
CHECK(stops[0].zone_id.empty());
auto const & stop = feed.get_stop("FUR_CREEK_RES");
@ -494,7 +485,7 @@ TEST_CASE("Fare attributes")
REQUIRE_EQ(feed.read_fare_attributes(), ResultCode::OK);
const auto & attributes = feed.get_fare_attributes();
REQUIRE_EQ(attributes.size(), 3);
REQUIRE_EQ(attributes.size(), 2);
CHECK_EQ(attributes[0].fare_id, "p");
CHECK_EQ(attributes[0].price, 1.25);
CHECK_EQ(attributes[0].currency_type, "USD");
@ -502,28 +493,9 @@ TEST_CASE("Fare attributes")
CHECK_EQ(attributes[0].transfers, FareTransfers::No);
CHECK_EQ(attributes[0].transfer_duration, 0);
CHECK_EQ(attributes[1].fare_id, "a");
CHECK_EQ(attributes[1].price, 5.25);
CHECK_EQ(attributes[1].currency_type, "USD");
CHECK_EQ(attributes[1].payment_method, FarePayment::BeforeBoarding);
CHECK_EQ(attributes[1].transfers, FareTransfers::Once);
CHECK_EQ(attributes[1].transfer_duration, 0);
CHECK_EQ(attributes[2].fare_id, "x");
CHECK_EQ(attributes[2].price, 20);
CHECK_EQ(attributes[2].currency_type, "USD");
CHECK_EQ(attributes[2].payment_method, FarePayment::OnBoard);
CHECK_EQ(attributes[2].transfers, FareTransfers::Unlimited);
CHECK_EQ(attributes[2].transfer_duration, 60);
const auto & attributes_for_id = feed.get_fare_attributes("a");
REQUIRE_EQ(attributes_for_id.size(), 1);
CHECK_EQ(attributes_for_id[0].price, 5.25);
REQUIRE_EQ(feed.write_fare_attributes("data/output_feed"), ResultCode::OK);
Feed feed_copy("data/output_feed");
REQUIRE_EQ(feed_copy.read_fare_attributes(), ResultCode::OK);
CHECK_EQ(attributes, feed_copy.get_fare_attributes());
}
TEST_CASE("Fare rules")