Commit 44ede4a2 authored by Volker Krause's avatar Volker Krause
Browse files

Add support for access/egress modes and rental bikes for Entur

Needs a different mode argument than OTP2, but otherwise just minor changes
to the GraphQL and result parser.
parent 5d508893
Pipeline #87001 passed with stage
in 1 minute and 15 seconds
......@@ -156,6 +156,39 @@ static QString qualifierName(IndividualTransport::Qualifier qualifier)
return {};
}
static void addEnturModes(QStringList &modes, const std::vector<IndividualTransport> &its)
{
for (const auto &it : its) {
switch (it.mode()) {
case IndividualTransport::Bike:
// TODO park/rent variants only supported by Entur v3
modes.push_back(QStringLiteral("bicycle"));
break;
case IndividualTransport::Car:
switch (it.qualifier()) {
case IndividualTransport::None:
modes.push_back(QStringLiteral("car"));
break;
case IndividualTransport::Park:
modes.push_back(QStringLiteral("car_park"));
break;
case IndividualTransport::Pickup:
modes.push_back(QStringLiteral("car_pickup"));
break;
case IndividualTransport::Dropoff:
modes.push_back(QStringLiteral("car_dropoff"));
break;
case IndividualTransport::Rent: // not supported
break;
}
break;
case IndividualTransport::Walk:
modes.push_back(QStringLiteral("foot"));
break;
}
}
}
bool OpenTripPlannerGraphQLBackend::queryJourney(const JourneyRequest &req, JourneyReply *reply, QNetworkAccessManager *nam) const
{
if (!req.from().hasCoordinate() || !req.to().hasCoordinate()) {
......@@ -188,47 +221,66 @@ bool OpenTripPlannerGraphQLBackend::queryJourney(const JourneyRequest &req, Jour
gqlReq.setVariable(QStringLiteral("withPaths"), req.includePaths());
// TODO set context.searchWindow?
struct Mode {
QString mode;
QString qualifier;
};
std::vector<Mode> modes;
if (m_apiVersion == QLatin1String("entur")) {
gqlReq.setVariable(QStringLiteral("allowBikeRental"), (req.modes() & JourneySection::RentedVehicle) != 0);
QStringList modes;
modes.push_back(QStringLiteral("foot"));
if (req.modes() & JourneySection::PublicTransport) {
modes.push_back(QStringLiteral("transit"));
}
if (req.modes() & JourneySection::RentedVehicle) {
modes.push_back(QStringLiteral("bicycle"));
}
addEnturModes(modes, req.accessModes());
addEnturModes(modes, req.egressModes());
if (req.modes() & JourneySection::PublicTransport) {
for (const auto &mode : m_supportedTransitModes) {
modes.push_back({ mode, {} });
modes.removeDuplicates();
QJsonArray modesArray;
std::copy(modes.begin(), modes.end(), std::back_inserter(modesArray));
gqlReq.setVariable(QStringLiteral("modes"), modesArray);
} else {
struct Mode {
QString mode;
QString qualifier;
};
std::vector<Mode> modes;
if (req.modes() & JourneySection::PublicTransport) {
for (const auto &mode : m_supportedTransitModes) {
modes.push_back({ mode, {} });
}
}
}
if (req.modes() & JourneySection::RentedVehicle) {
for (const auto &mode : m_supportedRentalModes) {
modes.push_back({ mode, QStringLiteral("RENT") });
if (req.modes() & JourneySection::RentedVehicle) {
for (const auto &mode : m_supportedRentalModes) {
modes.push_back({ mode, QStringLiteral("RENT") });
}
}
}
for (const auto &it : req.accessModes()) {
modes.push_back({ modeName(it.mode()), qualifierName(it.qualifier()) });
}
const auto modeLessThan = [](const Mode &lhs, const Mode &rhs) {
if (lhs.mode == rhs.mode) {
return lhs.qualifier < rhs.qualifier;
for (const auto &it : req.accessModes()) {
modes.push_back({ modeName(it.mode()), qualifierName(it.qualifier()) });
}
return lhs.mode < rhs.mode;
};
const auto modeEqual = [](const Mode &lhs, const Mode &rhs) {
return lhs.mode == rhs.mode && lhs.qualifier == rhs.qualifier;
};
std::sort(modes.begin(), modes.end(), modeLessThan);
modes.erase(std::unique(modes.begin(), modes.end(), modeEqual), modes.end());
QJsonArray modesArray;
for (const auto &mode : modes) {
QJsonObject modeObj;
modeObj.insert(QLatin1String("mode"), mode.mode);
if (!mode.qualifier.isEmpty()) {
modeObj.insert(QLatin1String("qualifier"), mode.qualifier);
const auto modeLessThan = [](const Mode &lhs, const Mode &rhs) {
if (lhs.mode == rhs.mode) {
return lhs.qualifier < rhs.qualifier;
}
return lhs.mode < rhs.mode;
};
const auto modeEqual = [](const Mode &lhs, const Mode &rhs) {
return lhs.mode == rhs.mode && lhs.qualifier == rhs.qualifier;
};
std::sort(modes.begin(), modes.end(), modeLessThan);
modes.erase(std::unique(modes.begin(), modes.end(), modeEqual), modes.end());
QJsonArray modesArray;
for (const auto &mode : modes) {
QJsonObject modeObj;
modeObj.insert(QLatin1String("mode"), mode.mode);
if (!mode.qualifier.isEmpty()) {
modeObj.insert(QLatin1String("qualifier"), mode.qualifier);
}
modesArray.push_back(modeObj);
}
modesArray.push_back(modeObj);
gqlReq.setVariable(QStringLiteral("modes"), modesArray);
}
gqlReq.setVariable(QStringLiteral("modes"), modesArray);
if (isLoggingEnabled()) {
logRequest(req, gqlReq.networkRequest(), gqlReq.rawData());
......
......@@ -430,7 +430,7 @@ JourneySection OpenTripPlannerParser::parseJourneySection(const QJsonObject &obj
if (mode.compare(QLatin1String("WALK"), Qt::CaseInsensitive) == 0 || mode.compare(QLatin1String("FOOT"), Qt::CaseInsensitive) == 0) {
section.setMode(JourneySection::Walking);
} else if (mode == QLatin1String("BICYCLE")) {
} else if (mode.compare(QLatin1String("BICYCLE"), Qt::CaseInsensitive) == 0) {
RentalVehicle v;
if (from.rentalVehicleStation().network().isValid()) {
v.setNetwork(from.rentalVehicleStation().network());
......@@ -447,7 +447,7 @@ JourneySection OpenTripPlannerParser::parseJourneySection(const QJsonObject &obj
section.setMode(JourneySection::IndividualTransport);
section.setIndividualTransport({ IndividualTransport::Bike });
}
} else if (mode == QLatin1String("CAR")) {
} else if (mode.compare(QLatin1String("CAR"), Qt::CaseInsensitive) == 0) {
section.setMode(JourneySection::IndividualTransport);
section.setIndividualTransport({ IndividualTransport::Car });
} else {
......
......@@ -12,6 +12,8 @@ query journeys(
$lang: Locale!,
$withIntermediateStops: Boolean!,
$withPaths: Boolean!
$allowBikeRental: Boolean!
$modes: [Mode]!
) {
plan: trip (
from: { coordinates: { latitude: $fromLat, longitude: $fromLon } }
......@@ -20,6 +22,8 @@ query journeys(
arriveBy: $arriveBy
numTripPatterns: $maxResults
locale: $lang
allowBikeRental: $allowBikeRental
modes: $modes
) {
itineraries: tripPatterns {
legs {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment