osrm-backend/test/t/relations/test_relations_manager.cpp

249 lines
7.6 KiB
C++
Raw Normal View History

#include "catch.hpp"
#include "utils.hpp"
#include <osmium/io/xml_input.hpp>
#include <osmium/osm/relation.hpp>
#include <osmium/relations/relations_manager.hpp>
struct EmptyRM : public osmium::relations::RelationsManager<EmptyRM, true, true, true> {
};
struct TestRM : public osmium::relations::RelationsManager<TestRM, true, true, true> {
std::size_t count_new_rels = 0;
std::size_t count_new_members = 0;
std::size_t count_complete_rels = 0;
std::size_t count_before = 0;
std::size_t count_not_in_any = 0;
std::size_t count_after = 0;
bool new_relation(const osmium::Relation& /*relation*/) noexcept {
++count_new_rels;
return true;
}
bool new_member(const osmium::Relation& /*relation*/, const osmium::RelationMember& /*member*/, std::size_t /*n*/) noexcept {
++count_new_members;
return true;
}
void complete_relation(const osmium::Relation& /*relation*/) noexcept {
++count_complete_rels;
}
void before_node(const osmium::Node& /*node*/) noexcept {
++count_before;
}
void node_not_in_any_relation(const osmium::Node& /*node*/) noexcept {
++count_not_in_any;
}
void after_node(const osmium::Node& /*node*/) noexcept {
++count_after;
}
void before_way(const osmium::Way& /*way*/) noexcept {
++count_before;
}
void way_not_in_any_relation(const osmium::Way& /*way*/) noexcept {
++count_not_in_any;
}
void after_way(const osmium::Way& /*way*/) noexcept {
++count_after;
}
void before_relation(const osmium::Relation& /*relation*/) noexcept {
++count_before;
}
void relation_not_in_any_relation(const osmium::Relation& /*relation*/) noexcept {
++count_not_in_any;
}
void after_relation(const osmium::Relation& /*relation*/) noexcept {
++count_after;
}
};
struct CallbackRM : public osmium::relations::RelationsManager<CallbackRM, true, false, false> {
std::size_t count_nodes = 0;
bool new_relation(const osmium::Relation& /*relation*/) noexcept {
return true;
}
bool new_member(const osmium::Relation& /*relation*/, const osmium::RelationMember& member, std::size_t /*n*/) noexcept {
return member.type() == osmium::item_type::node;
}
void complete_relation(const osmium::Relation& relation) noexcept {
for (const auto& member : relation.members()) {
if (member.type() == osmium::item_type::node) {
++count_nodes;
const auto* node = get_member_node(member.ref());
REQUIRE(node);
buffer().add_item(*node);
buffer().commit();
}
}
}
};
TEST_CASE("Use RelationsManager without any overloaded functions in derived class") {
osmium::io::File file{with_data_dir("t/relations/data.osm")};
EmptyRM manager;
osmium::relations::read_relations(file, manager);
REQUIRE(manager.member_nodes_database().size() == 2);
REQUIRE(manager.member_ways_database().size() == 2);
REQUIRE(manager.member_relations_database().size() == 1);
REQUIRE(manager.member_database(osmium::item_type::node).size() == 2);
REQUIRE(manager.member_database(osmium::item_type::way).size() == 2);
REQUIRE(manager.member_database(osmium::item_type::relation).size() == 1);
const auto& m = manager;
REQUIRE(m.member_database(osmium::item_type::node).size() == 2);
REQUIRE(m.member_database(osmium::item_type::way).size() == 2);
REQUIRE(m.member_database(osmium::item_type::relation).size() == 1);
osmium::io::Reader reader{file};
osmium::apply(reader, manager.handler());
reader.close();
}
TEST_CASE("Relations manager derived class") {
osmium::io::File file{with_data_dir("t/relations/data.osm")};
TestRM manager;
osmium::relations::read_relations(file, manager);
REQUIRE(manager.member_nodes_database().size() == 2);
REQUIRE(manager.member_ways_database().size() == 2);
REQUIRE(manager.member_relations_database().size() == 1);
bool callback_called = false;
osmium::io::Reader reader{file};
osmium::apply(reader, manager.handler([&](osmium::memory::Buffer&&) {
callback_called = true;
}));
reader.close();
REQUIRE_FALSE(callback_called);
REQUIRE(manager.count_new_rels == 3);
REQUIRE(manager.count_new_members == 5);
REQUIRE(manager.count_complete_rels == 2);
REQUIRE(manager.count_before == 10);
REQUIRE(manager.count_not_in_any == 6);
REQUIRE(manager.count_after == 10);
int n = 0;
manager.for_each_incomplete_relation([&](const osmium::relations::RelationHandle& handle){
++n;
REQUIRE(handle->id() == 31);
for (const auto& member : handle->members()) {
const auto* obj = manager.get_member_object(member);
if (member.ref() == 22) {
REQUIRE_FALSE(obj);
} else {
REQUIRE(obj);
}
}
});
REQUIRE(n == 1);
}
TEST_CASE("Relations manager with callback") {
osmium::io::File file{with_data_dir("t/relations/data.osm")};
CallbackRM manager;
osmium::relations::read_relations(file, manager);
REQUIRE(manager.member_nodes_database().size() == 2);
REQUIRE(manager.member_ways_database().size() == 0);
REQUIRE(manager.member_relations_database().size() == 0);
bool callback_called = false;
osmium::io::Reader reader{file};
osmium::apply(reader, manager.handler([&](osmium::memory::Buffer&& buffer) {
callback_called = true;
REQUIRE(std::distance(buffer.begin(), buffer.end()) == 2);
}));
reader.close();
REQUIRE(manager.count_nodes == 2);
REQUIRE(callback_called);
}
TEST_CASE("Relations manager reading buffer without callback") {
osmium::io::File file{with_data_dir("t/relations/data.osm")};
CallbackRM manager;
osmium::relations::read_relations(file, manager);
REQUIRE(manager.member_nodes_database().size() == 2);
REQUIRE(manager.member_ways_database().size() == 0);
REQUIRE(manager.member_relations_database().size() == 0);
osmium::io::Reader reader{file};
osmium::apply(reader, manager.handler());
reader.close();
auto buffer = manager.read();
REQUIRE(std::distance(buffer.begin(), buffer.end()) == 2);
REQUIRE(manager.count_nodes == 2);
}
TEST_CASE("Access members via RelationsManager") {
EmptyRM manager;
manager.prepare_for_lookup();
REQUIRE(nullptr == manager.get_member_node(0));
REQUIRE(nullptr == manager.get_member_way(0));
REQUIRE(nullptr == manager.get_member_relation(0));
REQUIRE(nullptr == manager.get_member_node(17));
REQUIRE(nullptr == manager.get_member_way(17));
REQUIRE(nullptr == manager.get_member_relation(17));
}
TEST_CASE("Handle duplicate members correctly") {
osmium::io::File file{with_data_dir("t/relations/dupl_member.osm")};
TestRM manager;
osmium::relations::read_relations(file, manager);
auto c = manager.member_nodes_database().count();
REQUIRE(c.tracked == 5);
REQUIRE(c.available == 0);
REQUIRE(c.removed == 0);
osmium::io::Reader reader{file};
osmium::apply(reader, manager.handler());
reader.close();
c = manager.member_nodes_database().count();
REQUIRE(c.tracked == 0);
REQUIRE(c.available == 0);
REQUIRE(c.removed == 5);
REQUIRE(manager.count_new_rels == 2);
REQUIRE(manager.count_new_members == 5);
REQUIRE(manager.count_complete_rels == 2);
REQUIRE(manager.count_not_in_any == 2); // 2 relations
}