Libosmium  2.15.5
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-2020 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 
312  OSMObject& set_timestamp(const char* timestamp) {
313  assert(timestamp);
314  m_timestamp = detail::parse_timestamp(timestamp);
315  if (timestamp[20] != '\0') {
316  throw std::invalid_argument{"can not parse timestamp: garbage after timestamp"};
317  }
318  return *this;
319  }
320 
322  const char* user() const noexcept {
323  return reinterpret_cast<const char*>(data() + sizeof_object());
324  }
325 
327  void clear_user() noexcept {
328  std::memset(data() + sizeof_object(), 0, user_size());
329  }
330 
332  const TagList& tags() const {
333  return osmium::detail::subitem_of_type<const TagList>(cbegin(), cend());
334  }
335 
342  const char* get_value_by_key(const char* key, const char* default_value = nullptr) const noexcept {
343  return tags().get_value_by_key(key, default_value);
344  }
345 
353  OSMObject& set_attribute(const char* attr, const char* value) {
354  if (!std::strcmp(attr, "id")) {
355  set_id(value);
356  } else if (!std::strcmp(attr, "version")) {
357  set_version(value);
358  } else if (!std::strcmp(attr, "changeset")) {
359  set_changeset(value);
360  } else if (!std::strcmp(attr, "timestamp")) {
361  set_timestamp(value);
362  } else if (!std::strcmp(attr, "uid")) {
363  set_uid(value);
364  } else if (!std::strcmp(attr, "visible")) {
365  set_visible(value);
366  }
367 
368  return *this;
369  }
370 
373 
380  void remove_tags() noexcept {
381  for (auto& subitem : *this) {
382  if (subitem.type() == osmium::item_type::tag_list) {
383  subitem.set_removed(true);
384  }
385  }
386  }
387 
389  return iterator(subitems_position());
390  }
391 
393  return iterator(next());
394  }
395 
397  return const_iterator(subitems_position());
398  }
399 
401  return const_iterator(next());
402  }
403 
405  return cbegin();
406  }
407 
408  const_iterator end() const {
409  return cend();
410  }
411 
417  template <typename T>
419  return osmium::memory::ItemIteratorRange<T>{subitems_position(), next()};
420  }
421 
427  template <typename T>
429  return osmium::memory::ItemIteratorRange<const T>{subitems_position(), next()};
430  }
431 
432  template <typename T>
434 
435  template <typename T>
437 
438  template <typename T>
440  return t_iterator<T>(subitems_position(), next());
441  }
442 
443  template <typename T>
445  return t_iterator<T>(next(), next());
446  }
447 
448  template <typename T>
450  return t_const_iterator<T>(subitems_position(), next());
451  }
452 
453  template <typename T>
455  return t_const_iterator<T>(next(), next());
456  }
457 
458  template <typename T>
460  return cbegin<T>();
461  }
462 
463  template <typename T>
465  return cend<T>();
466  }
467 
468  }; // class OSMObject
469 
470 
474  inline bool operator==(const OSMObject& lhs, const OSMObject& rhs) noexcept {
475  return lhs.type() == rhs.type() &&
476  lhs.id() == rhs.id() &&
477  lhs.version() == rhs.version();
478  }
479 
480  inline bool operator!=(const OSMObject& lhs, const OSMObject& rhs) noexcept {
481  return !(lhs == rhs);
482  }
483 
499  inline bool operator<(const OSMObject& lhs, const OSMObject& rhs) noexcept {
500  return const_tie(lhs.type(), lhs.id() > 0, lhs.positive_id(), lhs.version(),
501  ((lhs.timestamp().valid() && rhs.timestamp().valid()) ? lhs.timestamp() : osmium::Timestamp())) <
502  const_tie(rhs.type(), rhs.id() > 0, rhs.positive_id(), rhs.version(),
503  ((lhs.timestamp().valid() && rhs.timestamp().valid()) ? rhs.timestamp() : osmium::Timestamp()));
504  }
505 
506  inline bool operator>(const OSMObject& lhs, const OSMObject& rhs) noexcept {
507  return rhs < lhs;
508  }
509 
510  inline bool operator<=(const OSMObject& lhs, const OSMObject& rhs) noexcept {
511  return !(rhs < lhs);
512  }
513 
514  inline bool operator>=(const OSMObject& lhs, const OSMObject& rhs) noexcept {
515  return !(lhs < rhs);
516  }
517 
518 } // namespace osmium
519 
520 #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:418
t_const_iterator< T > end() const
Definition: object.hpp:464
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:332
Definition: tag.hpp:119
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:327
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:428
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:64
const_iterator cbegin() const
Definition: object.hpp:396
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:392
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:459
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:147
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:400
user_id_type uid() const noexcept
Get user id of this object.
Definition: object.hpp:246
t_iterator< T > begin()
Definition: object.hpp:439
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:271
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:353
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:454
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:449
unsigned char * subitems_position()
Definition: object.hpp:92
t_iterator< T > end()
Definition: object.hpp:444
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:408
void remove_tags() noexcept
Definition: object.hpp:380
const char * get_value_by_key(const char *key, const char *default_value=nullptr) const noexcept
Definition: object.hpp:342
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:322
const_iterator begin() const
Definition: object.hpp:404
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:312
Definition: object.hpp:64
iterator begin()
Definition: object.hpp:388