KOSMIndoorMap

element.h
1 /*
2  SPDX-FileCopyrightText: 2020 Volker Krause <[email protected]>
3 
4  SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6 
7 #ifndef OSM_ELEMENT_H
8 #define OSM_ELEMENT_H
9 
10 #include "kosm_export.h"
11 
12 #include "datatypes.h"
13 #include "internal.h"
14 
15 #include <cstdint>
16 
17 namespace OSM {
18 
19 /** A reference to any of OSM::Node/OSM::Way/OSM::Relation.
20  * Lifetime of the referenced object needs to extend beyond the lifetime of this.
21  */
22 class KOSM_EXPORT Element
23 {
24 public:
25  inline constexpr Element() : m_elem(nullptr, static_cast<uint8_t>(Type::Null)) {}
26  inline Element(const Node *node) : m_elem(node, static_cast<uint8_t>(Type::Node)) {}
27  inline Element(const Way *way) : m_elem(way, static_cast<uint8_t>(Type::Way)) {}
28  inline Element(const Relation *relation) : m_elem(relation, static_cast<uint8_t>(Type::Relation)) {}
29 
30  inline bool operator==(Element other) const { return m_elem == other.m_elem; }
31  inline bool operator!=(Element other) const { return m_elem != other.m_elem; }
32  inline bool operator<(Element other) const { return m_elem < other.m_elem; }
33  explicit inline operator bool() const { return type() != OSM::Type::Null; }
34 
35  inline Type type() const { return static_cast<Type>(m_elem.tag()); }
36  inline const Node* node() const { return static_cast<const Node*>(m_elem.get()); }
37  inline const Way* way() const { return static_cast<const Way*>(m_elem.get()); }
38  inline const Relation* relation() const { return static_cast<const Relation*>(m_elem.get()); }
39  Id id() const;
40 
41  Coordinate center() const;
42  BoundingBox boundingBox() const;
43  QByteArray tagValue(TagKey key) const;
44  QByteArray tagValue(const char *keyName) const;
45  QByteArray tagValue(const char *keyName, const QLocale &locale) const;
46  /** Returns the value of the first non-empty tag.
47  * Both OSM::TagKey (fast) and const char* (slow) keys are accepted.
48  */
49  template <typename K, typename ...Args> QByteArray tagValue(K key, Args... args) const;
50  template <typename K, typename ...Args> QByteArray tagValue(K key, Args... args, const QLocale &locale) const;
51  /** Returns whether or not this element has any tags set. */
52  inline bool hasTags() const { return std::distance(tagsBegin(), tagsEnd()) > 0; }
53  /** Returns @c true if this element has a tag with key @p key. */
54  bool hasTag(TagKey key) const;
55 
56  std::vector<Tag>::const_iterator tagsBegin() const;
57  std::vector<Tag>::const_iterator tagsEnd() const;
58  QString url() const;
59 
60  /** Returns all nodes belonging to the outer path of this element.
61  * In the simplest case that's a single closed polygon, but it can also be a sequence of multiple
62  * closed loop polygons, or a polyline.
63  */
64  std::vector<const Node*> outerPath(const DataSet &dataSet) const;
65 
66  /** Recompute the bounding box of this element.
67  * We usually assume those to be provided by Overpass/osmconvert, but there seem to be cases where those
68  * aren't reliable.
69  */
70  void recomputeBoundingBox(const DataSet &dataSet);
71 
72 private:
74 };
75 
76 template <typename K, typename ...Args>
77 QByteArray Element::tagValue(K k, Args... args) const
78 {
79  const auto v = tagValue(k);
80  if (!v.isEmpty()) {
81  return v;
82  }
83  return tagValue(args...);
84 }
85 
86 template <typename K, typename ...Args>
87 QByteArray Element::tagValue(K key, Args... args, const QLocale &locale) const
88 {
89  const auto v = tagValue(key, locale);
90  if (!v.isEmpty()) {
91  return v;
92  }
93  return tagValue(args..., locale);
94 }
95 
96 
97 /** A std::unique_ptr-like object for OSM element types. */
98 class KOSM_EXPORT UniqueElement
99 {
100 public:
101  explicit inline UniqueElement() = default;
102  explicit inline UniqueElement(Node *node) : m_element(node) {}
103  explicit inline UniqueElement(Way *way) : m_element(way) {}
104  explicit inline UniqueElement(Relation *rel) : m_element(rel) {}
105 
106  UniqueElement(const UniqueElement&) = delete;
107  inline UniqueElement(UniqueElement &&other) {
108  m_element = other.m_element;
109  other.m_element = {};
110  }
111 
112  ~UniqueElement();
113 
114  UniqueElement& operator=(const UniqueElement&) = delete;
115  UniqueElement& operator=(UniqueElement &&other) {
116  m_element = other.m_element;
117  other.m_element = {};
118  return *this;
119  }
120 
121  explicit inline operator bool() const { return m_element.type() != OSM::Type::Null; }
122 
123  constexpr inline Element element() const { return m_element; }
124  constexpr inline operator Element() const { return m_element; }
125 
126  void setId(Id id);
127  void setTagValue(TagKey key, const QByteArray &value);
128  void removeTag(TagKey key);
129 
130 private:
131  Element m_element;
132 };
133 
134 /** Creates a copy of @p element. */
135 KOSM_EXPORT UniqueElement copy_element(Element e);
136 
137 /** Utility function similar to SQL COALESCE for OSM::Element, ie. this returns the first non-null element passed as argument. */
138 constexpr Element coalesce(Element e) { return e; }
139 template <typename ...Args>
140 constexpr Element coalesce(Element e, Args... args) { return e ? e : coalesce(args...); }
141 
142 enum ForeachFlag : uint8_t {
143  IncludeRelations = 1,
144  IncludeWays = 2,
145  IncludeNodes = 4,
146  IterateAll = IncludeRelations | IncludeWays | IncludeNodes,
147 };
148 
149 template <typename Func>
150 inline void for_each(const DataSet &dataSet, Func func, uint8_t flags = IterateAll)
151 {
152  if (flags & IncludeRelations) {
153  for (const auto &rel : dataSet.relations) {
154  func(Element(&rel));
155  }
156  }
157  if (flags & IncludeWays) {
158  for (const auto &way : dataSet.ways) {
159  func(Element(&way));
160  }
161  }
162  if (flags & IncludeNodes) {
163  for (const auto &node : dataSet.nodes) {
164  func(Element(&node));
165  }
166  }
167 }
168 
169 template <typename Func>
170 inline void for_each_node(const DataSet &dataSet, const Way &way, Func func)
171 {
172  for (auto nodeId : way.nodes) {
173  if (auto node = dataSet.node(nodeId)) {
174  func(*node);
175  }
176  }
177 }
178 
179 template <typename Func>
180 inline void for_each_member(const DataSet &dataSet, const Relation &rel, Func func)
181 {
182  for (const auto &mem : rel.members) {
183  switch (mem.type()) {
184  case Type::Null:
185  break;
186  case Type::Node:
187  if (auto node = dataSet.node(mem.id)) {
188  func(Element(node));
189  }
190  break;
191  case Type::Way:
192  if (auto way = dataSet.way(mem.id)) {
193  func(Element(way));
194  }
195  break;
196  case Type::Relation:
197  if (auto rel = dataSet.relation(mem.id)) {
198  func(Element(rel));
199  }
200  break;
201  }
202  }
203 }
204 
205 }
206 
207 Q_DECLARE_METATYPE(OSM::Element)
208 
209 #endif // OSM_ELEMENT_H
void removeTag(Elem &elem, TagKey key)
Removes a tag from the given element.
Definition: datatypes.h:441
Coordinate, stored as 1e7 * degree to avoid floating point precision issues, and offset to unsigned v...
Definition: datatypes.h:37
constexpr Element coalesce(Element e)
Utility function similar to SQL COALESCE for OSM::Element, ie.
Definition: element.h:138
A reference to any of OSM::Node/OSMWay/OSMRelation.
Definition: element.h:22
A key of an OSM tag.
Definition: datatypes.h:179
void setTagValue(Elem &elem, TagKey key, const QByteArray &value)
Inserts a new tag, or updates an existing one.
Definition: datatypes.h:433
QByteArray tagValue(const Elem &elem, TagKey key)
Returns the tag value for key of elem.
Definition: datatypes.h:353
An OSM node.
Definition: datatypes.h:194
int64_t Id
OSM element identifier.
Definition: datatypes.h:27
An OSM way.
Definition: datatypes.h:206
Type
Element type.
Definition: datatypes.h:221
KOSM_EXPORT UniqueElement copy_element(Element e)
Creates a copy of element.
Definition: element.cpp:300
An OSM relation.
Definition: datatypes.h:270
A set of nodes, ways and relations.
Definition: datatypes.h:283
A std::unique_ptr-like object for OSM element types.
Definition: element.h:98
bool hasTags() const
Returns whether or not this element has any tags set.
Definition: element.h:52
const Way * way(Id id) const
Find a way by its id.
Definition: datatypes.cpp:46
Bounding box, ie.
Definition: datatypes.h:95
Low-level types and functions to work with raw OSM data as efficiently as possible.
const Relation * relation(Id id) const
Find a relation by its id.
Definition: datatypes.cpp:64
const Node * node(Id id) const
Find a node by its id.
Definition: datatypes.cpp:37
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Sun Oct 24 2021 23:03:45 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.