KPublicTransport

stopover.cpp
1/*
2 SPDX-FileCopyrightText: 2018 Volker Krause <vkrause@kde.org>
3
4 SPDX-License-Identifier: LGPL-2.0-or-later
5*/
6
7#include "stopover.h"
8#include "datatypes_p.h"
9#include "json_p.h"
10#include "loadutil_p.h"
11#include "mergeutil_p.h"
12#include "notesutil_p.h"
13#include "platformutils_p.h"
14#include "stopoverutil_p.h"
15
16#include <QDateTime>
17#include <QDebug>
18
19using namespace KPublicTransport;
20
21namespace KPublicTransport {
22class StopoverPrivate : public QSharedData {
23public:
24 Disruption::Effect disruptionEffect = Disruption::NormalService;
25 QDateTime scheduledArrivalTime;
26 QDateTime expectedArrivalTime;
27 QDateTime scheduledDepartureTime;
28 QDateTime expectedDepartureTime;
29 QString scheduledPlatform;
30 QString expectedPlatform;
31 Route route;
32 Location stopPoint;
33 QStringList notes;
34 std::vector<LoadInfo> loadInformation;
35 Vehicle vehicleLayout;
36 Platform platformLayout;
37};
38}
39
40KPUBLICTRANSPORT_MAKE_GADGET(Stopover)
41KPUBLICTRANSPORT_MAKE_PROPERTY(Stopover, QDateTime, scheduledArrivalTime, setScheduledArrivalTime)
42KPUBLICTRANSPORT_MAKE_PROPERTY(Stopover, QDateTime, expectedArrivalTime, setExpectedArrivalTime)
43KPUBLICTRANSPORT_MAKE_PROPERTY(Stopover, QDateTime, scheduledDepartureTime, setScheduledDepartureTime)
44KPUBLICTRANSPORT_MAKE_PROPERTY(Stopover, QDateTime, expectedDepartureTime, setExpectedDepartureTime)
45KPUBLICTRANSPORT_MAKE_PROPERTY(Stopover, Route, route, setRoute)
46KPUBLICTRANSPORT_MAKE_PROPERTY(Stopover, Location, stopPoint, setStopPoint)
47KPUBLICTRANSPORT_MAKE_PROPERTY(Stopover, Disruption::Effect, disruptionEffect, setDisruptionEffect)
48KPUBLICTRANSPORT_MAKE_PROPERTY(Stopover, QStringList, notes, setNotes)
49KPUBLICTRANSPORT_MAKE_PROPERTY(Stopover, Vehicle, vehicleLayout, setVehicleLayout)
50KPUBLICTRANSPORT_MAKE_PROPERTY(Stopover, Platform, platformLayout, setPlatformLayout)
51
53{
54 return d->expectedArrivalTime.isValid();
55}
56
57int Stopover::arrivalDelay() const
58{
60 return d->scheduledArrivalTime.secsTo(d->expectedArrivalTime) / 60;
61 }
62 return 0;
63}
64
66{
67 return d->expectedDepartureTime.isValid();
68}
69
71{
73 return d->scheduledDepartureTime.secsTo(d->expectedDepartureTime) / 60;
74 }
75 return 0;
76}
77
79{
80 return d->scheduledPlatform;
81}
82
83void Stopover::setScheduledPlatform(const QString &platform)
84{
85 d.detach();
86 d->scheduledPlatform = PlatformUtils::normalizePlatform(platform);
87}
88
90{
91 return d->expectedPlatform;
92}
93
94void Stopover::setExpectedPlatform(const QString &platform)
95{
96 d.detach();
97 d->expectedPlatform = PlatformUtils::normalizePlatform(platform);
98}
99
101{
102 return !d->expectedPlatform.isEmpty();
103}
104
105bool Stopover::platformChanged() const
106{
107 return PlatformUtils::platformChanged(d->scheduledPlatform, d->expectedPlatform);
108}
109
110void Stopover::addNote(const QString &note)
111{
112 const auto n = NotesUtil::normalizeNote(note);
113 const auto idx = NotesUtil::needsAdding(d->notes, n);
114 if (idx >= 0) {
115 d.detach();
116 NotesUtil::performAdd(d->notes, n, idx);
117 }
118}
119
120void Stopover::addNotes(const QStringList &notes)
121{
122 for (const auto &n : notes) {
123 addNote(n);
124 }
125}
126
127const std::vector<LoadInfo>& Stopover::loadInformation() const
128{
129 return d->loadInformation;
130}
131
132std::vector<LoadInfo>&& Stopover::takeLoadInformation()
133{
134 d.detach();
135 return std::move(d->loadInformation);
136}
137
138void Stopover::setLoadInformation(std::vector<LoadInfo> &&loadInfo)
139{
140 d.detach();
141 d->loadInformation = std::move(loadInfo);
142}
143
144QVariantList Stopover::loadInformationVariant() const
145{
146 QVariantList l;
147 l.reserve(d->loadInformation.size());
148 std::transform(d->loadInformation.begin(), d->loadInformation.end(), std::back_inserter(l), [](const auto &load) { return QVariant::fromValue(load); });
149 return l;
150}
151
152void Stopover::applyMetaData(bool download)
153{
154 auto line = d->route.line();
155 line.applyMetaData(stopPoint(), download);
156 d->route.setLine(line);
157}
158
159bool Stopover::isSame(const Stopover &lhs, const Stopover &rhs)
160{
161 // same time is mandatory
162 const auto departureTimeMatch = lhs.scheduledDepartureTime().isValid()
164 && MergeUtil::distance(lhs.scheduledDepartureTime(), rhs.scheduledDepartureTime()) < 60;
165 const auto arrivalTimeMatch = lhs.scheduledArrivalTime().isValid()
167 && MergeUtil::distance(lhs.scheduledArrivalTime(), rhs.scheduledArrivalTime()) < 60;
168 if (!departureTimeMatch && !arrivalTimeMatch) {
169 return false;
170 }
171
172 // same route would be sufficient, if that's not the case, look for other hints
173 // this might be the same below
174 if (Route::isSame(lhs.route(), rhs.route())) {
175 return true;
176 }
177
178 // different platform can't be the same train
179 if (!lhs.scheduledPlatform().isEmpty() && !rhs.scheduledPlatform().isEmpty() && lhs.scheduledPlatform() != rhs.scheduledPlatform()) {
180 return false;
181 }
182
183 // same destination and departure time is likely the same route after all
184 // TODO we should check for conflicting line names or train types here maybe?
185 return (!lhs.route().destination().isEmpty() && !rhs.route().destination().isEmpty() && Location::isSame(lhs.route().destination(), rhs.route().destination()))
187}
188
190{
191 auto stopover = lhs;
192
193 using namespace MergeUtil;
194 stopover.setScheduledDepartureTime(mergeDateTimeEqual(lhs.scheduledDepartureTime(), rhs.scheduledDepartureTime()));
195 stopover.setExpectedDepartureTime(mergeDateTimeMax(lhs.expectedDepartureTime(), rhs.expectedDepartureTime()));
196 stopover.setScheduledArrivalTime(mergeDateTimeEqual(lhs.scheduledArrivalTime(), rhs.scheduledArrivalTime()));
197 stopover.setExpectedArrivalTime(mergeDateTimeMax(lhs.expectedArrivalTime(), rhs.expectedArrivalTime()));
198
199 if (stopover.scheduledPlatform().isEmpty() && !rhs.scheduledPlatform().isEmpty()) {
200 stopover.setScheduledPlatform(rhs.scheduledPlatform());
201 }
202 if (!stopover.hasExpectedPlatform() && rhs.hasExpectedPlatform()) {
203 stopover.setExpectedPlatform(rhs.expectedPlatform());
204 }
205
206 stopover.setRoute(Route::merge(lhs.route(), rhs.route()));
207 stopover.setStopPoint(Location::merge(lhs.stopPoint(), rhs.stopPoint()));
208 stopover.setDisruptionEffect(std::max(lhs.disruptionEffect(), rhs.disruptionEffect()));
209 stopover.setNotes(NotesUtil::mergeNotes(lhs.notes(), rhs.notes()));
210 stopover.d->loadInformation = LoadUtil::merge(lhs.d->loadInformation, rhs.d->loadInformation);
211 stopover.d->vehicleLayout = Vehicle::merge(lhs.d->vehicleLayout, rhs.d->vehicleLayout);
212 stopover.d->platformLayout = Platform::merge(lhs.d->platformLayout, rhs.d->platformLayout);
213 return stopover;
214}
215
217{
218 auto obj = Json::toJson(stopover);
219 const auto routeObj = Route::toJson(stopover.route());
220 if (!routeObj.empty()) {
221 obj.insert(QLatin1String("route"), routeObj);
222 }
223 const auto locObj = Location::toJson(stopover.stopPoint());
224 if (!locObj.empty()) {
225 obj.insert(QLatin1String("stopPoint"), locObj);
226 }
227 if (!stopover.loadInformation().empty()) {
228 obj.insert(QLatin1String("load"), LoadInfo::toJson(stopover.loadInformation()));
229 }
230 if (!stopover.vehicleLayout().isEmpty()) {
231 obj.insert(QLatin1String("vehicleLayout"), Vehicle::toJson(stopover.vehicleLayout()));
232 }
233 if (!stopover.platformLayout().isEmpty()) {
234 obj.insert(QLatin1String("platformLayout"), Platform::toJson(stopover.platformLayout()));
235 }
236
237 if (obj.size() == 1) { // only the disruption enum, ie. this is an empty object
238 return {};
239 }
240 return obj;
241}
242
243QJsonArray Stopover::toJson(const std::vector<Stopover> &deps)
244{
245 return Json::toJson(deps);
246}
247
249{
250 auto stopover = Json::fromJson<Stopover>(obj);
251 stopover.setRoute(Route::fromJson(obj.value(QLatin1String("route")).toObject()));
252 stopover.setStopPoint(Location::fromJson(obj.value(QLatin1String("stopPoint")).toObject()));
253 stopover.setLoadInformation(LoadInfo::fromJson(obj.value(QLatin1String("load")).toArray()));
254 stopover.setVehicleLayout(Vehicle::fromJson(obj.value(QLatin1String("vehicleLayout")).toObject()));
255 stopover.setPlatformLayout(Platform::fromJson(obj.value(QLatin1String("platformLayout")).toObject()));
256 stopover.applyMetaData(false);
257 return stopover;
258}
259
260std::vector<Stopover> Stopover::fromJson(const QJsonArray &array)
261{
262 return Json::fromJson<Stopover>(array);
263}
264
265#include "moc_stopover.cpp"
static QJsonObject toJson(const LoadInfo &info)
Serializes one load information object to JSON.
Definition load.cpp:26
static LoadInfo fromJson(const QJsonObject &obj)
Deserialize an object from JSON.
Definition load.cpp:36
static Location fromJson(const QJsonObject &obj)
Deserialize a Location object from JSON.
Definition location.cpp:486
static bool isSameName(const QString &lhs, const QString &rhs)
Checks if two location names refer to the same location.
Definition location.cpp:322
static QJsonObject toJson(const Location &loc)
Serializes one Location object to JSON.
Definition location.cpp:445
static Location merge(const Location &lhs, const Location &rhs)
Merge two departure instances.
Definition location.cpp:369
bool isEmpty() const
Returns true if this is an default-constructed location object not specifying any location.
Definition location.cpp:76
static bool isSame(const Location &lhs, const Location &rhs)
Checks if to instances refer to the same location (which does not necessarily mean they are exactly e...
Definition location.cpp:263
Information about the layout of a station platform.
Definition platform.h:45
static Platform fromJson(const QJsonObject &obj)
Deserialize an object from JSON.
Definition platform.cpp:113
bool isEmpty() const
Returns true if this object contains no information beyond default values.
Definition platform.cpp:66
static Platform merge(const Platform &lhs, const Platform &rhs)
Merge two platform instances.
Definition platform.cpp:93
static QJsonObject toJson(const Platform &platform)
Serializes one platform object to JSON.
Definition platform.cpp:99
A route of a public transport line.
Definition line.h:125
KPublicTransport::Location destination
Destination of the route.
Definition line.h:139
QString direction
Direction of the route.
Definition line.h:134
static bool isSame(const Route &lhs, const Route &rhs)
Checks if to instances refer to the same route (which does not necessarily mean they are exactly equa...
Definition line.cpp:191
static QJsonObject toJson(const Route &r)
Serializes one object to JSON.
Definition line.cpp:211
static Route merge(const Route &lhs, const Route &rhs)
Merge two Route instances.
Definition line.cpp:201
static Route fromJson(const QJsonObject &obj)
Deserialize an object from JSON.
Definition line.cpp:224
Information about an arrival and/or departure of a vehicle at a stop area.
Definition stopover.h:26
static Stopover merge(const Stopover &lhs, const Stopover &rhs)
Merge two departure instances.
Definition stopover.cpp:189
KPublicTransport::Route route
The departing route.
Definition stopover.h:61
bool platformChanged
true if we have real-time platform information and the platform changed.
Definition stopover.h:58
void applyMetaData(bool download)
Augment line meta data.
Definition stopover.cpp:152
bool hasExpectedDepartureTime
true if this has real-time data.
Definition stopover.h:47
int arrivalDelay
Difference to schedule in minutes.
Definition stopover.h:38
QDateTime expectedDepartureTime
Actual departure time, if available.
Definition stopover.h:45
QStringList notes
General human-readable notes on this service, e.g.
Definition stopover.h:69
QString expectedPlatform
Actual departure platform, in case real-time information are available.
Definition stopover.h:54
static QJsonObject toJson(const Stopover &stopover)
Serializes one object to JSON.
Definition stopover.cpp:216
static bool isSame(const Stopover &lhs, const Stopover &rhs)
Checks if to instances refer to the same departure (which does not necessarily mean they are exactly ...
Definition stopover.cpp:159
KPublicTransport::Location stopPoint
The stop point of this departure.
Definition stopover.h:64
void setLoadInformation(std::vector< LoadInfo > &&loadInfo)
Set the expected vehicle load information for departing from this stopover.
Definition stopover.cpp:138
QDateTime expectedArrivalTime
Actual arrival time, if available.
Definition stopover.h:34
std::vector< LoadInfo > && takeLoadInformation()
Moves the load information out of this object for modification.
Definition stopover.cpp:132
QDateTime scheduledArrivalTime
Planned arrival time.
Definition stopover.h:30
bool hasExpectedArrivalTime
true if this has real-time data.
Definition stopover.h:36
bool hasExpectedPlatform
true if real-time platform information are available.
Definition stopover.h:56
static Stopover fromJson(const QJsonObject &obj)
Deserialize an object from JSON.
Definition stopover.cpp:248
QVariantList loadInformation
Vehicle load information for departure from this stopover Contains LoadInfo objects for consumption b...
Definition stopover.h:74
KPublicTransport::Disruption::Effect disruptionEffect
Disruption effect on this arrival or departure, if any.
Definition stopover.h:67
void addNote(const QString &note)
Adds a note.
Definition stopover.cpp:110
int departureDelay
Difference to schedule in minutes.
Definition stopover.h:49
KPublicTransport::Vehicle vehicleLayout
Vehicle coach layout information at this stopover.
Definition stopover.h:77
QDateTime scheduledDepartureTime
Planned departure time.
Definition stopover.h:41
KPublicTransport::Platform platformLayout
Platform layout information.
Definition stopover.h:79
QString scheduledPlatform
Planned departure platform.
Definition stopover.h:52
Information about the vehicle used on a journey.
Definition vehicle.h:144
static QJsonObject toJson(const Vehicle &vehicle)
Serializes one vehicle object to JSON.
Definition vehicle.cpp:204
static Vehicle fromJson(const QJsonObject &obj)
Deserialize an object from JSON.
Definition vehicle.cpp:218
bool isEmpty() const
Returns true if this object contains no information beyond the default values.
Definition vehicle.cpp:118
static Vehicle merge(const Vehicle &lhs, const Vehicle &rhs)
Merge two Vehicle instances.
Definition vehicle.cpp:182
Effect
Disruption effects, numerical sorted so that higher values imply more severe disruptions.
Definition disruption.h:25
Query operations and data types for accessing realtime public transport information from online servi...
bool isValid() const const
QJsonValue value(QLatin1StringView key) const const
bool isEmpty() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:13:06 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.