7#include "journeyrequest.h"
8#include "requestcontext_p.h"
9#include "datatypes/datatypes_p.h"
10#include "datatypes/json_p.h"
11#include "datatypes/locationutil_p.h"
13#include <KPublicTransport/Location>
15#include <QCryptographicHash>
21#include <unordered_map>
25enum { JourneyCacheTimeResolution = 60 };
33 std::vector<RequestContext> contexts;
37 int maximumResults = 12;
38 bool downloadAssets =
false;
39 bool includeIntermediateStops =
true;
40 bool includePaths =
false;
42 std::vector<IndividualTransport> accessModes = { {IndividualTransport::Walk} };
43 std::vector<IndividualTransport> egressModes = { {IndividualTransport::Walk} };
44 std::vector<Line::Mode> lineModes;
52KPUBLICTRANSPORT_MAKE_PROPERTY(
JourneyRequest,
bool, downloadAssets, setDownloadAssets)
54KPUBLICTRANSPORT_MAKE_PROPERTY(
JourneyRequest,
int, maximumResults, setMaximumResults)
55KPUBLICTRANSPORT_MAKE_PROPERTY(
JourneyRequest,
bool, includeIntermediateStops, setIncludeIntermediateStops)
56KPUBLICTRANSPORT_MAKE_PROPERTY(
JourneyRequest,
bool, includePaths, setIncludePaths)
59 : d(new JourneyRequestPrivate)
67 return !d->to.isEmpty() && !d->from.isEmpty();
72 if (!d->dateTime.isValid()) {
78void JourneyRequest::setDateTime(
const QDateTime& dt)
98RequestContext JourneyRequest::context(
const AbstractBackend *backend)
const
100 const auto it = std::lower_bound(d->contexts.begin(), d->contexts.end(), backend);
101 if (it != d->contexts.end() && (*it).backend == backend) {
105 RequestContext context;
106 context.backend = backend;
110const std::vector<RequestContext>& JourneyRequest::contexts()
const
115void JourneyRequest::setContext(
const AbstractBackend *backend, RequestContext &&context)
118 const auto it = std::lower_bound(d->contexts.begin(), d->contexts.end(), backend);
119 if (it != d->contexts.end() && (*it).backend == backend) {
120 (*it) = std::move(context);
122 d->contexts.insert(it, std::move(context));
128 RequestContext::purgeLoops(d->contexts, baseRequest.contexts());
133 auto obj = Json::toJson(req);
143 return d->backendIds;
153static QVariantList toVariantList(
const std::vector<T> &v)
157 std::transform(v.begin(), v.end(), std::back_inserter(l), [](
const T &value) {
158 return QVariant::fromValue<T>(value);
165 return d->accessModes;
168QVariantList JourneyRequest::accessModesVariant()
const
170 return toVariantList(d->accessModes);
179void JourneyRequest::setAccessModesVariant(
const QVariantList &accessModesVariant)
187 return d->egressModes;
190QVariantList JourneyRequest::egressModesVariant()
const
192 return toVariantList(d->egressModes);
201void JourneyRequest::setEgressModesVariant(
const QVariantList &egressModesVariant)
216 std::sort(d->lineModes.begin(), d->lineModes.end());
217 d->lineModes.erase(std::unique(d->lineModes.begin(), d->lineModes.end()), d->lineModes.end());
220QVariantList JourneyRequest::lineModesVariant()
const
222 return toVariantList(d->lineModes);
225void JourneyRequest::setLineModesVariant(
const QVariantList &lineModes)
227 auto l = std::move(d->lineModes);
230 std::transform(
lineModes.begin(),
lineModes.end(), std::back_inserter(l), [](
const auto &mode) { return static_cast<Line::Mode>(mode.toInt()); });
238 hash.
addData(LocationUtil::cacheKey(d->from).toUtf8());
239 hash.
addData(LocationUtil::cacheKey(d->to).toUtf8());
243 hash.
addData(d->includeIntermediateStops ?
"I" :
"-");
244 hash.
addData(d->includePaths ?
"P" :
"-");
247 for (
const auto &it : d->accessModes) {
253 for (
const auto &it : d->accessModes) {
259 for (
const auto &mode : d->lineModes) {
266static bool hasTakeBikeMode(
const std::vector<IndividualTransport> &modes)
268 return std::any_of(modes.begin(), modes.end(), [](
const auto &it) {
269 return it.mode() == IndividualTransport::Bike && it.qualifier() == IndividualTransport::None;
273void JourneyRequest::validate()
const
276 d->accessModes.erase(std::remove_if(d->accessModes.begin(), d->accessModes.end(), [](
const auto &it) {
277 return (it.mode() == IndividualTransport::Car && it.qualifier() == IndividualTransport::None)
278 || it.qualifier() == IndividualTransport::Pickup;
279 }), d->accessModes.end());
280 d->egressModes.erase(std::remove_if(d->egressModes.begin(), d->egressModes.end(), [](
const auto &it) {
281 return (it.mode() == IndividualTransport::Car && it.qualifier() == IndividualTransport::None)
282 || it.qualifier() == IndividualTransport::Dropoff
283 || it.qualifier() == IndividualTransport::Park;
284 }), d->egressModes.end());
287 const auto hasTakeBikeAccess = hasTakeBikeMode(d->accessModes);
288 const auto hasTakeBikeEgress = hasTakeBikeMode(d->egressModes);
289 if (hasTakeBikeAccess && !hasTakeBikeEgress) {
290 d->egressModes.push_back({ IndividualTransport::Bike });
291 }
else if (!hasTakeBikeAccess && hasTakeBikeEgress) {
292 d->egressModes.erase(std::remove_if(d->egressModes.begin(), d->egressModes.end(), [](
const auto &it) {
293 return it.mode() == IndividualTransport::Bike && it.qualifier() == IndividualTransport::None;
294 }), d->egressModes.end());
298 if (d->accessModes.empty()) {
299 d->accessModes = {{IndividualTransport::Walk}};
301 if (d->egressModes.empty()) {
302 d->egressModes = {{IndividualTransport::Walk}};
306#include "moc_journeyrequest.cpp"
static std::vector< IndividualTransport > fromVariant(const QVariantList &v)
static QJsonObject toJson(const IndividualTransport &it)
Serializes one object to JSON.
Describes a journey search.
QDateTime dateTime
Date/time at which the journey should start/end.
KPublicTransport::Location to
The journey destination.
void setArrivalTime(const QDateTime &dt)
Sets the desired arrival time.
void setDepartureTime(const QDateTime &dt)
Set the desired departure time.
void setAccessModes(std::vector< IndividualTransport > &&accessModes)
Sets the requested access modes.
QStringList backendIds() const
Identifiers of the backends that should be queried.
void setEgressModes(std::vector< IndividualTransport > &&egressModes)
Sets the requested egress modes.
@ Arrival
dateTime() represents the desired arriva time.
@ Departure
dateTime() represents the desired departure time.
bool isValid() const
Returns true if this is a valid request, that is, it has enough parameters set to perform a query.
QString cacheKey() const
Unique string representation used for caching results.
QVariantList egressModes
Egress modes.
KPublicTransport::Location from
The starting point of the journey search.
void setBackendIds(const QStringList &backendIds)
Set identifiers of backends that should be queried.
QVariantList accessModes
Access modes.
void setLineModes(std::vector< Line::Mode > &&modes)
Sets the requested line modes.
QVariantList lineModes
Line modes.
@ RentedVehicle
free floating or dock-based rental bike service, electric scooters, car sharing services,...
static QJsonObject toJson(const Location &loc)
Serializes one Location object to JSON.
Query operations and data types for accessing realtime public transport information from online servi...
QByteArray number(double n, char format, int precision)
QByteArray toHex(char separator) const const
bool addData(QIODevice *device)
QByteArray result() const const
QDateTime currentDateTime()
QString fromUtf8(QByteArrayView str)