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
152const std::vector<KPublicTransport::Feature>& Stopover::features() const
153{
154 return d->vehicleLayout.features();
155}
156
157[[nodiscard]] std::vector<KPublicTransport::Feature>&& Stopover::takeFeatures()
158{
159 return d->vehicleLayout.takeFeatures();
160}
161
162void Stopover::setFeatures(std::vector<KPublicTransport::Feature> &&features)
163{
164 d.detach();
165 d->vehicleLayout.setFeatures(std::move(features));
166}
167
168void Stopover::applyMetaData(bool download)
169{
170 auto line = d->route.line();
171 line.applyMetaData(stopPoint(), download);
172 d->route.setLine(line);
173}
174
175bool Stopover::isSame(const Stopover &lhs, const Stopover &rhs)
176{
177 // same time is mandatory
178 const auto departureTimeMatch = lhs.scheduledDepartureTime().isValid()
180 && MergeUtil::distance(lhs.scheduledDepartureTime(), rhs.scheduledDepartureTime()) < 60;
181 const auto arrivalTimeMatch = lhs.scheduledArrivalTime().isValid()
183 && MergeUtil::distance(lhs.scheduledArrivalTime(), rhs.scheduledArrivalTime()) < 60;
184 if (!departureTimeMatch && !arrivalTimeMatch) {
185 return false;
186 }
187
188 // same route would be sufficient, if that's not the case, look for other hints
189 // this might be the same below
190 if (Route::isSame(lhs.route(), rhs.route())) {
191 return true;
192 }
193
194 // different platform can't be the same train
195 if (!lhs.scheduledPlatform().isEmpty() && !rhs.scheduledPlatform().isEmpty() && lhs.scheduledPlatform() != rhs.scheduledPlatform()) {
196 return false;
197 }
198
199 // same destination and departure time is likely the same route after all
200 // TODO we should check for conflicting line names or train types here maybe?
201 return (!lhs.route().destination().isEmpty() && !rhs.route().destination().isEmpty() && Location::isSame(lhs.route().destination(), rhs.route().destination()))
203}
204
206{
207 auto stopover = lhs;
208
209 using namespace MergeUtil;
210 stopover.setScheduledDepartureTime(mergeDateTimeEqual(lhs.scheduledDepartureTime(), rhs.scheduledDepartureTime()));
211 stopover.setExpectedDepartureTime(mergeDateTimeMax(lhs.expectedDepartureTime(), rhs.expectedDepartureTime()));
212 stopover.setScheduledArrivalTime(mergeDateTimeEqual(lhs.scheduledArrivalTime(), rhs.scheduledArrivalTime()));
213 stopover.setExpectedArrivalTime(mergeDateTimeMax(lhs.expectedArrivalTime(), rhs.expectedArrivalTime()));
214
215 if (stopover.scheduledPlatform().isEmpty() && !rhs.scheduledPlatform().isEmpty()) {
216 stopover.setScheduledPlatform(rhs.scheduledPlatform());
217 }
218 if (!stopover.hasExpectedPlatform() && rhs.hasExpectedPlatform()) {
219 stopover.setExpectedPlatform(rhs.expectedPlatform());
220 }
221
222 stopover.setRoute(Route::merge(lhs.route(), rhs.route()));
223 stopover.setStopPoint(Location::merge(lhs.stopPoint(), rhs.stopPoint()));
224 stopover.setDisruptionEffect(std::max(lhs.disruptionEffect(), rhs.disruptionEffect()));
225 stopover.setNotes(NotesUtil::mergeNotes(lhs.notes(), rhs.notes()));
226 stopover.d->loadInformation = LoadUtil::merge(lhs.d->loadInformation, rhs.d->loadInformation);
227 stopover.d->vehicleLayout = Vehicle::merge(lhs.d->vehicleLayout, rhs.d->vehicleLayout);
228 stopover.d->platformLayout = Platform::merge(lhs.d->platformLayout, rhs.d->platformLayout);
229 return stopover;
230}
231
233{
234 auto obj = Json::toJson(stopover);
235 const auto routeObj = Route::toJson(stopover.route());
236 if (!routeObj.empty()) {
237 obj.insert(QLatin1String("route"), routeObj);
238 }
239 const auto locObj = Location::toJson(stopover.stopPoint());
240 if (!locObj.empty()) {
241 obj.insert(QLatin1String("stopPoint"), locObj);
242 }
243 if (!stopover.loadInformation().empty()) {
244 obj.insert(QLatin1String("load"), LoadInfo::toJson(stopover.loadInformation()));
245 }
246 if (!stopover.vehicleLayout().isEmpty()) {
247 obj.insert(QLatin1String("vehicleLayout"), Vehicle::toJson(stopover.vehicleLayout()));
248 }
249 if (!stopover.platformLayout().isEmpty()) {
250 obj.insert(QLatin1String("platformLayout"), Platform::toJson(stopover.platformLayout()));
251 }
252
253 if (obj.size() == 1) { // only the disruption enum, ie. this is an empty object
254 return {};
255 }
256 return obj;
257}
258
259QJsonArray Stopover::toJson(const std::vector<Stopover> &deps)
260{
261 return Json::toJson(deps);
262}
263
265{
266 auto stopover = Json::fromJson<Stopover>(obj);
267 stopover.setRoute(Route::fromJson(obj.value(QLatin1String("route")).toObject()));
268 stopover.setStopPoint(Location::fromJson(obj.value(QLatin1String("stopPoint")).toObject()));
269 stopover.setLoadInformation(LoadInfo::fromJson(obj.value(QLatin1String("load")).toArray()));
270 stopover.setVehicleLayout(Vehicle::fromJson(obj.value(QLatin1String("vehicleLayout")).toObject()));
271 stopover.setPlatformLayout(Platform::fromJson(obj.value(QLatin1String("platformLayout")).toObject()));
272 stopover.applyMetaData(false);
273 return stopover;
274}
275
276std::vector<Stopover> Stopover::fromJson(const QJsonArray &array)
277{
278 return Json::fromJson<Stopover>(array);
279}
280
281#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:550
static bool isSameName(const QString &lhs, const QString &rhs)
Checks if two location names refer to the same location.
Definition location.cpp:364
static QJsonObject toJson(const Location &loc)
Serializes one Location object to JSON.
Definition location.cpp:488
static Location merge(const Location &lhs, const Location &rhs)
Merge two departure instances.
Definition location.cpp:411
bool isEmpty() const
Returns true if this is an default-constructed location object not specifying any location.
Definition location.cpp:108
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:305
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:146
KPublicTransport::Location destination
Destination of the route.
Definition line.h:160
QString direction
Direction of the route.
Definition line.h:155
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:250
static QJsonObject toJson(const Route &r)
Serializes one object to JSON.
Definition line.cpp:270
static Route merge(const Route &lhs, const Route &rhs)
Merge two Route instances.
Definition line.cpp:260
static Route fromJson(const QJsonObject &obj)
Deserialize an object from JSON.
Definition line.cpp:283
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:205
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:168
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:232
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:175
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:264
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
std::vector< KPublicTransport::Feature > features
Features of the vehicle used on this section.
Definition stopover.h:85
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:186
static QJsonObject toJson(const Vehicle &vehicle)
Serializes one vehicle object to JSON.
Definition vehicle.cpp:340
static Vehicle fromJson(const QJsonObject &obj)
Deserialize an object from JSON.
Definition vehicle.cpp:357
bool isEmpty() const
Returns true if this object contains no information beyond the default values.
Definition vehicle.cpp:252
static Vehicle merge(const Vehicle &lhs, const Vehicle &rhs)
Merge two Vehicle instances.
Definition vehicle.cpp:316
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 Fri Oct 11 2024 12:12:54 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.