diff --git a/src/journeyreply.cpp b/src/journeyreply.cpp index 65bed03..e5833a0 100644 --- a/src/journeyreply.cpp +++ b/src/journeyreply.cpp @@ -1,143 +1,154 @@ /* 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 "reply_p.h" #include "journeyrequest.h" #include "logging.h" #include #include #include #include using namespace KPublicTransport; namespace KPublicTransport { class JourneyReplyPrivate : public ReplyPrivate { public: void finalizeResult() override; void postProcessJourneys(); JourneyRequest request; std::vector journeys; }; } void JourneyReplyPrivate::finalizeResult() { if (journeys.empty()) { return; } error = Reply::NoError; errorMsg.clear(); postProcessJourneys(); std::sort(journeys.begin(), journeys.end(), [](const auto &lhs, const auto &rhs) { return lhs.scheduledDepartureTime() < rhs.scheduledDepartureTime(); }); } +static QDateTime firstTransportDeparture(const Journey &jny) +{ + for (const auto §ion : jny.sections()) { + if (section.mode() == JourneySection::PublicTransport) { + return section.scheduledDepartureTime(); + } + } + + return jny.scheduledDepartureTime(); +} + 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.scheduledDepartureTime(); dt.setTimeZone(from.timeZone()); section.setScheduledDepartureTime(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.scheduledArrivalTime(); dt.setTimeZone(to.timeZone()); section.setScheduledArrivalTime(dt); } } } journey.setSections(std::move(sections)); } - // sort and merge results + // sort and merge results, aligned by first transport departure std::sort(journeys.begin(), journeys.end(), [](const auto &lhs, const auto &rhs) { - return lhs.scheduledDepartureTime() < rhs.scheduledDepartureTime(); + return firstTransportDeparture(lhs) < firstTransportDeparture(rhs); }); for (auto it = journeys.begin(); it != journeys.end(); ++it) { for (auto mergeIt = it + 1; mergeIt != journeys.end();) { - if ((*it).scheduledDepartureTime() != (*mergeIt).scheduledDepartureTime()) { + if (firstTransportDeparture(*it) != firstTransportDeparture(*mergeIt)) { break; } if (Journey::isSame(*it, *mergeIt)) { *it = Journey::merge(*it, *mergeIt); mergeIt = journeys.erase(mergeIt); } else { ++mergeIt; } } } } JourneyReply::JourneyReply(const JourneyRequest &req, QObject *parent) : Reply(new JourneyReplyPrivate, parent) { Q_D(JourneyReply); d->request = req; } JourneyReply::~JourneyReply() = default; JourneyRequest JourneyReply::request() const { Q_D(const JourneyReply); return d->request; } const std::vector& JourneyReply::result() const { Q_D(const JourneyReply); return d->journeys; } std::vector&& JourneyReply::takeResult() { Q_D(JourneyReply); return std::move(d->journeys); } void JourneyReply::addResult(std::vector &&res) { Q_D(JourneyReply); if (d->journeys.empty()) { d->journeys = std::move(res); } else { d->journeys.insert(d->journeys.end(), res.begin(), res.end()); } d->pendingOps--; d->emitFinishedIfDone(this); }