KOSMIndoorMap

element.cpp
1/*
2 SPDX-FileCopyrightText: 2020 Volker Krause <vkrause@kde.org>
3
4 SPDX-License-Identifier: LGPL-2.0-or-later
5*/
6
7#include "element.h"
8#include "pathutil.h"
9
10using namespace OSM;
11
12Id Element::id() const
13{
14 switch (type()) {
15 case Type::Null:
16 return {};
17 case Type::Node:
18 return node()->id;
19 case Type::Way:
20 return way()->id;
21 case Type::Relation:
22 return relation()->id;
23 }
24
25 Q_UNREACHABLE();
26 return {};
27}
28
29Coordinate Element::center() const
30{
31 switch (type()) {
32 case Type::Null:
33 return {};
34 case Type::Node:
35 return node()->coordinate;
36 case Type::Way:
37 return way()->bbox.center();
38 case Type::Relation:
39 return relation()->bbox.center();
40 }
41
42 Q_UNREACHABLE();
43 return {};
44}
45
46BoundingBox Element::boundingBox() const
47{
48 switch (type()) {
49 case Type::Null:
50 return {};
51 case Type::Node:
52 return BoundingBox(node()->coordinate, node()->coordinate);
53 case Type::Way:
54 return way()->bbox;
55 case Type::Relation:
56 return relation()->bbox;
57 }
58
59 Q_UNREACHABLE();
60 return {};
61}
62
63QByteArray Element::tagValue(TagKey key) const
64{
65 switch (type()) {
66 case Type::Null:
67 return {};
68 case Type::Node:
69 return OSM::tagValue(*node(), key);
70 case Type::Way:
71 return OSM::tagValue(*way(), key);
72 case Type::Relation:
73 return OSM::tagValue(*relation(), key);
74 }
75
76 Q_UNREACHABLE();
77 return {};
78}
79
80QByteArray Element::tagValue(const char *keyName) const
81{
82 switch (type()) {
83 case Type::Null:
84 return {};
85 case Type::Node:
86 return OSM::tagValue(*node(), keyName);
87 case Type::Way:
88 return OSM::tagValue(*way(), keyName);
89 case Type::Relation:
90 return OSM::tagValue(*relation(), keyName);
91 }
92
93 Q_UNREACHABLE();
94 return {};
95}
96
97QByteArray Element::tagValue(const OSM::Languages &languages, const char *keyName) const
98{
99 switch (type()) {
100 case Type::Null:
101 return {};
102 case Type::Node:
103 return OSM::tagValue(*node(), languages, keyName);
104 case Type::Way:
105 return OSM::tagValue(*way(), languages, keyName);
106 case Type::Relation:
107 return OSM::tagValue(*relation(), languages, keyName);
108 }
109
110 Q_UNREACHABLE();
111 return {};
112}
113
114bool Element::hasTag(TagKey key) const
115{
116 return std::binary_search(tagsBegin(), tagsEnd(), key);
117}
118
119std::vector<Tag>::const_iterator OSM::Element::tagsBegin() const
120{
121 switch (type()) {
122 case Type::Null:
123 Q_UNREACHABLE();
124 case Type::Node:
125 return node()->tags.begin();
126 case Type::Way:
127 return way()->tags.begin();
128 case Type::Relation:
129 return relation()->tags.begin();
130 }
131 Q_UNREACHABLE();
132}
133
134std::vector<Tag>::const_iterator OSM::Element::tagsEnd() const
135{
136 switch (type()) {
137 case Type::Null:
138 Q_UNREACHABLE();
139 case Type::Node:
140 return node()->tags.end();
141 case Type::Way:
142 return way()->tags.end();
143 case Type::Relation:
144 return relation()->tags.end();
145 }
146 Q_UNREACHABLE();
147}
148
149QString Element::url() const
150{
151 switch (type()) {
152 case Type::Null:
153 return {};
154 case Type::Node:
155 return node()->url();
156 case Type::Way:
157 return way()->url();
158 case Type::Relation:
159 return relation()->url();
160 }
161
162 Q_UNREACHABLE();
163 return {};
164}
165
166std::vector<const Node*> Element::outerPath(const DataSet &dataSet) const
167{
168 switch (type()) {
169 case Type::Null:
170 return {};
171 case Type::Node:
172 return {node()};
173 case Type::Way:
174 {
175 std::vector<const Node*> nodes;
176 appendNodesFromWay(dataSet, nodes, way()->nodes.begin(), way()->nodes.end());
177 return nodes;
178 }
179 case Type::Relation:
180 {
181 if (tagValue("type") != "multipolygon") {
182 return {};
183 }
184
185 // collect the relevant ways
186 std::vector<const Way*> ways;
187 for (const auto &member : relation()->members) {
188 if (std::strcmp(member.role().name(), "outer") != 0) {
189 continue;
190 }
191 if (auto way = dataSet.way(member.id)) {
192 ways.push_back(way);
193 }
194 }
195
196 // stitch them together (there is no well-defined order)
197 std::vector<const Node*> nodes;
198 assemblePath(dataSet, std::move(ways), nodes);
199 return nodes;
200 }
201 }
202
203 Q_UNREACHABLE();
204 return {};
205}
206
208{
209 switch (type()) {
210 case Type::Null:
211 case Type::Node:
212 break;
213 case Type::Way:
214 way()->bbox = std::accumulate(way()->nodes.begin(), way()->nodes.end(), OSM::BoundingBox(), [&dataSet](auto bbox, auto nodeId) {
215 if (auto node = dataSet.node(nodeId)) {
216 return OSM::unite(bbox, {node->coordinate, node->coordinate});
217 }
218 return bbox;
219 });
220 break;
221 case Type::Relation:
222 relation()->bbox = {};
223 for_each_member(dataSet, *relation(), [this, &dataSet](auto mem) {
224 mem.recomputeBoundingBox(dataSet);
225 relation()->bbox = OSM::unite(relation()->bbox, mem.boundingBox());
226 });
227 break;
228 }
229}
230
231
232UniqueElement::~UniqueElement()
233{
234 switch (m_element.type()) {
235 case OSM::Type::Null:
236 break;
237 case OSM::Type::Node:
238 delete m_element.node();
239 break;
240 case OSM::Type::Way:
241 delete m_element.way();
242 break;
243 case OSM::Type::Relation:
244 delete m_element.relation();
245 break;
246 }
247}
248
249void UniqueElement::setId(Id id)
250{
251 switch (m_element.type()) {
252 case OSM::Type::Null:
253 return;
254 case OSM::Type::Node:
255 const_cast<Node*>(m_element.node())->id = id;
256 break;
257 case OSM::Type::Way:
258 const_cast<Way*>(m_element.way())->id = id;
259 break;
260 case OSM::Type::Relation:
261 const_cast<Relation*>(m_element.relation())->id = id;
262 break;
263 }
264}
265
266void UniqueElement::setTagValue(TagKey key, QByteArray &&value)
267{
268 switch (m_element.type()) {
269 case OSM::Type::Null:
270 return;
271 case OSM::Type::Node:
272 OSM::setTagValue(*const_cast<Node*>(m_element.node()), key, std::move(value));
273 break;
274 case OSM::Type::Way:
275 OSM::setTagValue(*const_cast<Way*>(m_element.way()), key, std::move(value));
276 break;
277 case OSM::Type::Relation:
278 OSM::setTagValue(*const_cast<Relation*>(m_element.relation()), key, std::move(value));
279 break;
280 }
281}
282
283void UniqueElement::removeTag(TagKey key)
284{
285 switch (m_element.type()) {
286 case OSM::Type::Null:
287 return;
288 case OSM::Type::Node:
289 OSM::removeTag(*const_cast<Node*>(m_element.node()), key);
290 break;
291 case OSM::Type::Way:
292 OSM::removeTag(*const_cast<Way*>(m_element.way()), key);
293 break;
294 case OSM::Type::Relation:
295 OSM::removeTag(*const_cast<Relation*>(m_element.relation()), key);
296 break;
297 }
298}
299
301{
302 switch (e.type()) {
303 case OSM::Type::Null:
304 return UniqueElement();
305 case OSM::Type::Node:
306 return UniqueElement(new Node(*e.node()));
307 case OSM::Type::Way:
308 return UniqueElement(new Way(*e.way()));
309 case OSM::Type::Relation:
310 return UniqueElement(new Relation(*e.relation()));
311 }
312 Q_UNREACHABLE();
313 return UniqueElement();
314}
Bounding box, ie.
Definition datatypes.h:95
A set of nodes, ways and relations.
Definition datatypes.h:340
const Way * way(Id id) const
Find a way by its id.
Definition datatypes.cpp:46
A reference to any of OSM::Node/OSM::Way/OSM::Relation.
Definition element.h:24
void recomputeBoundingBox(const DataSet &dataSet)
Recompute the bounding box of this element.
Definition element.cpp:207
bool hasTag(TagKey key) const
Returns true if this element has a tag with key key.
Definition element.cpp:114
std::vector< const Node * > outerPath(const DataSet &dataSet) const
Returns all nodes belonging to the outer path of this element.
Definition element.cpp:166
Languages in preference order to consider when looking up translated tag values.
Definition languages.h:25
An OSM node.
Definition datatypes.h:204
An OSM relation.
Definition datatypes.h:311
A key of an OSM tag.
Definition datatypes.h:179
A std::unique_ptr-like object for OSM element types.
Definition element.h:100
An OSM way.
Definition datatypes.h:231
Low-level types and functions to work with raw OSM data as efficiently as possible.
void setTagValue(Elem &elem, TagKey key, QByteArray &&value)
Inserts a new tag, or updates an existing one.
Definition datatypes.h:484
int64_t Id
OSM element identifier.
Definition datatypes.h:30
KOSM_EXPORT void assemblePath(const DataSet &dataSet, std::vector< const Way * > &&ways, std::vector< const Node * > &path)
Assemble a continuous path into path from the given ways.
Definition pathutil.cpp:42
KOSM_EXPORT UniqueElement copy_element(Element e)
Creates a copy of element.
Definition element.cpp:300
static void appendNodesFromWay(const DataSet &dataSet, std::vector< const Node * > &nodes, const Iter &nodeBegin, const Iter &nodeEnd)
Appends the nodes referenced by nodesBegin and @pnodesEnd into nodes.
Definition pathutil.h:24
QByteArray tagValue(const Elem &elem, TagKey key)
Returns the tag value for key of elem.
Definition datatypes.h:410
void removeTag(Elem &elem, TagKey key)
Removes a tag from the given element.
Definition datatypes.h:491
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Sun Feb 25 2024 18:46:39 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.