File indexing completed on 2024-05-12 04:42:45
0001 /* 0002 SPDX-FileCopyrightText: 2021 Volker Krause <vkrause@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "path.h" 0008 #include "datatypes_p.h" 0009 #include "json_p.h" 0010 #include "../geo/geojson_p.h" 0011 #include "location.h" 0012 0013 #include <QLineF> 0014 0015 using namespace KPublicTransport; 0016 0017 namespace KPublicTransport { 0018 class PathSectionPrivate : public QSharedData { 0019 public: 0020 QPolygonF path; 0021 QString description; 0022 int floorLevelChange = 0; 0023 PathSection::Maneuver maneuver = PathSection::Move; 0024 }; 0025 } 0026 0027 KPUBLICTRANSPORT_MAKE_GADGET(PathSection) 0028 KPUBLICTRANSPORT_MAKE_PROPERTY(PathSection, QPolygonF, path, setPath) 0029 KPUBLICTRANSPORT_MAKE_PROPERTY(PathSection, QString, description, setDescription) 0030 KPUBLICTRANSPORT_MAKE_PROPERTY(PathSection, int, floorLevelChange, setFloorLevelChange) 0031 KPUBLICTRANSPORT_MAKE_PROPERTY(PathSection, PathSection::Maneuver, maneuver, setManeuver) 0032 0033 int PathSection::distance() const 0034 { 0035 if (d->path.size() < 2) { 0036 return 0; 0037 } 0038 0039 float dist = 0; 0040 for (auto it = d->path.begin(); it != std::prev(d->path.end()); ++it) { 0041 const auto nextIt = std::next(it); 0042 dist += Location::distance((*it).y(), (*it).x(), (*nextIt).y(), (*nextIt).x()); 0043 } 0044 return dist; 0045 } 0046 0047 int PathSection::direction() const 0048 { 0049 const auto p1 = startPoint(); 0050 const auto p2 = endPoint(); 0051 if (d->path.size() < 2 || p1 == p2) { 0052 return -1; 0053 } 0054 return static_cast<int>(450 - QLineF(p1.x(), -p1.y(), p2.x(), -p2.y()).angle()) % 360; 0055 } 0056 0057 QPointF PathSection::startPoint() const 0058 { 0059 return d->path.empty() ? QPointF() : d->path.constFirst(); 0060 } 0061 0062 QPointF PathSection::endPoint() const 0063 { 0064 return d->path.empty() ? QPointF() : d->path.constLast(); 0065 } 0066 0067 QJsonObject PathSection::toJson(const PathSection §ion) 0068 { 0069 auto obj = Json::toJson(section); 0070 if (!section.path().empty()) { 0071 obj.insert(QLatin1String("path"), GeoJson::writeLineString(section.path())); 0072 } 0073 if (section.maneuver() == PathSection::Move) { 0074 obj.remove(QLatin1String("maneuver")); 0075 } 0076 if (section.floorLevelChange() == 0) { 0077 obj.remove(QLatin1String("floorLevelChange")); 0078 } 0079 return obj; 0080 } 0081 0082 QJsonArray PathSection::toJson(const std::vector<PathSection> §ions) 0083 { 0084 return Json::toJson(sections); 0085 } 0086 0087 PathSection PathSection::fromJson(const QJsonObject &obj) 0088 { 0089 auto section = Json::fromJson<PathSection>(obj); 0090 section.setPath(GeoJson::readLineString(obj.value(QLatin1String("path")).toObject())); 0091 return section; 0092 } 0093 0094 std::vector<PathSection> PathSection::fromJson(const QJsonArray &array) 0095 { 0096 return Json::fromJson<PathSection>(array); 0097 } 0098 0099 0100 namespace KPublicTransport { 0101 class PathPrivate : public QSharedData { 0102 public: 0103 std::vector<PathSection> sections; 0104 }; 0105 } 0106 0107 KPUBLICTRANSPORT_MAKE_GADGET(Path) 0108 0109 bool Path::isEmpty() const 0110 { 0111 return d->sections.empty(); 0112 } 0113 0114 const std::vector<PathSection>& Path::sections() const 0115 { 0116 return d->sections; 0117 } 0118 0119 std::vector<PathSection>&& Path::takeSections() 0120 { 0121 d.detach(); 0122 return std::move(d->sections); 0123 } 0124 0125 void Path::setSections(std::vector<PathSection> &§ions) 0126 { 0127 d.detach(); 0128 d->sections = std::move(sections); 0129 } 0130 0131 int Path::distance() const 0132 { 0133 return std::accumulate(d->sections.begin(), d->sections.end(), 0, [](int d, const auto &sec) { return d + sec.distance(); }); 0134 } 0135 0136 QPointF Path::startPoint() const 0137 { 0138 return isEmpty() ? QPointF() : d->sections.front().startPoint(); 0139 } 0140 0141 QPointF Path::endPoint() const 0142 { 0143 return isEmpty() ? QPointF() : d->sections.front().endPoint(); 0144 } 0145 0146 QJsonObject Path::toJson(const Path &path) 0147 { 0148 auto obj = Json::toJson(path); 0149 obj.insert(QLatin1String("sections"), PathSection::toJson(path.sections())); 0150 return obj; 0151 } 0152 0153 Path Path::fromJson(const QJsonObject &obj) 0154 { 0155 auto path = Json::fromJson<Path>(obj); 0156 path.setSections(PathSection::fromJson(obj.value(QLatin1String("sections")).toArray())); 0157 return path; 0158 } 0159 0160 int Path::sectionCount() const 0161 { 0162 return d->sections.size(); 0163 } 0164 0165 #include "moc_path.cpp"