Libosmium  2.14.1
Fast and flexible C++ library for working with OpenStreetMap data
object.hpp
Go to the documentation of this file.
1 #ifndef OSMIUM_OSM_OBJECT_HPP
2 #define OSMIUM_OSM_OBJECT_HPP
3 
4 /*
5 
6 This file is part of Osmium (https://osmcode.org/libosmium).
7 
8 Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
9 
10 Boost Software License - Version 1.0 - August 17th, 2003
11 
12 Permission is hereby granted, free of charge, to any person or organization
13 obtaining a copy of the software and accompanying documentation covered by
14 this license (the "Software") to use, reproduce, display, distribute,
15 execute, and transmit the Software, and to prepare derivative works of the
16 Software, and to permit third-parties to whom the Software is furnished to
17 do so, all subject to the following:
18 
19 The copyright notices in the Software and this entire statement, including
20 the above license grant, this restriction and the following disclaimer,
21 must be included in all copies of the Software, in whole or in part, and
22 all derivative works of the Software, unless such copies or derivative
23 works are solely in the form of machine-executable object code generated by
24 a source language processor.
25 
26 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
27 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28 FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
29 SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
30 FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
31 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
32 DEALINGS IN THE SOFTWARE.
33 
34 */
35 
37 #include <osmium/memory/item.hpp>
39 #include <osmium/osm/entity.hpp>
40 #include <osmium/osm/item_type.hpp>
41 #include <osmium/osm/location.hpp>
42 #include <osmium/osm/tag.hpp>
43 #include <osmium/osm/timestamp.hpp>
44 #include <osmium/osm/types.hpp>
46 #include <osmium/util/misc.hpp>
47 
48 #include <cstdlib>
49 #include <cstring>
50 #include <stdexcept>
51 #include <tuple>
52 #include <type_traits>
53 
54 namespace osmium {
55 
56  namespace builder {
57  template <typename TDerived, typename T>
58  class OSMObjectBuilder;
59  } // namespace builder
60 
64  class OSMObject : public osmium::OSMEntity {
65 
66  template <typename TDerived, typename T>
68 
69  object_id_type m_id = 0;
70  bool m_deleted : 1;
72  osmium::Timestamp m_timestamp{};
73  user_id_type m_uid = 0;
74  changeset_id_type m_changeset = 0;
75 
76  size_t sizeof_object() const noexcept {
77  return sizeof(OSMObject) + (type() == item_type::node ? sizeof(osmium::Location) : 0) + sizeof(string_size_type);
78  }
79 
80  unsigned char* user_position() noexcept {
81  return data() + sizeof_object() - sizeof(string_size_type);
82  }
83 
84  const unsigned char* user_position() const noexcept {
85  return data() + sizeof_object() - sizeof(string_size_type);
86  }
87 
88  string_size_type user_size() const noexcept {
89  return *reinterpret_cast<const string_size_type*>(user_position());
90  }
91 
92  unsigned char* subitems_position() {
93  return data() + osmium::memory::padded_length(sizeof_object() + user_size());
94  }
95 
96  const unsigned char* subitems_position() const {
97  return data() + osmium::memory::padded_length(sizeof_object() + user_size());
98  }
99 
100  protected:
101 
103  OSMEntity(size, type),
104  m_deleted(false),
105  m_version(0) {
106  }
107 
109  *reinterpret_cast<string_size_type*>(user_position()) = size;
110  }
111 
112  public:
113 
114  constexpr static bool is_compatible_to(osmium::item_type t) noexcept {
115  return t == osmium::item_type::node ||
116  t == osmium::item_type::way ||
119  }
120 
122  object_id_type id() const noexcept {
123  return m_id;
124  }
125 
128  return static_cast<unsigned_object_id_type>(std::abs(m_id));
129  }
130 
137  m_id = id;
138  return *this;
139  }
140 
146  OSMObject& set_id(const char* id) {
147  return set_id(osmium::string_to_object_id(id));
148  }
149 
151  bool deleted() const noexcept {
152  return m_deleted;
153  }
154 
156  bool visible() const noexcept {
157  return !deleted();
158  }
159 
165  OSMObject& set_deleted(bool deleted) noexcept {
166  m_deleted = deleted;
167  return *this;
168  }
169 
175  OSMObject& set_visible(bool visible) noexcept {
176  m_deleted = !visible;
177  return *this;
178  }
179 
186  OSMObject& set_visible(const char* visible) {
187  if (!std::strcmp("true", visible)) {
188  set_visible(true);
189  } else if (!std::strcmp("false", visible)) {
190  set_visible(false);
191  } else {
192  throw std::invalid_argument{"Unknown value for visible attribute (allowed is 'true' or 'false')"};
193  }
194  return *this;
195  }
196 
198  object_version_type version() const noexcept {
199  return m_version;
200  }
201 
208  m_version = version;
209  return *this;
210  }
211 
217  OSMObject& set_version(const char* version) {
218  return set_version(string_to_object_version(version));
219  }
220 
222  changeset_id_type changeset() const noexcept {
223  return m_changeset;
224  }
225 
232  m_changeset = changeset;
233  return *this;
234  }
235 
241  OSMObject& set_changeset(const char* changeset) {
242  return set_changeset(string_to_changeset_id(changeset));
243  }
244 
246  user_id_type uid() const noexcept {
247  return m_uid;
248  }
249 
255  OSMObject& set_uid(user_id_type uid) noexcept {
256  m_uid = uid;
257  return *this;
258  }
259 
267  m_uid = uid < 0 ? 0 : static_cast<user_id_type>(uid);
268  return *this;
269  }
270 
276  OSMObject& set_uid(const char* uid) {
277  m_uid = string_to_uid(uid);
278  return *this;
279  }
280 
282  bool user_is_anonymous() const noexcept {
283  return m_uid == 0;
284  }
285 
287  osmium::Timestamp timestamp() const noexcept {
288  return m_timestamp;
289  }
290 
297  OSMObject& set_timestamp(const osmium::Timestamp& timestamp) noexcept {
298  m_timestamp = timestamp;
299  return *this;
300  }
301 
308  OSMObject& set_timestamp(const char* timestamp) {
309  m_timestamp = detail::parse_timestamp(timestamp);
310  if (timestamp[20] != '\0') {
311  throw std::invalid_argument{"can not parse timestamp"};
312  }
313  return *this;
314  }
315 
317  const char* user() const noexcept {
318  return reinterpret_cast<const char*>(data() + sizeof_object());
319  }
320 
322  void clear_user() noexcept {
323  std::memset(data() + sizeof_object(), 0, user_size());
324  }
325 
327  const TagList& tags() const {
328  return osmium::detail::subitem_of_type<const TagList>(cbegin(), cend());
329  }
330 
337  const char* get_value_by_key(const char* key, const char* default_value = nullptr) const noexcept {
338  return tags().get_value_by_key(key, default_value);
339  }
340 
348  OSMObject& set_attribute(const char* attr, const char* value) {
349  if (!std::strcmp(attr, "id")) {
350  set_id(value);
351  } else if (!std::strcmp(attr, "version")) {
352  set_version(value);
353  } else if (!std::strcmp(attr, "changeset")) {
354  set_changeset(value);
355  } else if (!std::strcmp(attr, "timestamp")) {
356  set_timestamp(value);
357  } else if (!std::strcmp(attr, "uid")) {
358  set_uid(value);
359  } else if (!std::strcmp(attr, "visible")) {
360  set_visible(value);
361  }
362 
363  return *this;
364  }
365 
368 
370  return iterator(subitems_position());
371  }
372 
374  return iterator(next());
375  }
376 
378  return const_iterator(subitems_position());
379  }
380 
382  return const_iterator(next());
383  }
384 
386  return cbegin();
387  }
388 
389  const_iterator end() const {
390  return cend();
391  }
392 
398  template <typename T>
400  return osmium::memory::ItemIteratorRange<T>{subitems_position(), next()};
401  }
402 
408  template <typename T>
410  return osmium::memory::ItemIteratorRange<const T>{subitems_position(), next()};
411  }
412 
413  template <typename T>
415 
416  template <typename T>
418 
419  template <typename T>
421  return t_iterator<T>(subitems_position(), next());
422  }
423 
424  template <typename T>
426  return t_iterator<T>(next(), next());
427  }
428 
429  template <typename T>
431  return t_const_iterator<T>(subitems_position(), next());
432  }
433 
434  template <typename T>
436  return t_const_iterator<T>(next(), next());
437  }
438 
439  template <typename T>
441  return cbegin<T>();
442  }
443 
444  template <typename T>
446  return cend<T>();
447  }
448 
449  }; // class OSMObject
450 
451 
455  inline bool operator==(const OSMObject& lhs, const OSMObject& rhs) noexcept {
456  return lhs.type() == rhs.type() &&
457  lhs.id() == rhs.id() &&
458  lhs.version() == rhs.version();
459  }
460 
461  inline bool operator!=(const OSMObject& lhs, const OSMObject& rhs) noexcept {
462  return !(lhs == rhs);
463  }
464 
480  inline bool operator<(const OSMObject& lhs, const OSMObject& rhs) noexcept {
481  return const_tie(lhs.type(), lhs.id() > 0, lhs.positive_id(), lhs.version(),
482  ((lhs.timestamp().valid() && rhs.timestamp().valid()) ? lhs.timestamp() : osmium::Timestamp())) <
483  const_tie(rhs.type(), rhs.id() > 0, rhs.positive_id(), rhs.version(),
484  ((lhs.timestamp().valid() && rhs.timestamp().valid()) ? rhs.timestamp() : osmium::Timestamp()));
485  }
486 
487  inline bool operator>(const OSMObject& lhs, const OSMObject& rhs) noexcept {
488  return rhs < lhs;
489  }
490 
491  inline bool operator<=(const OSMObject& lhs, const OSMObject& rhs) noexcept {
492  return !(rhs < lhs);
493  }
494 
495  inline bool operator>=(const OSMObject& lhs, const OSMObject& rhs) noexcept {
496  return !(lhs < rhs);
497  }
498 
499 } // namespace osmium
500 
501 #endif // OSMIUM_OSM_OBJECT_HPP
uint32_t object_version_type
Type for OSM object version number.
Definition: types.hpp:47
uint32_t user_id_type
Type for OSM user IDs.
Definition: types.hpp:49
Definition: osm_object_builder.hpp:402
osmium::memory::ItemIteratorRange< T > subitems()
Definition: object.hpp:399
t_const_iterator< T > end() const
Definition: object.hpp:445
Definition: collection.hpp:47
unsigned char * user_position() noexcept
Definition: object.hpp:80
const TagList & tags() const
Get the list of tags for this object.
Definition: object.hpp:327
Definition: tag.hpp:109
type
Definition: entity_bits.hpp:63
Definition: item_iterator.hpp:175
bool operator<=(const Changeset &lhs, const Changeset &rhs)
Definition: changeset.hpp:461
OSMObject & set_timestamp(const osmium::Timestamp &timestamp) noexcept
Definition: object.hpp:297
uint32_t item_size_type
Definition: item.hpp:57
void clear_user() noexcept
Clear user name.
Definition: object.hpp:322
bool m_deleted
Definition: object.hpp:70
OSMObject(osmium::memory::item_size_type size, osmium::item_type type)
Definition: object.hpp:102
Definition: item_iterator.hpp:59
string_size_type user_size() const noexcept
Definition: object.hpp:88
constexpr bool operator==(const Box &lhs, const Box &rhs) noexcept
Definition: box.hpp:212
item_type
Definition: item_type.hpp:43
osmium::memory::ItemIteratorRange< const T > subitems() const
Definition: object.hpp:409
uint16_t string_size_type
Definition: types.hpp:59
uint64_t unsigned_object_id_type
Type for OSM object (node, way, or relation) IDs where we only allow positive IDs.
Definition: types.hpp:46
size_t sizeof_object() const noexcept
Definition: object.hpp:76
object_version_type m_version
Definition: object.hpp:71
std::tuple< const Ts &... > const_tie(const Ts &... args) noexcept
Definition: misc.hpp:52
OSMObject & set_id(object_id_type id) noexcept
Definition: object.hpp:136
OSMEntity is the abstract base class for the OSMObject and Changeset classes.
Definition: entity.hpp:64
OSMObject & set_changeset(const char *changeset)
Definition: object.hpp:241
constexpr std::size_t padded_length(std::size_t length) noexcept
Definition: item.hpp:62
const_iterator cbegin() const
Definition: object.hpp:377
user_id_type string_to_uid(const char *input)
Definition: types_from_string.hpp:186
object_version_type string_to_object_version(const char *input)
Definition: types_from_string.hpp:135
bool user_is_anonymous() const noexcept
Is this user anonymous?
Definition: object.hpp:282
iterator end()
Definition: object.hpp:373
OSMObject & set_visible(const char *visible)
Definition: object.hpp:186
OSMObject & set_uid_from_signed(signed_user_id_type uid) noexcept
Definition: object.hpp:266
bool operator<(const Changeset &lhs, const Changeset &rhs)
Definition: changeset.hpp:453
object_id_type string_to_object_id(const char *input)
Definition: types_from_string.hpp:60
t_const_iterator< T > begin() const
Definition: object.hpp:440
Namespace for everything in the Osmium library.
Definition: assembler.hpp:53
static constexpr bool is_compatible_to(osmium::item_type t) noexcept
Definition: object.hpp:114
int32_t signed_user_id_type
Type for signed OSM user IDs.
Definition: types.hpp:50
Definition: timestamp.hpp:145
uint32_t changeset_id_type
Type for OSM changeset IDs.
Definition: types.hpp:48
int64_t object_id_type
Type for OSM object (node, way, or relation) IDs.
Definition: types.hpp:45
changeset_id_type string_to_changeset_id(const char *input)
Definition: types_from_string.hpp:149
const_iterator cend() const
Definition: object.hpp:381
user_id_type uid() const noexcept
Get user id of this object.
Definition: object.hpp:246
t_iterator< T > begin()
Definition: object.hpp:420
changeset_id_type changeset() const noexcept
Get changeset id of this object.
Definition: object.hpp:222
OSMObject & set_changeset(changeset_id_type changeset) noexcept
Definition: object.hpp:231
OSMObject & set_uid(const char *uid)
Definition: object.hpp:276
Definition: location.hpp:273
OSMObject & set_id(const char *id)
Definition: object.hpp:146
bool deleted() const noexcept
Is this object marked as deleted?
Definition: object.hpp:151
bool operator>=(const Changeset &lhs, const Changeset &rhs)
Definition: changeset.hpp:465
object_id_type id() const noexcept
Get ID of this object.
Definition: object.hpp:122
OSMObject & set_version(object_version_type version) noexcept
Definition: object.hpp:207
OSMObject & set_attribute(const char *attr, const char *value)
Definition: object.hpp:348
object_version_type version() const noexcept
Get version of this object.
Definition: object.hpp:198
bool operator>(const Changeset &lhs, const Changeset &rhs)
Definition: changeset.hpp:457
t_const_iterator< T > cend() const
Definition: object.hpp:435
OSMObject & set_visible(bool visible) noexcept
Definition: object.hpp:175
uint32_t size() const noexcept
Definition: builder.hpp:133
bool visible() const noexcept
Is this object marked visible (ie not deleted)?
Definition: object.hpp:156
t_const_iterator< T > cbegin() const
Definition: object.hpp:430
unsigned char * subitems_position()
Definition: object.hpp:92
t_iterator< T > end()
Definition: object.hpp:425
unsigned_object_id_type positive_id() const noexcept
Get absolute value of the ID of this object.
Definition: object.hpp:127
OSMObject & set_deleted(bool deleted) noexcept
Definition: object.hpp:165
const unsigned char * subitems_position() const
Definition: object.hpp:96
void set_user_size(string_size_type size)
Definition: object.hpp:108
const_iterator end() const
Definition: object.hpp:389
const char * get_value_by_key(const char *key, const char *default_value=nullptr) const noexcept
Definition: object.hpp:337
const unsigned char * user_position() const noexcept
Definition: object.hpp:84
const char * user() const noexcept
Get user name for this object.
Definition: object.hpp:317
const_iterator begin() const
Definition: object.hpp:385
OSMObject & set_version(const char *version)
Definition: object.hpp:217
osmium::Timestamp timestamp() const noexcept
Get timestamp when this object last changed.
Definition: object.hpp:287
OSMObject & set_uid(user_id_type uid) noexcept
Definition: object.hpp:255
bool operator!=(const Changeset &lhs, const Changeset &rhs)
Definition: changeset.hpp:446
OSMObject & set_timestamp(const char *timestamp)
Definition: object.hpp:308
Definition: object.hpp:64
iterator begin()
Definition: object.hpp:369