osrm-backend/third_party/libosmium/test/t/builder/test_attr.cpp

568 lines
17 KiB
C++

#include "catch.hpp"
#include <cstdint>
#include <initializer_list>
#include <string>
#include <type_traits>
#include <utility>
#include <vector>
#include <osmium/builder/attr.hpp>
#include <osmium/memory/buffer.hpp>
#include <osmium/osm.hpp>
#include <osmium/osm/types.hpp>
TEST_CASE("create node using builders") {
using namespace osmium::builder::attr;
osmium::memory::Buffer buffer{1024 * 10};
SECTION("add node with only id") {
const auto pos = osmium::builder::add_node(buffer, _id(22));
const auto& node = buffer.get<osmium::Node>(pos);
REQUIRE(node.id() == 22);
REQUIRE(node.version() == 0);
REQUIRE(node.timestamp() == osmium::Timestamp{});
REQUIRE(node.changeset() == 0);
REQUIRE(node.uid() == 0);
REQUIRE(std::string(node.user()) == "");
REQUIRE(node.location() == osmium::Location{});
REQUIRE(node.tags().size() == 0);
}
SECTION("add node with complete info but no tags") {
const osmium::Location loc{3.14, 1.59};
const auto pos = osmium::builder::add_node(buffer,
_id(1),
_version(17),
_timestamp(osmium::Timestamp{"2015-01-01T10:20:30Z"}),
_cid(21),
_uid(222),
_location(loc),
_user("foo")
);
const auto& node = buffer.get<osmium::Node>(pos);
REQUIRE(node.id() == 1);
REQUIRE(node.version() == 17);
REQUIRE(node.timestamp() == osmium::Timestamp{"2015-01-01T10:20:30Z"});
REQUIRE(node.changeset() == 21);
REQUIRE(node.uid() == 222);
REQUIRE(std::string(node.user()) == "foo");
REQUIRE(node.location() == loc);
REQUIRE(node.tags().size() == 0);
REQUIRE(std::distance(node.cbegin(), node.cend()) == 0);
}
SECTION("visible/deleted flag") {
osmium::builder::add_node(buffer, _id(1), _deleted());
osmium::builder::add_node(buffer, _id(2), _deleted(true));
osmium::builder::add_node(buffer, _id(3), _deleted(false));
osmium::builder::add_node(buffer, _id(4), _visible());
osmium::builder::add_node(buffer, _id(5), _visible(true));
osmium::builder::add_node(buffer, _id(6), _visible(false));
auto it = buffer.select<osmium::Node>().cbegin();
REQUIRE_FALSE(it++->visible());
REQUIRE_FALSE(it++->visible());
REQUIRE(it++->visible());
REQUIRE(it++->visible());
REQUIRE(it++->visible());
REQUIRE_FALSE(it++->visible());
REQUIRE(it == buffer.select<osmium::Node>().cend());
}
SECTION("order of attributes doesn't matter") {
const osmium::Location loc{3.14, 1.59};
const auto pos = osmium::builder::add_node(buffer,
_timestamp("2015-01-01T10:20:30Z"),
_version(17),
_cid(21),
_uid(222),
_user(std::string("foo")),
_id(1),
_location(3.14, 1.59)
);
const auto& node = buffer.get<osmium::Node>(pos);
REQUIRE(node.id() == 1);
REQUIRE(node.version() == 17);
REQUIRE(node.timestamp() == osmium::Timestamp{"2015-01-01T10:20:30Z"});
REQUIRE(node.changeset() == 21);
REQUIRE(node.uid() == 222);
REQUIRE(std::string(node.user()) == "foo");
REQUIRE(node.location() == loc);
REQUIRE(node.tags().size() == 0);
}
SECTION("add tags using _tag") {
std::pair<const char*, const char*> t1 = {"name", "Node Inn"};
std::pair<std::string, std::string> t2 = {"phone", "+1-123-555-4567"};
const auto pos = osmium::builder::add_node(buffer,
_id(2),
_tag("amenity", "restaurant"),
_tag(t1),
_tag(t2),
_tag(std::string{"cuisine"}, std::string{"italian"})
);
const auto& node = buffer.get<osmium::Node>(pos);
REQUIRE(node.id() == 2);
REQUIRE(node.tags().size() == 4);
REQUIRE(std::distance(node.cbegin(), node.cend()) == 1);
auto it = node.tags().cbegin();
REQUIRE(std::string(it->key()) == "amenity");
REQUIRE(std::string(it->value()) == "restaurant");
++it;
REQUIRE(std::string(it->key()) == "name");
REQUIRE(std::string(it->value()) == "Node Inn");
++it;
REQUIRE(std::string(it->key()) == "phone");
REQUIRE(std::string(it->value()) == "+1-123-555-4567");
++it;
REQUIRE(std::string(it->key()) == "cuisine");
REQUIRE(std::string(it->value()) == "italian");
++it;
REQUIRE(it == node.tags().cend());
}
SECTION("add tags using _tags from initializer list") {
const auto pos = osmium::builder::add_node(buffer,
_id(3),
_tags({{"amenity", "post_box"}})
);
const auto& node = buffer.get<osmium::Node>(pos);
REQUIRE(node.id() == 3);
REQUIRE(node.tags().size() == 1);
auto it = node.tags().cbegin();
REQUIRE(std::string(it->key()) == "amenity");
REQUIRE(std::string(it->value()) == "post_box");
++it;
REQUIRE(it == node.tags().cend());
REQUIRE(std::distance(node.cbegin(), node.cend()) == 1);
}
SECTION("add tags using _tags from TagList") {
const auto pos1 = osmium::builder::add_node(buffer,
_id(3),
_tag("a", "d"),
_tag("b", "e"),
_tag("c", "f")
);
const auto& node1 = buffer.get<osmium::Node>(pos1);
const auto pos2 = osmium::builder::add_node(buffer,
_id(4),
_tags(node1.tags())
);
const auto& node2 = buffer.get<osmium::Node>(pos2);
REQUIRE(node2.id() == 4);
REQUIRE(node2.tags().size() == 3);
auto it = node2.tags().cbegin();
REQUIRE(std::string(it++->key()) == "a");
REQUIRE(std::string(it++->key()) == "b");
REQUIRE(std::string(it++->key()) == "c");
REQUIRE(it == node2.tags().cend());
REQUIRE(std::distance(node2.cbegin(), node2.cend()) == 1);
}
SECTION("add tags using mixed tag sources") {
const std::vector<pair_of_cstrings> tags = {
{"t5", "t5"},
{"t6", "t6"}
};
const auto pos = osmium::builder::add_node(buffer,
_id(4),
_tag("t1", "t1"),
_tags({{"t2", "t2"}, {"t3", "t3"}}),
_tag("t4", "t4"),
_tags(tags)
);
const auto& node = buffer.get<osmium::Node>(pos);
REQUIRE(node.id() == 4);
REQUIRE(node.tags().size() == 6);
auto it = node.tags().cbegin();
REQUIRE(std::string(it->key()) == "t1");
++it;
REQUIRE(std::string(it->key()) == "t2");
++it;
REQUIRE(std::string(it->key()) == "t3");
++it;
REQUIRE(std::string(it->key()) == "t4");
++it;
REQUIRE(std::string(it->key()) == "t5");
++it;
REQUIRE(std::string(it->key()) == "t6");
++it;
REQUIRE(it == node.tags().cend());
REQUIRE(std::distance(node.cbegin(), node.cend()) == 1);
}
}
TEST_CASE("create way using builders") {
using namespace osmium::builder::attr;
osmium::memory::Buffer buffer{1024 * 10};
SECTION("add way without nodes") {
const auto pos = osmium::builder::add_way(buffer,
_id(999),
_cid(21),
_uid(222),
_user("foo")
);
const auto& way = buffer.get<osmium::Way>(pos);
REQUIRE(way.id() == 999);
REQUIRE(way.version() == 0);
REQUIRE(way.timestamp() == osmium::Timestamp{});
REQUIRE(way.changeset() == 21);
REQUIRE(way.uid() == 222);
REQUIRE(std::string(way.user()) == "foo");
REQUIRE(way.tags().size() == 0);
REQUIRE(way.nodes().size() == 0);
REQUIRE(std::distance(way.cbegin(), way.cend()) == 0);
}
}
TEST_CASE("create way with nodes") {
std::vector<osmium::NodeRef> nrvec = {
{ 1, osmium::Location{1.1, 0.1} },
{ 2, osmium::Location{2.2, 0.2} },
{ 4, osmium::Location{4.4, 0.4} },
{ 8, osmium::Location{8.8, 0.8} }
};
using namespace osmium::builder::attr;
osmium::memory::Buffer wbuffer{1024 * 10};
osmium::builder::add_way(wbuffer,
_id(1),
_nodes({1, 2, 4, 8})
);
const osmium::NodeRefList& nodes = wbuffer.get<osmium::Way>(0).nodes();
osmium::memory::Buffer buffer{1024 * 10};
SECTION("add nodes using an OSM object id or NodeRef") {
osmium::builder::add_way(buffer,
_id(1),
_node(1),
_node(2),
_node(osmium::NodeRef{4}),
_node(8)
);
}
SECTION("add nodes using iterator list with object ids") {
osmium::builder::add_way(buffer,
_id(1),
_nodes({1, 2, 4, 8})
);
}
SECTION("add way with nodes in initializer_list of NodeRefs") {
osmium::builder::add_way(buffer,
_id(1),
_nodes({
{ 1, {1.1, 0.1} },
{ 2, {2.2, 0.2} },
{ 4, {4.4, 0.4} },
{ 8, {8.8, 0.8} }
})
);
}
SECTION("add nodes using WayNodeList") {
osmium::builder::add_way(buffer,
_id(1),
_nodes(nodes)
);
}
SECTION("add nodes using vector of OSM object ids") {
const std::vector<osmium::object_id_type> some_nodes = {
1, 2, 4, 8
};
osmium::builder::add_way(buffer,
_id(1),
_nodes(some_nodes)
);
}
SECTION("add nodes using vector of NodeRefs") {
osmium::builder::add_way(buffer,
_id(1),
_nodes(nrvec)
);
}
SECTION("add nodes using different means together") {
osmium::builder::add_way(buffer,
_id(1),
_node(1),
_nodes({2, 4}),
_node(8)
);
}
SECTION("add nodes using different means together") {
osmium::builder::add_way(buffer,
_id(1),
_nodes(nodes.begin(), nodes.begin() + 1),
_nodes({2, 4, 8})
);
}
const auto& way = buffer.get<osmium::Way>(0);
REQUIRE(way.id() == 1);
REQUIRE(way.nodes().size() == 4);
REQUIRE(std::distance(way.cbegin(), way.cend()) == 1);
auto it = way.nodes().cbegin();
REQUIRE(it->ref() == 1);
if (it->location().valid()) {
REQUIRE(*it == nrvec[0]);
}
it++;
REQUIRE(it->ref() == 2);
if (it->location().valid()) {
REQUIRE(*it == nrvec[1]);
}
it++;
REQUIRE(it->ref() == 4);
if (it->location().valid()) {
REQUIRE(*it == nrvec[2]);
}
it++;
REQUIRE(it->ref() == 8);
if (it->location().valid()) {
REQUIRE(*it == nrvec[3]);
}
it++;
REQUIRE(it == way.nodes().cend());
}
TEST_CASE("create relation using builders") {
using namespace osmium::builder::attr;
osmium::memory::Buffer buffer{1024 * 10};
SECTION("create relation") {
osmium::builder::attr::member_type m{osmium::item_type::way, 113, "inner"};
osmium::builder::add_relation(buffer,
_id(123),
_member(osmium::item_type::node, 123, ""),
_member(osmium::item_type::node, 132),
_member(osmium::item_type::way, 111, "outer"),
_member(osmium::builder::attr::member_type{osmium::item_type::way, 112, "inner"}),
_member(m)
);
const auto& relation = buffer.get<osmium::Relation>(0);
REQUIRE(relation.id() == 123);
REQUIRE(relation.members().size() == 5);
REQUIRE(std::distance(relation.cbegin(), relation.cend()) == 1);
auto it = relation.members().begin();
REQUIRE(it->type() == osmium::item_type::node);
REQUIRE(it->ref() == 123);
REQUIRE(std::string(it->role()) == "");
++it;
REQUIRE(it->type() == osmium::item_type::node);
REQUIRE(it->ref() == 132);
REQUIRE(std::string(it->role()) == "");
++it;
REQUIRE(it->type() == osmium::item_type::way);
REQUIRE(it->ref() == 111);
REQUIRE(std::string(it->role()) == "outer");
++it;
REQUIRE(it->type() == osmium::item_type::way);
REQUIRE(it->ref() == 112);
REQUIRE(std::string(it->role()) == "inner");
++it;
REQUIRE(it->type() == osmium::item_type::way);
REQUIRE(it->ref() == 113);
REQUIRE(std::string(it->role()) == "inner");
++it;
REQUIRE(it == relation.members().end());
}
SECTION("create relation member from existing relation member") {
osmium::builder::add_relation(buffer,
_id(123),
_member(osmium::item_type::way, 111, "outer"),
_member(osmium::item_type::way, 112, "inner")
);
const auto& relation1 = buffer.get<osmium::Relation>(0);
const auto pos = osmium::builder::add_relation(buffer,
_id(124),
_member(*relation1.members().begin()),
_members(std::next(relation1.members().begin()), relation1.members().end())
);
const auto& relation = buffer.get<osmium::Relation>(pos);
REQUIRE(relation.id() == 124);
REQUIRE(relation.members().size() == 2);
auto it = relation.members().begin();
REQUIRE(it->type() == osmium::item_type::way);
REQUIRE(it->ref() == 111);
REQUIRE(std::string(it->role()) == "outer");
++it;
REQUIRE(it->type() == osmium::item_type::way);
REQUIRE(it->ref() == 112);
REQUIRE(std::string(it->role()) == "inner");
++it;
REQUIRE(it == relation.members().end());
}
SECTION("create relation with members from initializer list") {
const auto pos = osmium::builder::add_relation(buffer,
_id(123),
_members({
{osmium::item_type::node, 123, ""},
{osmium::item_type::way, 111, "outer"}
})
);
const auto& relation = buffer.get<osmium::Relation>(pos);
REQUIRE(relation.id() == 123);
REQUIRE(relation.members().size() == 2);
REQUIRE(std::distance(relation.cbegin(), relation.cend()) == 1);
auto it = relation.members().begin();
REQUIRE(it->type() == osmium::item_type::node);
REQUIRE(it->ref() == 123);
REQUIRE(std::string(it->role()) == "");
++it;
REQUIRE(it->type() == osmium::item_type::way);
REQUIRE(it->ref() == 111);
REQUIRE(std::string(it->role()) == "outer");
++it;
REQUIRE(it == relation.members().end());
}
SECTION("create relation with members from iterators and some tags") {
const std::vector<member_type> members = {
{osmium::item_type::node, 123},
{osmium::item_type::way, 111, "outer"}
};
SECTION("using iterators") {
osmium::builder::add_relation(buffer,
_id(123),
_members(members.begin(), members.end()),
_tag("a", "x"),
_tag("b", "y")
);
}
SECTION("using container") {
osmium::builder::add_relation(buffer,
_id(123),
_members(members),
_tag("a", "x"),
_tag("b", "y")
);
}
const auto& relation = buffer.get<osmium::Relation>(0);
REQUIRE(relation.id() == 123);
REQUIRE(relation.members().size() == 2);
REQUIRE(relation.tags().size() == 2);
REQUIRE(std::distance(relation.cbegin(), relation.cend()) == 2);
auto it = relation.members().begin();
REQUIRE(it->type() == osmium::item_type::node);
REQUIRE(it->ref() == 123);
REQUIRE(std::string(it->role()) == "");
++it;
REQUIRE(it->type() == osmium::item_type::way);
REQUIRE(it->ref() == 111);
REQUIRE(std::string(it->role()) == "outer");
++it;
REQUIRE(it == relation.members().end());
}
}
TEST_CASE("create area using builders") {
using namespace osmium::builder::attr;
osmium::memory::Buffer buffer{1024 * 10};
SECTION("add area without rings") {
const auto pos = osmium::builder::add_area(buffer,
_id(999),
_cid(21),
_uid(222),
_user("foo"),
_tag("landuse", "residential")
);
const auto& area = buffer.get<osmium::Area>(pos);
REQUIRE(area.id() == 999);
REQUIRE(area.version() == 0);
REQUIRE(area.timestamp() == osmium::Timestamp{});
REQUIRE(area.changeset() == 21);
REQUIRE(area.uid() == 222);
REQUIRE(std::string(area.user()) == "foo");
REQUIRE(area.tags().size() == 1);
REQUIRE(std::distance(area.cbegin(), area.cend()) == 1);
}
}