Commit 4489fff0 authored by Volker Krause's avatar Volker Krause

Merge journey results from multiple sources

parent 43b95df6
......@@ -234,6 +234,39 @@ bool JourneySection::arrivalPlatformChanged() const
return hasExpectedArrivalPlatform() && d->scheduledArrivalPlatform != d->expectedArrivalPlatform;
}
bool JourneySection::isSame(const JourneySection &lhs, const JourneySection &rhs)
{
return lhs.d->mode == rhs.d->mode
&& lhs.d->scheduledDepartureTime == rhs.d->scheduledDepartureTime
&& lhs.d->scheduledArrivalTime == rhs.d->scheduledArrivalTime
&& Location::isSame(lhs.d->from, rhs.d->from)
&& Location::isSame(lhs.d->to, rhs.d->to)
&& Route::isSame(lhs.d->route, rhs.d->route);
// ### platforms relevant?
}
JourneySection JourneySection::merge(const JourneySection &lhs, const JourneySection &rhs)
{
auto res = lhs;
if (!res.expectedDepartureTime().isValid()) {
res.setExpectedDepartureTime(rhs.expectedDepartureTime());
}
if (res.expectedDeparturePlatform().isEmpty()) {
res.setExpectedDeparturePlatform(rhs.expectedDeparturePlatform());
}
if (!res.expectedArrivalTime().isValid()) {
res.setExpectedArrivalTime(rhs.expectedArrivalTime());
}
if (res.expectedArrivalPlatform().isEmpty()) {
res.setExpectedArrivalPlatform(rhs.expectedArrivalPlatform());
}
res.setFrom(Location::merge(lhs.from(), rhs.from()));
res.setTo(Location::merge(lhs.to(), rhs.to()));
res.setRoute(Route::merge(lhs.route(), rhs.route()));
return res;
}
KPUBLICTRANSPORT_MAKE_GADGET(Journey)
......@@ -287,4 +320,30 @@ int Journey::numberOfChanges() const
return std::count_if(d->sections.begin(), d->sections.end(), [](const auto &section) { return section.mode() == JourneySection::PublicTransport; });
}
bool Journey::isSame(const Journey &lhs, const Journey &rhs)
{
// ### we can make this more clever by ignoring transit elements for example
// doing that will need changes below too!
if (lhs.sections().size() != rhs.sections().size()) {
return false;
}
return std::equal(lhs.sections().begin(), lhs.sections().end(), rhs.sections().begin(), [](const auto &lhs, const auto &rhs) {
return JourneySection::isSame(lhs, rhs);
});
}
Journey Journey::merge(const Journey &lhs, const Journey &rhs)
{
// ### see above
std::vector<JourneySection> sections;
sections.reserve(lhs.sections().size());
for (auto lit = lhs.sections().begin(), rit = rhs.sections().begin(); lit != lhs.sections().end(); ++lit, ++rit) {
sections.push_back(JourneySection::merge(*lit, *rit));
}
Journey res;
res.setSections(std::move(sections));
return res;
}
#include "moc_journey.cpp"
......@@ -136,6 +136,14 @@ public:
void setExpectedArrivalPlatform(const QString &platform);
bool hasExpectedArrivalPlatform() const;
bool arrivalPlatformChanged() const;
/** Checks if two instances refer to the same journey section (which does not necessarily mean they are exactly equal). */
static bool isSame(const JourneySection &lhs, const JourneySection &rhs);
/** Merge two instances.
* This assumes isSame(lhs, rhs) and tries to preserve the most detailed information.
*/
static JourneySection merge(const JourneySection &lhs, const JourneySection &rhs);
};
class JourneyPrivate;
......@@ -167,6 +175,15 @@ public:
QDateTime scheduledArrivalTime() const;
int duration() const;
int numberOfChanges() const;
/** Checks if two instances refer to the same journey (which does not necessarily mean they are exactly equal). */
static bool isSame(const Journey &lhs, const Journey &rhs);
/** Merge two instances.
* This assumes isSame(lhs, rhs) and tries to preserve the most detailed information.
*/
static Journey merge(const Journey &lhs, const Journey &rhs);
private:
QVariantList sectionsVariant() const;
};
......
......@@ -81,6 +81,25 @@ void JourneyReplyPrivate::postProcessJourneys()
}
journey.setSections(std::move(sections));
}
// sort and merge results
std::sort(journeys.begin(), journeys.end(), [](const auto &lhs, const auto &rhs) {
return lhs.scheduledDepartureTime() < rhs.scheduledDepartureTime();
});
for (auto it = journeys.begin(); it != journeys.end(); ++it) {
for (auto mergeIt = it + 1; mergeIt != journeys.end();) {
if ((*it).scheduledDepartureTime() != (*mergeIt).scheduledDepartureTime()) {
break;
}
if (Journey::isSame(*it, *mergeIt)) {
*it = Journey::merge(*it, *mergeIt);
mergeIt = journeys.erase(mergeIt);
} else {
++mergeIt;
}
}
}
}
JourneyReply::JourneyReply(const JourneyRequest &req)
......
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