diff --git a/src/publictransport/datatypes/journey.cpp b/src/publictransport/datatypes/journey.cpp index 9950748..cf72b74 100644 --- a/src/publictransport/datatypes/journey.cpp +++ b/src/publictransport/datatypes/journey.cpp @@ -1,162 +1,167 @@ /* Copyright (C) 2018 Volker Krause This program is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "journey.h" #include "datatypes_p.h" #include using namespace KPublicTransport; namespace KPublicTransport { class JourneySectionPrivate : public QSharedData { public: JourneySection::Mode mode = JourneySection::Invalid; QDateTime departureTime; QDateTime arrivalTime; Location from; Location to; Route route; }; class JourneyPrivate : public QSharedData { public: std::vector sections; }; } KPUBLICTRANSPORT_MAKE_GADGET(JourneySection) JourneySection::Mode JourneySection::mode() const { return d->mode; } void JourneySection::setMode(JourneySection::Mode mode) { d.detach(); d->mode = mode; } QDateTime JourneySection::departureTime() const { return d->departureTime; } void JourneySection::setDepartureTime(const QDateTime &dt) { d.detach(); d->departureTime = dt; } QDateTime JourneySection::arrivalTime() const { return d->arrivalTime; } void JourneySection::setArrivalTime(const QDateTime &dt) { d.detach(); d->arrivalTime = dt; } int JourneySection::duration() const { return d->departureTime.secsTo(d->arrivalTime); } Location JourneySection::from() const { return d->from; } void JourneySection::setFrom(const Location &from) { d.detach(); d->from = from; } Location JourneySection::to() const { return d->to; } void JourneySection::setTo(const Location &to) { d.detach(); d->to = to; } Route JourneySection::route() const { return d->route; } void JourneySection::setRoute(const Route &route) { d.detach(); d->route = route; } KPUBLICTRANSPORT_MAKE_GADGET(Journey) const std::vector& Journey::sections() const { return d->sections; } +std::vector&& Journey::takeSections() +{ + return std::move(d->sections); +} + void Journey::setSections(std::vector &§ions) { d.detach(); d->sections = std::move(sections); } QVariantList Journey::sectionsVariant() const { QVariantList l; l.reserve(d->sections.size()); std::transform(d->sections.begin(), d->sections.end(), std::back_inserter(l), [](const auto &sec) { return QVariant::fromValue(sec); }); return l; } QDateTime KPublicTransport::Journey::departureTime() const { if (!d->sections.empty()) { return d->sections.front().departureTime(); } return {}; } QDateTime Journey::arrivalTime() const { if (!d->sections.empty()) { return d->sections.back().arrivalTime(); } return {}; } int Journey::duration() const { return departureTime().secsTo(arrivalTime()); } #include "moc_journey.cpp" diff --git a/src/publictransport/datatypes/journey.h b/src/publictransport/datatypes/journey.h index 8e6c491..c9c6f01 100644 --- a/src/publictransport/datatypes/journey.h +++ b/src/publictransport/datatypes/journey.h @@ -1,111 +1,113 @@ /* Copyright (C) 2018 Volker Krause This program is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef KPUBLICTRANSPORT_JOURNEY_H #define KPUBLICTRANSPORT_JOURNEY_H #include "datatypes.h" #include "line.h" #include "location.h" #include #include namespace KPublicTransport { class JourneySectionPrivate; /** A segment of a journey plan. */ class JourneySection { KPUBLICTRANSPORT_GADGET(JourneySection) /** Mode of transport for this section. */ Q_PROPERTY(Mode mode READ mode WRITE setMode) /** Departue time for this segment. */ Q_PROPERTY(QDateTime departureTime READ departureTime WRITE setDepartureTime) /** Arrival time for this segment. */ Q_PROPERTY(QDateTime arrivalTime READ arrivalTime WRITE setArrivalTime) /** Duration of the section in seconds. */ Q_PROPERTY(int duration READ duration STORED false) /** Departure location of this segment. */ Q_PROPERTY(KPublicTransport::Location from READ from WRITE setFrom) /** Arrival location of this segment. */ Q_PROPERTY(KPublicTransport::Location to READ to WRITE setTo) /** Route to take on this segment. */ Q_PROPERTY(KPublicTransport::Route route READ route WRITE setRoute) // TODO: planned vs. expected times? public: /** Mode of transport. */ enum Mode { Invalid, PublicTransport, Transfer, Walking, Waiting }; Q_ENUM(Mode) Mode mode() const; void setMode(Mode mode); QDateTime departureTime() const; void setDepartureTime(const QDateTime &dt); QDateTime arrivalTime() const; void setArrivalTime(const QDateTime &dt); int duration() const; Location from() const; void setFrom(const Location &from); Location to() const; void setTo(const Location &to); Route route() const; void setRoute(const Route &route); }; class JourneyPrivate; /** A journey plan. */ class Journey { KPUBLICTRANSPORT_GADGET(Journey) /** Journey sections for consumption by QML. */ Q_PROPERTY(QVariantList sections READ sectionsVariant) /** Departure time of the journey. */ Q_PROPERTY(QDateTime departureTime READ departureTime STORED false) /** Arrival time of the journey. */ Q_PROPERTY(QDateTime arrivalTime READ arrivalTime STORED false) /** Duration of the entire journey in seconds. */ Q_PROPERTY(int duration READ duration STORED false) public: /** The journey sections. */ const std::vector& sections() const; + /** Moves the journey sections out of this object. */ + std::vector&& takeSections(); /** Sets the journey sections. */ void setSections(std::vector &§ions); QDateTime departureTime() const; QDateTime arrivalTime() const; int duration() const; private: QVariantList sectionsVariant() const; }; } Q_DECLARE_METATYPE(KPublicTransport::JourneySection) Q_DECLARE_METATYPE(KPublicTransport::Journey) #endif // KPUBLICTRANSPORT_JOURNEY_H diff --git a/src/publictransport/journeyreply.cpp b/src/publictransport/journeyreply.cpp index 10b7b2e..25f7872 100644 --- a/src/publictransport/journeyreply.cpp +++ b/src/publictransport/journeyreply.cpp @@ -1,82 +1,115 @@ /* Copyright (C) 2018 Volker Krause This program is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "journeyreply.h" #include "journeyrequest.h" #include "logging.h" #include "backends/navitiaclient.h" #include "backends/navitiaparser.h" #include #include #include #include +#include using namespace KPublicTransport; namespace KPublicTransport { class JourneyReplyPrivate { public: + void postProcessJourneys(); + std::vector journeys; QString errorMsg; JourneyReply::Error error = JourneyReply::NoError; }; } +void JourneyReplyPrivate::postProcessJourneys() +{ + // try to fill gaps in timezone data + for (auto &journey : journeys) { + auto sections = journey.takeSections(); + for (auto §ion : sections) { + if (section.mode() == JourneySection::Walking) { + if (!section.from().timeZone().isValid() && section.to().timeZone().isValid()) { + auto from = section.from(); + from.setTimeZone(section.to().timeZone()); + section.setFrom(from); + auto dt = section.departureTime(); + dt.setTimeZone(from.timeZone()); + section.setDepartureTime(dt); + } + if (section.from().timeZone().isValid() && !section.to().timeZone().isValid()) { + auto to = section.to(); + to.setTimeZone(section.from().timeZone()); + section.setTo(to); + auto dt = section.arrivalTime(); + dt.setTimeZone(to.timeZone()); + section.setArrivalTime(dt); + } + } + } + journey.setSections(std::move(sections)); + } +} + JourneyReply::JourneyReply(const JourneyRequest &req, QNetworkAccessManager *nam) : d(new JourneyReplyPrivate) { auto reply = NavitiaClient::findJourney(req, nam); connect(reply, &QNetworkReply::finished, [reply, this] { switch (reply->error()) { case QNetworkReply::NoError: d->journeys = NavitiaParser::parseJourneys(reply->readAll()); + d->postProcessJourneys(); break; case QNetworkReply::ContentNotFoundError: d->error = NotFoundError; d->errorMsg = NavitiaParser::parseErrorMessage(reply->readAll()); break; default: d->error = NetworkError; d->errorMsg = reply->errorString(); qCDebug(Log) << reply->error() << reply->errorString(); } emit finished(); deleteLater(); }); } JourneyReply::~JourneyReply() = default; std::vector JourneyReply::journeys() const { // TODO avoid the copy here return d->journeys; } JourneyReply::Error JourneyReply::error() const { return d->error; } QString JourneyReply::errorString() const { return d->errorMsg; }