KPublicTransport

line.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 "line.h"
8#include "lineutil_p.h"
9#include "datatypes_p.h"
10#include "json_p.h"
11#include "mergeutil_p.h"
12#include "assetrepository_p.h"
13
14#include "knowledgedb/linemetadata.h"
15
16#include <QColor>
17#include <QDebug>
18#include <QUrl>
19
20using namespace KPublicTransport;
21
22namespace KPublicTransport {
23class LinePrivate : public QSharedData {
24public:
25 Line::Mode mode = Line::Unknown;
26 QString modeString;
27 QString name;
28 QColor color;
29 QColor textColor;
30 LineMetaData metaData;
31 QString operatorName;
32};
33
34class RoutePrivate : public QSharedData {
35public:
36 Line line;
37 QString direction;
38 Location destination;
39 QString name;
40};
41
42}
43
44KPUBLICTRANSPORT_MAKE_GADGET(Line)
45KPUBLICTRANSPORT_MAKE_PROPERTY(Line, QString, name, setName)
46KPUBLICTRANSPORT_MAKE_PROPERTY(Line, QColor, textColor, setTextColor)
47KPUBLICTRANSPORT_MAKE_PROPERTY(Line, Line::Mode, mode, setMode)
48KPUBLICTRANSPORT_MAKE_PROPERTY(Line, QString, modeString, setModeString)
49KPUBLICTRANSPORT_MAKE_PROPERTY(Line, QString, operatorName, setOperatorName)
50
51QColor Line::color() const
52{
53 return d->metaData.color().isValid() ? d->metaData.color() : d->color;
54}
55
56void Line::setColor(const QColor &value)
57{
58 d.detach();
59 d->color = value;
60}
61
62bool Line::hasColor() const
63{
64 return d->color.isValid() || d->metaData.color().isValid();
65}
66
67bool Line::hasTextColor() const
68{
69 return d->textColor.isValid();
70}
71
72QString Line::logo() const
73{
74 return AssetRepository::localFile(d->metaData.logoUrl()).toString(QUrl::FullyEncoded);
75}
76
77bool Line::hasLogo() const
78{
79 return !logo().isEmpty();
80}
81
83{
84 return AssetRepository::localFile(d->metaData.modeLogoUrl()).toString(QUrl::FullyEncoded);
85}
86
87bool Line::hasModeLogo() const
88{
89 return !modeLogo().isEmpty();
90}
91
92bool Line::isSame(const Line &lhs, const Line &rhs)
93{
94 if (!LineUtil::isCompatibleMode(lhs.mode(), rhs.mode())) {
95 return false;
96 }
97
98 // ### not really the most efficient way of doing this...
99 using namespace LineUtil;
100 return isSameLineNameFuzzy(lhs.name(), rhs.name())
101 || isSameLineNameFuzzy(QString(lhs.modeString() + QLatin1Char(' ') + lhs.name()).trimmed(), rhs.name())
102 || isSameLineNameFuzzy(lhs.name(), QString(rhs.modeString() + QLatin1Char(' ') + rhs.name()).trimmed())
103 || isSameLineNameFuzzy(QString(lhs.modeString() + QLatin1Char(' ') + lhs.name()).trimmed(), QString(rhs.modeString() + QLatin1Char(' ') + rhs.name()).trimmed());
104}
105
106static QColor mergeColor(const QColor &lhs, const QColor &rhs)
107{
108 if (!lhs.isValid()) {
109 return rhs;
110 }
111 if (!rhs.isValid()) {
112 return lhs;
113 }
114
115 const auto lh = lhs.hue(), ls = lhs.saturation(), lv = lhs.value();
116 const auto rh = rhs.hue(), rs = rhs.saturation(), rv = rhs.value();
117 return std::tie(ls, lv, lh) < std::tie(rs, rv, rh) ? rhs : lhs;
118}
119
120Line Line::merge(const Line &lhs, const Line &rhs)
121{
122 Line l(lhs);
123
124 l.setModeString(MergeUtil::mergeString(lhs.modeString(), rhs.modeString()));
125 l.setName(MergeUtil::mergeString(lhs.name(), rhs.name()));
127 l.setName(QStringView(l.name()).mid(l.modeString().size()).trimmed().toString());
128 }
129
130 l.setColor(mergeColor(lhs.color(), rhs.color()));
131 if (!l.textColor().isValid() && rhs.textColor().isValid()) {
132 l.setTextColor(rhs.textColor());
133 }
134 if (l.mode() == Unknown || (l.mode() == Train && rhs.mode() != Unknown)) {
135 l.setMode(rhs.mode());
136 }
137
138 l.setOperatorName(MergeUtil::mergeString(lhs.operatorName(), rhs.operatorName()));
139 return l;
140}
141
142void Line::applyMetaData(const Location &location, bool download)
143{
144 if (name().isEmpty() || !location.hasCoordinate()) {
145 return;
146 }
147
148 d->metaData = LineMetaData::find(location.latitude(), location.longitude(), name(), mode());
149
150 if (download && AssetRepository::instance()) {
151 AssetRepository::instance()->download(d->metaData.logoUrl());
152 AssetRepository::instance()->download(d->metaData.modeLogoUrl());
153 }
154}
155
157{
158 auto obj = Json::toJson(l);
159 if (l.mode() == Unknown) {
160 obj.remove(QLatin1String("mode"));
161 }
162 return obj;
163}
164
166{
167 auto l = Json::fromJson<Line>(obj);
168 return l;
169}
170
171
172KPUBLICTRANSPORT_MAKE_GADGET(Route)
173KPUBLICTRANSPORT_MAKE_PROPERTY(Route, Line, line, setLine)
174KPUBLICTRANSPORT_MAKE_PROPERTY(Route, Location, destination, setDestination)
175KPUBLICTRANSPORT_MAKE_PROPERTY(Route, QString, name, setName)
176
178{
179 if (d->direction.isEmpty() && !d->destination.isEmpty()) {
180 return d->destination.name();
181 }
182 return d->direction;
183}
184
185void Route::setDirection(const QString &value)
186{
187 d.detach();
188 d->direction = value;
189}
190
191bool Route::isSame(const Route &lhs, const Route &rhs)
192{
193 const auto matchingDirection = (!lhs.destination().isEmpty() && !rhs.destination().isEmpty() && Location::isSame(lhs.destination(), rhs.destination()))
195
196 const auto matchingRouteName = lhs.name().size() < 3 || rhs.name().size() < 3 || lhs.name().endsWith(rhs.name()) || rhs.name().endsWith(lhs.name());
197
198 return matchingDirection && matchingRouteName && Line::isSame(lhs.line(), rhs.line());
199}
200
201Route Route::merge(const Route &lhs, const Route &rhs)
202{
203 Route r(lhs);
204 r.setLine(Line::merge(lhs.line(), rhs.line()));
205 r.setName(MergeUtil::mergeString(lhs.name(), rhs.name()));
206 r.setDirection(MergeUtil::mergeString(lhs.direction(), rhs.direction()));
207 r.setDestination(Location::merge(lhs.destination(), rhs.destination()));
208 return r;
209}
210
212{
213 auto obj = Json::toJson(r);
214 const auto lineObj = Line::toJson(r.line());
215 if (!lineObj.empty()) {
216 obj.insert(QLatin1String("line"), lineObj);
217 }
218 if (!r.destination().isEmpty()) {
219 obj.insert(QLatin1String("destination"), Location::toJson(r.destination()));
220 }
221 return obj;
222}
223
225{
226 auto r = Json::fromJson<Route>(obj);
227 r.setLine(Line::fromJson(obj.value(QLatin1String("line")).toObject()));
228 r.setDestination(Location::fromJson(obj.value(QLatin1String("destination")).toObject()));
229 return r;
230}
231
232#include "moc_line.cpp"
Static information about a public transport line.
static LineMetaData find(double latitude, double longitude, const QString &name, Line::Mode mode)
Attempts to find information about a line with the given name and a stop at the given coordinates.
A public transport line.
Definition line.h:20
KPublicTransport::Line::Mode mode
Type of transport.
Definition line.h:60
bool hasTextColor
true if a text color is set.
Definition line.h:58
static Line fromJson(const QJsonObject &obj)
Deserialize an object from JSON.
Definition line.cpp:165
QString name
Name of the line.
Definition line.h:50
QString modeString
Human readable representation of the type of transport.
Definition line.h:65
bool hasLogo
true if the line has a logo.
Definition line.h:74
static Line merge(const Line &lhs, const Line &rhs)
Merge two Line instances.
Definition line.cpp:120
bool hasColor
true if a line color is set.
Definition line.h:54
QString operatorName
Name of the operator running this line.
Definition line.h:88
QColor color
Color of the line.
Definition line.h:52
void applyMetaData(const Location &location, bool download)
Look up line meta data and apply what is found.
Definition line.cpp:142
QString logo
Path of a local file containing the line logo.
Definition line.h:72
QColor textColor
Text color to use on top of the line color.
Definition line.h:56
QString modeLogo
Path of a local file containing the line mode logo.
Definition line.h:83
static QJsonObject toJson(const Line &l)
Serializes one object to JSON.
Definition line.cpp:156
Mode
Mode of transportation.
Definition line.h:27
bool hasModeLogo
true if the line has a mode logo.
Definition line.h:85
static bool isSame(const Line &lhs, const Line &rhs)
Checks if to instances refer to the same line (which does not necessarily mean they are exactly equal...
Definition line.cpp:92
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
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
QString name
Name of the route.
Definition line.h:147
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
KPublicTransport::Line line
Line this route belongs to.
Definition line.h:128
static Route fromJson(const QJsonObject &obj)
Deserialize an object from JSON.
Definition line.cpp:224
Query operations and data types for accessing realtime public transport information from online servi...
int hue() const const
bool isValid() const const
int saturation() const const
int value() const const
QJsonValue value(QLatin1StringView key) const const
bool endsWith(QChar c, Qt::CaseSensitivity cs) const const
bool isEmpty() const const
qsizetype size() const const
bool startsWith(QChar c, Qt::CaseSensitivity cs) const const
QString trimmed() const const
QStringView mid(qsizetype start, qsizetype length) const const
QString toString() const const
QStringView trimmed() const const
CaseInsensitive
FullyEncoded
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.