Marble

GeoDataRelation.cpp
1// SPDX-License-Identifier: LGPL-2.1-or-later
2//
3// SPDX-FileCopyrightText: 2017 Dennis Nienhüser <nienhueser@kde.org>
4
5#include "GeoDataRelation.h"
6
7#include "GeoDataTypes.h"
8#include "OsmPlacemarkData.h"
9
10#include <QSet>
11
12namespace Marble
13{
14
15class GeoDataRelationPrivate
16{
17public:
19 OsmPlacemarkData m_osmData;
20 QSet<qint64> m_memberIds;
21
22 mutable GeoDataRelation::RelationType m_relationType = GeoDataRelation::UnknownType;
23 mutable bool m_relationTypeDirty = true;
25};
26
27QHash<QString, GeoDataRelation::RelationType> GeoDataRelationPrivate::s_relationTypes;
28
29GeoDataRelation::GeoDataRelation() :
30 GeoDataFeature(),
31 d_ptr(new GeoDataRelationPrivate)
32{
33 // nothing to do
34}
35
36GeoDataRelation::~GeoDataRelation()
37{
38 delete d_ptr;
39}
40
41GeoDataRelation::GeoDataRelation(const GeoDataRelation &other) :
42 GeoDataFeature(other),
43 d_ptr(new GeoDataRelationPrivate)
44{
45 Q_D(GeoDataRelation);
46 d->m_features = other.d_func()->m_features;
47 d->m_osmData = other.d_func()->m_osmData;
48 d->m_memberIds = other.d_func()->m_memberIds;
49 d->m_relationType = other.d_func()->m_relationType;
50 d->m_relationTypeDirty = other.d_func()->m_relationTypeDirty;
51}
52
53GeoDataRelation &GeoDataRelation::operator=(GeoDataRelation other) // passed by value
54{
55 GeoDataFeature::operator=(other);
56 std::swap(*this->d_ptr, *other.d_ptr);
57 return *this;
58}
59
60bool GeoDataRelation::operator<(const GeoDataRelation &other) const
61{
62 if (relationType() == other.relationType()) {
63 Q_D(const GeoDataRelation);
64 auto const refA = d->m_osmData.tagValue(QStringLiteral("ref"));
65 auto const refB = other.osmData().tagValue(QStringLiteral("ref"));
66 if (refA == refB) {
67 return name() < other.name();
68 }
69 return refA < refB;
70 }
71 return relationType() < other.relationType();
72}
73
74const char *GeoDataRelation::nodeType() const
75{
76 return GeoDataTypes::GeoDataRelationType;
77}
78
79GeoDataFeature *GeoDataRelation::clone() const
80{
81 return new GeoDataRelation(*this);
82}
83
84void GeoDataRelation::addMember(const GeoDataFeature *feature, qint64 id, OsmType type, const QString &role)
85{
86 Q_D(GeoDataRelation);
87 d->m_features << feature;
88 d->m_osmData.addRelation(id, type, role);
89 d->m_memberIds << id;
90}
91
92QSet<const GeoDataFeature *> GeoDataRelation::members() const
93{
94 Q_D(const GeoDataRelation);
95 return d->m_features;
96}
97
98OsmPlacemarkData &GeoDataRelation::osmData()
99{
100 Q_D(GeoDataRelation);
101 d->m_relationTypeDirty = true;
102 return d->m_osmData;
103}
104
105const OsmPlacemarkData &GeoDataRelation::osmData() const
106{
107 Q_D(const GeoDataRelation);
108 return d->m_osmData;
109}
110
111GeoDataRelation::RelationType GeoDataRelation::relationType() const
112{
113 Q_D(const GeoDataRelation);
114 if (!d->m_relationTypeDirty) {
115 return d->m_relationType;
116 }
117
118 if (GeoDataRelationPrivate::s_relationTypes.isEmpty()) {
119 auto &map = GeoDataRelationPrivate::s_relationTypes;
120 map["road"] = RouteRoad;
121 map["detour"] = RouteDetour;
122 map["ferry"] = RouteFerry;
123 map["train"] = RouteTrain;
124 map["subway"] = RouteSubway;
125 map["tram"] = RouteTram;
126 map["bus"] = RouteBus;
127 map["trolleybus"] = RouteTrolleyBus;
128 map["bicycle"] = RouteBicycle;
129 map["mtb"] = RouteMountainbike;
130 map["foot"] = RouteFoot;
131 map["hiking"] = GeoDataRelation::RouteHiking;
132 map["horse"] = RouteHorse;
133 map["inline_skates"] = RouteInlineSkates;
134 }
135
136 d->m_relationType = GeoDataRelation::UnknownType;
137 d->m_relationTypeDirty = false;
138 if (d->m_osmData.containsTag(QStringLiteral("type"), QStringLiteral("route"))) {
139 auto const route = d->m_osmData.tagValue(QStringLiteral("route"));
140 if (route == QStringLiteral("piste")) {
141 auto const piste = d->m_osmData.tagValue(QStringLiteral("piste:type"));
142 if (piste == QStringLiteral("downhill")) {
143 d->m_relationType = RouteSkiDownhill;
144 } else if (piste == QStringLiteral("nordic")) {
145 d->m_relationType = RouteSkiNordic;
146 } else if (piste == QStringLiteral("skitour")) {
147 d->m_relationType = RouteSkitour;
148 } else if (piste == QStringLiteral("sled")) {
149 d->m_relationType = RouteSled;
150 }
151 } else {
152 d->m_relationType = GeoDataRelationPrivate::s_relationTypes.value(route, UnknownType);
153 }
154 }
155
156 return d->m_relationType;
157}
158
159QSet<qint64> GeoDataRelation::memberIds() const
160{
161 Q_D(const GeoDataRelation);
162 return d->m_memberIds;
163}
164
165bool GeoDataRelation::containsAnyOf(const QSet<qint64> &memberIds) const
166{
167 Q_D(const GeoDataRelation);
168 return d->m_memberIds.intersects(memberIds);
169}
170
171Q_DECLARE_OPERATORS_FOR_FLAGS(GeoDataRelation::RelationTypes)
172
173}
QString name(StandardShortcut id)
Binds a QML item to a specific geodetic location in screen coordinates.
T value(const Key &key) const const
QFuture< void > map(Iterator begin, Iterator end, MapFunctor &&function)
Q_D(Todo)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:18:17 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.