osm_object_builder.hpp
Go to the documentation of this file.
#ifndef OSMIUM_BUILDER_OSM_OBJECT_BUILDER_HPP
#define OSMIUM_BUILDER_OSM_OBJECT_BUILDER_HPP
/*
This file is part of Osmium (http://osmcode.org/libosmium).
Copyright 2013-2016 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#include <cassert>
#include <cstddef>
#include <cstring>
#include <initializer_list>
#include <limits>
#include <new>
#include <stdexcept>
#include <string>
#include <utility>
#include <osmium/builder/builder.hpp>
#include <osmium/osm.hpp>
#include <osmium/osm/item_type.hpp>
#include <osmium/osm/location.hpp>
#include <osmium/osm/node_ref.hpp>
#include <osmium/osm/object.hpp>
#include <osmium/osm/tag.hpp>
#include <osmium/osm/types.hpp>
namespace osmium {
namespace memory {
class Buffer;
} // namespace memory
namespace builder {
class TagListBuilder : public ObjectBuilder<TagList> {
public:
explicit TagListBuilder(osmium::memory::Buffer& buffer, Builder* parent = nullptr) :
ObjectBuilder<TagList>(buffer, parent) {
}
~TagListBuilder() {
add_padding();
}
void add_tag(const char* key, const char* value) {
if (std::strlen(key) > osmium::max_osm_string_length) {
throw std::length_error("OSM tag key is too long");
}
if (std::strlen(value) > osmium::max_osm_string_length) {
throw std::length_error("OSM tag value is too long");
}
add_size(append(key) + append(value));
}
void add_tag(const char* key, const size_t key_length, const char* value, const size_t value_length) {
if (key_length > osmium::max_osm_string_length) {
throw std::length_error("OSM tag key is too long");
}
if (value_length > osmium::max_osm_string_length) {
throw std::length_error("OSM tag value is too long");
}
add_size(append(key, osmium::memory::item_size_type(key_length)) + append_zero() +
append(value, osmium::memory::item_size_type(value_length)) + append_zero());
}
void add_tag(const std::string& key, const std::string& value) {
if (key.size() > osmium::max_osm_string_length) {
throw std::length_error("OSM tag key is too long");
}
if (value.size() > osmium::max_osm_string_length) {
throw std::length_error("OSM tag value is too long");
}
add_size(append(key.data(), osmium::memory::item_size_type(key.size()) + 1) +
append(value.data(), osmium::memory::item_size_type(value.size()) + 1));
}
void add_tag(const osmium::Tag& tag) {
add_size(append(tag.key()) + append(tag.value()));
}
void add_tag(const std::pair<const char* const, const char* const>& tag) {
add_tag(tag.first, tag.second);
}
void add_tag(const std::pair<const char* const, const char*>& tag) {
add_tag(tag.first, tag.second);
}
void add_tag(const std::pair<const char*, const char* const>& tag) {
add_tag(tag.first, tag.second);
}
void add_tag(const std::pair<const char*, const char*>& tag) {
add_tag(tag.first, tag.second);
}
void add_tag(const std::pair<const std::string&, const std::string&>& tag) {
add_tag(tag.first, tag.second);
}
}; // class TagListBuilder
template <typename T>
class NodeRefListBuilder : public ObjectBuilder<T> {
public:
explicit NodeRefListBuilder(osmium::memory::Buffer& buffer, Builder* parent = nullptr) :
ObjectBuilder<T>(buffer, parent) {
}
~NodeRefListBuilder() {
static_cast<Builder*>(this)->add_padding();
}
void add_node_ref(const NodeRef& node_ref) {
new (static_cast<Builder*>(this)->reserve_space_for<osmium::NodeRef>()) osmium::NodeRef(node_ref);
static_cast<Builder*>(this)->add_size(sizeof(osmium::NodeRef));
}
void add_node_ref(const object_id_type ref, const osmium::Location& location = Location{}) {
add_node_ref(NodeRef(ref, location));
}
}; // class NodeRefListBuilder
typedef NodeRefListBuilder<WayNodeList> WayNodeListBuilder;
typedef NodeRefListBuilder<OuterRing> OuterRingBuilder;
typedef NodeRefListBuilder<InnerRing> InnerRingBuilder;
class RelationMemberListBuilder : public ObjectBuilder<RelationMemberList> {
void add_role(osmium::RelationMember& member, const char* role, const size_t length) {
if (length > osmium::max_osm_string_length) {
throw std::length_error("OSM relation member role is too long");
}
member.set_role_size(osmium::string_size_type(length) + 1);
add_size(append(role, osmium::memory::item_size_type(length)) + append_zero());
add_padding(true);
}
public:
explicit RelationMemberListBuilder(osmium::memory::Buffer& buffer, Builder* parent = nullptr) :
ObjectBuilder<RelationMemberList>(buffer, parent) {
}
~RelationMemberListBuilder() {
add_padding();
}
void add_member(osmium::item_type type, object_id_type ref, const char* role, const size_t role_length, const osmium::OSMObject* full_member = nullptr) {
osmium::RelationMember* member = reserve_space_for<osmium::RelationMember>();
new (member) osmium::RelationMember(ref, type, full_member != nullptr);
add_size(sizeof(RelationMember));
add_role(*member, role, role_length);
if (full_member) {
add_item(full_member);
}
}
void add_member(osmium::item_type type, object_id_type ref, const char* role, const osmium::OSMObject* full_member = nullptr) {
add_member(type, ref, role, std::strlen(role), full_member);
}
void add_member(osmium::item_type type, object_id_type ref, const std::string& role, const osmium::OSMObject* full_member = nullptr) {
add_member(type, ref, role.data(), role.size(), full_member);
}
}; // class RelationMemberListBuilder
class ChangesetDiscussionBuilder : public ObjectBuilder<ChangesetDiscussion> {
osmium::ChangesetComment* m_comment = nullptr;
void add_user(osmium::ChangesetComment& comment, const char* user, const size_t length) {
if (length > osmium::max_osm_string_length) {
throw std::length_error("OSM user name is too long");
}
comment.set_user_size(osmium::string_size_type(length) + 1);
add_size(append(user, osmium::memory::item_size_type(length)) + append_zero());
}
void add_text(osmium::ChangesetComment& comment, const char* text, const size_t length) {
// XXX There is no limit on the length of a comment text. We
// limit it here to 2^16-2 characters, because that's all that
// will fit into our internal data structure. This is not ideal,
// and will have to be discussed and cleared up.
if (length > std::numeric_limits<osmium::string_size_type>::max() - 1) {
throw std::length_error("OSM changeset comment is too long");
}
comment.set_text_size(osmium::string_size_type(length) + 1);
add_size(append(text, osmium::memory::item_size_type(length)) + append_zero());
add_padding(true);
}
public:
explicit ChangesetDiscussionBuilder(osmium::memory::Buffer& buffer, Builder* parent = nullptr) :
ObjectBuilder<ChangesetDiscussion>(buffer, parent) {
}
~ChangesetDiscussionBuilder() {
assert(!m_comment && "You have to always call both add_comment() and then add_comment_text() in that order for each comment!");
add_padding();
}
void add_comment(osmium::Timestamp date, osmium::user_id_type uid, const char* user) {
assert(!m_comment && "You have to always call both add_comment() and then add_comment_text() in that order for each comment!");
m_comment = reserve_space_for<osmium::ChangesetComment>();
new (m_comment) osmium::ChangesetComment(date, uid);
add_size(sizeof(ChangesetComment));
add_user(*m_comment, user, std::strlen(user));
}
void add_comment_text(const char* text) {
assert(m_comment && "You have to always call both add_comment() and then add_comment_text() in that order for each comment!");
add_text(*m_comment, text, std::strlen(text));
m_comment = nullptr;
}
void add_comment_text(const std::string& text) {
assert(m_comment && "You have to always call both add_comment() and then add_comment_text() in that order for each comment!");
add_text(*m_comment, text.c_str(), text.size());
m_comment = nullptr;
}
}; // class ChangesetDiscussionBuilder
template <typename T>
class OSMObjectBuilder : public ObjectBuilder<T> {
public:
explicit OSMObjectBuilder(osmium::memory::Buffer& buffer, Builder* parent = nullptr) :
ObjectBuilder<T>(buffer, parent) {
static_cast<Builder*>(this)->reserve_space_for<string_size_type>();
static_cast<Builder*>(this)->add_size(sizeof(string_size_type));
}
void add_tags(const std::initializer_list<std::pair<const char*, const char*>>& tags) {
osmium::builder::TagListBuilder tl_builder(static_cast<Builder*>(this)->buffer(), this);
for (const auto& p : tags) {
tl_builder.add_tag(p.first, p.second);
}
}
}; // class OSMObjectBuilder
typedef OSMObjectBuilder<osmium::Node> NodeBuilder;
typedef OSMObjectBuilder<osmium::Relation> RelationBuilder;
class WayBuilder : public OSMObjectBuilder<osmium::Way> {
public:
explicit WayBuilder(osmium::memory::Buffer& buffer, Builder* parent = nullptr) :
OSMObjectBuilder<osmium::Way>(buffer, parent) {
}
void add_node_refs(const std::initializer_list<osmium::NodeRef>& nodes) {
osmium::builder::WayNodeListBuilder builder(buffer(), this);
for (const auto& node_ref : nodes) {
builder.add_node_ref(node_ref);
}
}
}; // class WayBuilder
class AreaBuilder : public OSMObjectBuilder<osmium::Area> {
public:
explicit AreaBuilder(osmium::memory::Buffer& buffer, Builder* parent = nullptr) :
OSMObjectBuilder<osmium::Area>(buffer, parent) {
}
void initialize_from_object(const osmium::OSMObject& source) {
osmium::Area& area = object();
area.set_id(osmium::object_id_to_area_id(source.id(), source.type()));
area.set_version(source.version());
area.set_changeset(source.changeset());
area.set_timestamp(source.timestamp());
area.set_visible(source.visible());
area.set_uid(source.uid());
add_user(source.user());
}
}; // class AreaBuilder
typedef ObjectBuilder<osmium::Changeset> ChangesetBuilder;
} // namespace builder
} // namespace osmium
#endif // OSMIUM_BUILDER_OSM_OBJECT_BUILDER_HPP
osmium::builder::TagListBuilder::add_tag
void add_tag(const std::pair< const char *const, const char *const > &tag)
Definition: osm_object_builder.hpp:141
osmium::Tag
Definition: tag.hpp:48
osmium::builder::OSMObjectBuilder
Definition: osm_object_builder.hpp:337
osmium::builder::InnerRingBuilder
NodeRefListBuilder< InnerRing > InnerRingBuilder
Definition: osm_object_builder.hpp:191
osmium::builder::TagListBuilder::~TagListBuilder
~TagListBuilder()
Definition: osm_object_builder.hpp:71
osmium::ChangesetDiscussion
Definition: changeset.hpp:128
osmium::TagList
Definition: tag.hpp:105
osmium::osm_entity_bits::type
type
Definition: entity_bits.hpp:60
osmium::OSMObject::set_timestamp
OSMObject & set_timestamp(const osmium::Timestamp &timestamp) noexcept
Definition: object.hpp:284
location.hpp
osmium::Tag::value
const char * value() const
Definition: tag.hpp:83
osmium::builder::WayBuilder::WayBuilder
WayBuilder(osmium::memory::Buffer &buffer, Builder *parent=nullptr)
Definition: osm_object_builder.hpp:363
osmium::builder::AreaBuilder::AreaBuilder
AreaBuilder(osmium::memory::Buffer &buffer, Builder *parent=nullptr)
Definition: osm_object_builder.hpp:380
osmium::builder::ChangesetDiscussionBuilder::add_user
void add_user(osmium::ChangesetComment &comment, const char *user, const size_t length)
Definition: osm_object_builder.hpp:282
osmium::builder::RelationMemberListBuilder::add_member
void add_member(osmium::item_type type, object_id_type ref, const char *role, const osmium::OSMObject *full_member=nullptr)
Definition: osm_object_builder.hpp:257
osmium::builder::AreaBuilder::initialize_from_object
void initialize_from_object(const osmium::OSMObject &source)
Definition: osm_object_builder.hpp:387
osmium::builder::NodeBuilder
OSMObjectBuilder< osmium::Node > NodeBuilder
Definition: osm_object_builder.hpp:356
osmium::item_type
item_type
Definition: item_type.hpp:43
osmium::builder::TagListBuilder::add_tag
void add_tag(const osmium::Tag &tag)
Definition: osm_object_builder.hpp:132
osmium::builder::RelationMemberListBuilder::~RelationMemberListBuilder
~RelationMemberListBuilder()
Definition: osm_object_builder.hpp:219
osmium::Area
Definition: area.hpp:113
node_ref.hpp
osmium::RelationMemberList
Definition: relation.hpp:148
object.hpp
osmium::OSMObject::set_id
OSMObject & set_id(object_id_type id) noexcept
Definition: object.hpp:124
types.hpp
osmium::Way
Definition: way.hpp:65
osmium::builder::RelationMemberListBuilder::RelationMemberListBuilder
RelationMemberListBuilder(osmium::memory::Buffer &buffer, Builder *parent=nullptr)
Definition: osm_object_builder.hpp:215
osmium::ChangesetComment
Definition: changeset.hpp:57
osmium::builder::ChangesetDiscussionBuilder
Definition: osm_object_builder.hpp:278
item_type.hpp
tag.hpp
osmium::object_id_to_area_id
osmium::object_id_type object_id_to_area_id(osmium::object_id_type id, osmium::item_type type) noexcept
Definition: area.hpp:92
osmium::builder::WayNodeListBuilder
NodeRefListBuilder< WayNodeList > WayNodeListBuilder
Definition: osm_object_builder.hpp:189
osmium::builder::ChangesetDiscussionBuilder::add_text
void add_text(osmium::ChangesetComment &comment, const char *text, const size_t length)
Definition: osm_object_builder.hpp:290
osmium::builder::NodeRefListBuilder
Definition: osm_object_builder.hpp:166
osmium::builder::TagListBuilder::add_tag
void add_tag(const std::pair< const std::string &, const std::string & > &tag)
Definition: osm_object_builder.hpp:159
osmium::builder::TagListBuilder::add_tag
void add_tag(const char *key, const size_t key_length, const char *value, const size_t value_length)
Definition: osm_object_builder.hpp:99
osmium::RelationMember
Definition: relation.hpp:54
osmium::builder::TagListBuilder::add_tag
void add_tag(const std::pair< const char *const, const char * > &tag)
Definition: osm_object_builder.hpp:144
osmium::object_id_type
int64_t object_id_type
Type for OSM object (node, way, or relation) IDs.
Definition: types.hpp:45
osmium
Namespace for everything in the Osmium library.
Definition: assembler.hpp:59
osmium::builder::OSMObjectBuilder::add_tags
void add_tags(const std::initializer_list< std::pair< const char *, const char * >> &tags)
Definition: osm_object_builder.hpp:347
osmium::builder::WayBuilder::add_node_refs
void add_node_refs(const std::initializer_list< osmium::NodeRef > &nodes)
Definition: osm_object_builder.hpp:367
osmium::builder::ChangesetDiscussionBuilder::add_comment
void add_comment(osmium::Timestamp date, osmium::user_id_type uid, const char *user)
Definition: osm_object_builder.hpp:314
osmium::Timestamp
Definition: timestamp.hpp:56
osmium::builder::OSMObjectBuilder::OSMObjectBuilder
OSMObjectBuilder(osmium::memory::Buffer &buffer, Builder *parent=nullptr)
Definition: osm_object_builder.hpp:341
osmium::string_size_type
uint16_t string_size_type
Definition: types.hpp:59
osmium::builder::TagListBuilder::add_tag
void add_tag(const std::pair< const char *, const char * > &tag)
Definition: osm_object_builder.hpp:150
osmium::builder::OuterRingBuilder
NodeRefListBuilder< OuterRing > OuterRingBuilder
Definition: osm_object_builder.hpp:190
osmium::OSMObject::uid
user_id_type uid() const noexcept
Get user id of this object.
Definition: object.hpp:234
osmium::OSMObject::changeset
changeset_id_type changeset() const noexcept
Get changeset id of this object.
Definition: object.hpp:210
osmium::OSMObject::set_changeset
OSMObject & set_changeset(changeset_id_type changeset) noexcept
Definition: object.hpp:219
osmium::builder::RelationMemberListBuilder::add_member
void add_member(osmium::item_type type, object_id_type ref, const char *role, const size_t role_length, const osmium::OSMObject *full_member=nullptr)
Definition: osm_object_builder.hpp:236
osmium::builder::TagListBuilder::add_tag
void add_tag(const std::pair< const char *, const char *const > &tag)
Definition: osm_object_builder.hpp:147
osmium::Location
Definition: location.hpp:79
osmium::builder::WayBuilder
Definition: osm_object_builder.hpp:359
osmium::ChangesetComment::set_text_size
void set_text_size(string_size_type size) noexcept
Definition: changeset.hpp:95
osmium::OSMObject::id
object_id_type id() const noexcept
Get ID of this object.
Definition: object.hpp:110
osmium::OSMObject::set_version
OSMObject & set_version(object_version_type version) noexcept
Definition: object.hpp:195
osmium::OSMObject::version
object_version_type version() const noexcept
Get version of this object.
Definition: object.hpp:186
osmium::RelationMember::set_role_size
void set_role_size(string_size_type size) noexcept
Definition: relation.hpp:94
osmium::builder::RelationMemberListBuilder::add_member
void add_member(osmium::item_type type, object_id_type ref, const std::string &role, const osmium::OSMObject *full_member=nullptr)
Definition: osm_object_builder.hpp:272
detail::add_user
void add_user(TBuilder &builder, const TArgs &...args)
Definition: attr.hpp:584
osmium::builder::NodeRefListBuilder::NodeRefListBuilder
NodeRefListBuilder(osmium::memory::Buffer &buffer, Builder *parent=nullptr)
Definition: osm_object_builder.hpp:170
osmium::builder::ChangesetDiscussionBuilder::add_comment_text
void add_comment_text(const char *text)
Definition: osm_object_builder.hpp:322
osmium::memory::Buffer
Definition: buffer.hpp:97
osmium::Tag::key
const char * key() const noexcept
Definition: tag.hpp:79
osmium::builder::ObjectBuilder
Definition: builder.hpp:186
builder.hpp
osmium::ChangesetComment::set_user_size
void set_user_size(string_size_type size) noexcept
Definition: changeset.hpp:91
osmium::OSMObject::set_visible
OSMObject & set_visible(bool visible) noexcept
Definition: object.hpp:163
osmium::builder::NodeRefListBuilder::~NodeRefListBuilder
~NodeRefListBuilder()
Definition: osm_object_builder.hpp:174
osmium::builder::ChangesetDiscussionBuilder::add_comment_text
void add_comment_text(const std::string &text)
Definition: osm_object_builder.hpp:328
osmium::builder::ChangesetBuilder
ObjectBuilder< osmium::Changeset > ChangesetBuilder
Definition: osm_object_builder.hpp:401
osmium::OSMObject::visible
bool visible() const noexcept
Is this object marked visible (ie not deleted)?
Definition: object.hpp:144
osmium::builder::RelationMemberListBuilder::add_role
void add_role(osmium::RelationMember &member, const char *role, const size_t length)
Definition: osm_object_builder.hpp:204
osmium::memory::item_size_type
uint32_t item_size_type
Definition: item.hpp:50
osmium::builder::NodeRefListBuilder::add_node_ref
void add_node_ref(const object_id_type ref, const osmium::Location &location=Location{})
Definition: osm_object_builder.hpp:183
osmium::builder::RelationBuilder
OSMObjectBuilder< osmium::Relation > RelationBuilder
Definition: osm_object_builder.hpp:357
osmium::builder::ChangesetDiscussionBuilder::~ChangesetDiscussionBuilder
~ChangesetDiscussionBuilder()
Definition: osm_object_builder.hpp:309
osmium::builder::TagListBuilder::add_tag
void add_tag(const std::string &key, const std::string &value)
Definition: osm_object_builder.hpp:116
osm.hpp
osmium::osm_entity_bits::object
node, way, relation, or area object
Definition: entity_bits.hpp:69
osmium::NodeRef
Definition: node_ref.hpp:50
osmium::OSMObject::user
const char * user() const noexcept
Get user name for this object.
Definition: object.hpp:290
osmium::memory::Item::type
item_type type() const noexcept
Definition: item.hpp:155
osmium::OSMObject::timestamp
osmium::Timestamp timestamp() const noexcept
Get timestamp when this object last changed.
Definition: object.hpp:274
osmium::OSMObject::set_uid
OSMObject & set_uid(user_id_type uid) noexcept
Definition: object.hpp:243
osmium::builder::Builder
Definition: builder.hpp:57
osmium::builder::RelationMemberListBuilder
Definition: osm_object_builder.hpp:193
osmium::max_osm_string_length
constexpr const int max_osm_string_length
Definition: types.hpp:62
osmium::builder::TagListBuilder::TagListBuilder
TagListBuilder(osmium::memory::Buffer &buffer, Builder *parent=nullptr)
Definition: osm_object_builder.hpp:67
osmium::builder::TagListBuilder::add_tag
void add_tag(const char *key, const char *value)
Definition: osm_object_builder.hpp:81
osmium::builder::ChangesetDiscussionBuilder::ChangesetDiscussionBuilder
ChangesetDiscussionBuilder(osmium::memory::Buffer &buffer, Builder *parent=nullptr)
Definition: osm_object_builder.hpp:305
osmium::OSMObject
Definition: object.hpp:58
osmium::user_id_type
uint32_t user_id_type
Type for OSM user IDs.
Definition: types.hpp:49
osmium::builder::TagListBuilder
Definition: osm_object_builder.hpp:63
osmium::builder::NodeRefListBuilder::add_node_ref
void add_node_ref(const NodeRef &node_ref)
Definition: osm_object_builder.hpp:178
osmium::builder::AreaBuilder
Definition: osm_object_builder.hpp:376