KPublicTransport

path.cpp
1/*
2 SPDX-FileCopyrightText: 2021 Volker Krause <vkrause@kde.org>
3
4 SPDX-License-Identifier: LGPL-2.0-or-later
5*/
6
7#include "path.h"
8#include "datatypes_p.h"
9#include "json_p.h"
10#include "../geo/geojson_p.h"
11#include "location.h"
12
13#include <QLineF>
14
15#include <limits>
16
17using namespace Qt::Literals::StringLiterals;
18using namespace KPublicTransport;
19
20namespace KPublicTransport {
21class PathSectionPrivate : public QSharedData {
22public:
23 QPolygonF path;
24 QString description;
25 int startFloorLevel = std::numeric_limits<int>::lowest();
26 int floorLevelChange = 0;
28};
29}
30
31KPUBLICTRANSPORT_MAKE_GADGET(PathSection)
32KPUBLICTRANSPORT_MAKE_PROPERTY(PathSection, QPolygonF, path, setPath)
33KPUBLICTRANSPORT_MAKE_PROPERTY(PathSection, QString, description, setDescription)
34KPUBLICTRANSPORT_MAKE_PROPERTY(PathSection, int, startFloorLevel, setStartFloorLevel)
35KPUBLICTRANSPORT_MAKE_PROPERTY(PathSection, int, floorLevelChange, setFloorLevelChange)
36KPUBLICTRANSPORT_MAKE_PROPERTY(PathSection, PathSection::Maneuver, maneuver, setManeuver)
37
38int PathSection::distance() const
39{
40 if (d->path.size() < 2) {
41 return 0;
42 }
43
44 double dist = 0;
45 for (auto it = d->path.begin(); it != std::prev(d->path.end()); ++it) {
46 const auto nextIt = std::next(it);
47 dist += Location::distance((*it).y(), (*it).x(), (*nextIt).y(), (*nextIt).x());
48 }
49 return (int)std::round(dist);
50}
51
53{
54 const auto p1 = startPoint();
55 const auto p2 = endPoint();
56 if (d->path.size() < 2 || p1 == p2) {
57 return -1;
58 }
59 return static_cast<int>(450 - QLineF(p1.x(), -p1.y(), p2.x(), -p2.y()).angle()) % 360;
60}
61
63{
64 return d->startFloorLevel > std::numeric_limits<int>::lowest() && d->startFloorLevel < std::numeric_limits<int>::max();
65}
66
68{
69 return d->path.empty() ? QPointF() : d->path.constFirst();
70}
71
73{
74 return d->path.empty() ? QPointF() : d->path.constLast();
75}
76
78{
79 switch (maneuver) {
81 return u"qrc:///org.kde.kpublictransport/assets/images/transport-mode-walk.svg"_s;
83 return u"qrc:///org.kde.kpublictransport/assets/images/path-elevator.svg"_s;
85 return u"qrc:///org.kde.kpublictransport/assets/images/path-escalator.svg"_s;
87 return u"qrc:///org.kde.kpublictransport/assets/images/path-stairs.svg"_s;
88 }
89
90 return {};
91}
92
94{
96}
97
99{
100 auto obj = Json::toJson(section);
101 if (!section.path().empty()) {
102 obj.insert("path"_L1, GeoJson::writeLineString(section.path()));
103 }
104 if (section.maneuver() == PathSection::Move) {
105 obj.remove("maneuver"_L1);
106 }
107 if (!section.hasStartFloorLevel()) {
108 obj.remove("startFloorLevel"_L1);
109 }
110 if (section.floorLevelChange() == 0) {
111 obj.remove("floorLevelChange"_L1);
112 }
113 return obj;
114}
115
116QJsonArray PathSection::toJson(const std::vector<PathSection> &sections)
117{
118 return Json::toJson(sections);
119}
120
122{
123 auto section = Json::fromJson<PathSection>(obj);
124 section.setPath(GeoJson::readLineString(obj.value("path"_L1).toObject()));
125 return section;
126}
127
128std::vector<PathSection> PathSection::fromJson(const QJsonArray &array)
129{
130 return Json::fromJson<PathSection>(array);
131}
132
133
134namespace KPublicTransport {
135class PathPrivate : public QSharedData {
136public:
137 std::vector<PathSection> sections;
138};
139}
140
141KPUBLICTRANSPORT_MAKE_GADGET(Path)
142
143bool Path::isEmpty() const
144{
145 return d->sections.empty();
146}
147
148const std::vector<PathSection>& Path::sections() const
149{
150 return d->sections;
151}
152
153std::vector<PathSection>&& Path::takeSections()
154{
155 d.detach();
156 return std::move(d->sections);
157}
158
159void Path::setSections(std::vector<PathSection> &&sections)
160{
161 d.detach();
162 d->sections = std::move(sections);
163}
164
165int Path::distance() const
166{
167 return std::accumulate(d->sections.begin(), d->sections.end(), 0, [](int d, const auto &sec) { return d + sec.distance(); });
168}
169
171{
172 return isEmpty() ? QPointF() : d->sections.front().startPoint();
173}
174
176{
177 return isEmpty() ? QPointF() : d->sections.back().endPoint();
178}
179
181{
182 auto obj = Json::toJson(path);
183 obj.insert("sections"_L1, PathSection::toJson(path.sections()));
184 return obj;
185}
186
188{
189 auto path = Json::fromJson<Path>(obj);
190 path.setSections(PathSection::fromJson(obj.value("sections"_L1).toArray()));
191 return path;
192}
193
194int Path::sectionCount() const
195{
196 return (int)d->sections.size();
197}
198
199#include "moc_path.cpp"
A section of a Path.
Definition path.h:25
static Q_INVOKABLE QString maneuverIconName(KPublicTransport::PathSection::Maneuver maneuver)
An icon representing maneuver.
Definition path.cpp:77
Maneuver
Maneuver associated with a path section.
Definition path.h:56
@ Elevator
Take an elevator.
Definition path.h:59
@ Escalator
Take an escalator.
Definition path.h:60
@ Move
Move/drive with the default mode of transport for this path.
Definition path.h:57
@ Stairs
Walk up or down stairs.
Definition path.h:58
QString iconName
An icon representing the maneuver.
Definition path.h:69
bool hasStartFloorLevel
Indicates an absolute start floor level is known.
Definition path.h:47
QPolygonF path
The geo coordinate poly-line followed by this path section.
Definition path.h:28
static QJsonObject toJson(const PathSection &section)
Serializes one path section section to JSON.
Definition path.cpp:98
QPointF startPoint
First point on the path of this section.
Definition path.h:35
QPointF endPoint
Last point on the path of this section.
Definition path.h:37
int floorLevelChange
Floor level change during this path section.
Definition path.h:52
static PathSection fromJson(const QJsonObject &obj)
Deserialize an object from JSON.
Definition path.cpp:121
int direction
The overall direction of this section in degree.
Definition path.h:42
Maneuver maneuver
Movement maneuver for this path section.
Definition path.h:64
A path followed by any kind of location change.
Definition path.h:113
std::vector< PathSection > && takeSections()
Moves the path sections out of this object.
Definition path.cpp:153
QPointF endPoint
Last point on this path.
Definition path.h:127
int sectionCount
Number of path sections for QML.
Definition path.h:119
int distance
The length of this path in meters.
Definition path.h:122
bool isEmpty() const
Returns true if this is an empty/not-set path.
Definition path.cpp:143
QPointF startPoint
First point on this path.
Definition path.h:125
static Path fromJson(const QJsonObject &obj)
Deserialize an object from JSON.
Definition path.cpp:187
void setSections(std::vector< PathSection > &&sections)
Sets the path sections.
Definition path.cpp:159
static QJsonObject toJson(const Path &path)
Serializes one path object to JSON.
Definition path.cpp:180
std::vector< KPublicTransport::PathSection > sections
Access to path sections for QML.
Definition path.h:117
Query operations and data types for accessing realtime public transport information from online servi...
QJsonValue value(QLatin1StringView key) const const
QJsonArray toArray() const const
QJsonObject toObject() const const
qreal angle() const const
bool empty() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Mon Nov 18 2024 12:07:52 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.