Libosmium  2.14.0
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 (http://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  const TagList& tags() const {
323  return osmium::detail::subitem_of_type<const TagList>(cbegin(), cend());
324  }
325 
332  const char* get_value_by_key(const char* key, const char* default_value = nullptr) const noexcept {
333  return tags().get_value_by_key(key, default_value);
334  }
335 
343  OSMObject& set_attribute(const char* attr, const char* value) {
344  if (!std::strcmp(attr, "id")) {
345  set_id(value);
346  } else if (!std::strcmp(attr, "version")) {
347  set_version(value);
348  } else if (!std::strcmp(attr, "changeset")) {
349  set_changeset(value);
350  } else if (!std::strcmp(attr, "timestamp")) {
351  set_timestamp(value);
352  } else if (!std::strcmp(attr, "uid")) {
353  set_uid(value);
354  } else if (!std::strcmp(attr, "visible")) {
355  set_visible(value);
356  }
357 
358  return *this;
359  }
360 
363 
365  return iterator(subitems_position());
366  }
367 
369  return iterator(next());
370  }
371 
373  return const_iterator(subitems_position());
374  }
375 
377  return const_iterator(next());
378  }
379 
381  return cbegin();
382  }
383 
384  const_iterator end() const {
385  return cend();
386  }
387 
393  template <typename T>
395  return osmium::memory::ItemIteratorRange<T>{subitems_position(), next()};
396  }
397 
403  template <typename T>
405  return osmium::memory::ItemIteratorRange<const T>{subitems_position(), next()};
406  }
407 
408  template <typename T>
410 
411  template <typename T>
413 
414  template <typename T>
416  return t_iterator<T>(subitems_position(), next());
417  }
418 
419  template <typename T>
421  return t_iterator<T>(next(), next());
422  }
423 
424  template <typename T>
426  return t_const_iterator<T>(subitems_position(), next());
427  }
428 
429  template <typename T>
431  return t_const_iterator<T>(next(), next());
432  }
433 
434  template <typename T>
436  return cbegin<T>();
437  }
438 
439  template <typename T>
441  return cend<T>();
442  }
443 
444  }; // class OSMObject
445 
446 
450  inline bool operator==(const OSMObject& lhs, const OSMObject& rhs) noexcept {
451  return lhs.type() == rhs.type() &&
452  lhs.id() == rhs.id() &&
453  lhs.version() == rhs.version();
454  }
455 
456  inline bool operator!=(const OSMObject& lhs, const OSMObject& rhs) noexcept {
457  return !(lhs == rhs);
458  }
459 
475  inline bool operator<(const OSMObject& lhs, const OSMObject& rhs) noexcept {
476  return const_tie(lhs.type(), lhs.id() > 0, lhs.positive_id(), lhs.version(),
477  ((lhs.timestamp().valid() && rhs.timestamp().valid()) ? lhs.timestamp() : osmium::Timestamp())) <
478  const_tie(rhs.type(), rhs.id() > 0, rhs.positive_id(), rhs.version(),
479  ((lhs.timestamp().valid() && rhs.timestamp().valid()) ? rhs.timestamp() : osmium::Timestamp()));
480  }
481 
482  inline bool operator>(const OSMObject& lhs, const OSMObject& rhs) noexcept {
483  return rhs < lhs;
484  }
485 
486  inline bool operator<=(const OSMObject& lhs, const OSMObject& rhs) noexcept {
487  return !(rhs < lhs);
488  }
489 
490  inline bool operator>=(const OSMObject& lhs, const OSMObject& rhs) noexcept {
491  return !(lhs < rhs);
492  }
493 
494 } // namespace osmium
495 
496 #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:394
t_const_iterator< T > end() const
Definition: object.hpp:440
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:322
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:456
OSMObject & set_timestamp(const osmium::Timestamp &timestamp) noexcept
Definition: object.hpp:297
uint32_t item_size_type
Definition: item.hpp:57
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:404
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:372
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:368
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:448
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:435
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:376
user_id_type uid() const noexcept
Get user id of this object.
Definition: object.hpp:246
t_iterator< T > begin()
Definition: object.hpp:415
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:460
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:343
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:452
t_const_iterator< T > cend() const
Definition: object.hpp:430
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:425
unsigned char * subitems_position()
Definition: object.hpp:92
t_iterator< T > end()
Definition: object.hpp:420
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:384
const char * get_value_by_key(const char *key, const char *default_value=nullptr) const noexcept
Definition: object.hpp:332
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:380
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:441
OSMObject & set_timestamp(const char *timestamp)
Definition: object.hpp:308
Definition: object.hpp:64
iterator begin()
Definition: object.hpp:364