Squashed 'third_party/libosmium/' content from commit ce865381f

git-subtree-dir: third_party/libosmium
git-subtree-split: ce865381fb752323ff1e66181f5a49b7f500ffa3
This commit is contained in:
Patrick Niklaus
2017-08-30 09:30:27 +00:00
commit 6eb4f090f9
434 changed files with 81367 additions and 0 deletions
+84
View File
@@ -0,0 +1,84 @@
#include "catch.hpp"
#include <boost/crc.hpp>
#include <osmium/builder/attr.hpp>
#include <osmium/osm/crc.hpp>
#include <osmium/osm/area.hpp>
using namespace osmium::builder::attr;
TEST_CASE("Build area") {
osmium::memory::Buffer buffer(10000);
osmium::builder::add_area(buffer,
_id(17),
_version(3),
_visible(),
_cid(333),
_uid(21),
_timestamp(time_t(123)),
_user("foo"),
_tag("landuse", "forest"),
_tag("name", "Sherwood Forest"),
_outer_ring({
{1, {3.2, 4.2}},
{2, {3.5, 4.7}},
{3, {3.6, 4.9}},
{1, {3.2, 4.2}}
}),
_inner_ring({
{5, {1.0, 1.0}},
{6, {8.0, 1.0}},
{7, {8.0, 8.0}},
{8, {1.0, 8.0}},
{5, {1.0, 1.0}}
})
);
const osmium::Area& area = buffer.get<osmium::Area>(0);
REQUIRE(17 == area.id());
REQUIRE(3 == area.version());
REQUIRE(true == area.visible());
REQUIRE(333 == area.changeset());
REQUIRE(21 == area.uid());
REQUIRE(std::string("foo") == area.user());
REQUIRE(123 == uint32_t(area.timestamp()));
REQUIRE(2 == area.tags().size());
int inner = 0;
int outer = 0;
for (const auto& subitem : area) {
switch (subitem.type()) {
case osmium::item_type::outer_ring: {
const auto& ring = static_cast<const osmium::OuterRing&>(subitem);
REQUIRE(ring.size() == 4);
++outer;
}
break;
case osmium::item_type::inner_ring: {
const auto& ring = static_cast<const osmium::OuterRing&>(subitem);
REQUIRE(ring.size() == 5);
++inner;
}
break;
default:
break;
}
}
REQUIRE(outer == 1);
REQUIRE(inner == 1);
osmium::CRC<boost::crc_32_type> crc32;
crc32.update(area);
REQUIRE(crc32().checksum() == 0x2b2b7fa0);
const osmium::Box envelope = area.envelope();
REQUIRE(envelope.bottom_left().lon() == Approx(3.2));
REQUIRE(envelope.bottom_left().lat() == Approx(4.2));
REQUIRE(envelope.top_right().lon() == Approx(3.6));
REQUIRE(envelope.top_right().lat() == Approx(4.9));
}
+172
View File
@@ -0,0 +1,172 @@
#include "catch.hpp"
#include <sstream>
#include <boost/crc.hpp>
#include <osmium/osm/box.hpp>
#include <osmium/osm/crc.hpp>
#include <osmium/geom/relations.hpp>
TEST_CASE("Default constructor creates invalid box") {
const osmium::Box b;
REQUIRE_FALSE(b);
REQUIRE_FALSE(b.bottom_left());
REQUIRE_FALSE(b.top_right());
REQUIRE_THROWS_AS(b.size(), const osmium::invalid_location&);
}
TEST_CASE("Extend box with undefined") {
osmium::Box b;
REQUIRE_FALSE(b);
b.extend(osmium::Location{});
REQUIRE_FALSE(b);
REQUIRE_FALSE(b.bottom_left());
REQUIRE_FALSE(b.top_right());
}
TEST_CASE("Extend box with invalid") {
osmium::Box b;
REQUIRE_FALSE(b);
b.extend(osmium::Location{200.0, 100.0});
REQUIRE_FALSE(b);
REQUIRE_FALSE(b.bottom_left());
REQUIRE_FALSE(b.top_right());
}
TEST_CASE("Extend box with valid") {
osmium::Box b;
const osmium::Location loc1{1.2, 3.4};
b.extend(loc1);
REQUIRE(!!b);
REQUIRE(!!b.bottom_left());
REQUIRE(!!b.top_right());
REQUIRE(b.contains(loc1));
const osmium::Location loc2{3.4, 4.5};
const osmium::Location loc3{5.6, 7.8};
b.extend(loc2);
b.extend(loc3);
REQUIRE(b.bottom_left() == osmium::Location(1.2, 3.4));
REQUIRE(b.top_right() == osmium::Location(5.6, 7.8));
// extend with undefined doesn't change anything
b.extend(osmium::Location{});
REQUIRE(b.bottom_left() == osmium::Location(1.2, 3.4));
REQUIRE(b.top_right() == osmium::Location(5.6, 7.8));
REQUIRE(b.contains(loc1));
REQUIRE(b.contains(loc2));
REQUIRE(b.contains(loc3));
osmium::CRC<boost::crc_32_type> crc32;
crc32.update(b);
REQUIRE(crc32().checksum() == 0xd381a838);
}
TEST_CASE("Output of defined Box") {
osmium::Box b;
b.extend(osmium::Location{1.2, 3.4});
b.extend(osmium::Location{5.6, 7.8});
std::stringstream out;
out << b;
REQUIRE(out.str() == "(1.2,3.4,5.6,7.8)");
REQUIRE(b.size() == Approx(19.36).epsilon(0.000001));
}
TEST_CASE("Output of undefined Box") {
const osmium::Box b;
std::stringstream out;
out << b;
REQUIRE(out.str() == "(undefined)");
}
TEST_CASE("Output of undefined Box (bottom left)") {
osmium::Box b;
b.top_right() = osmium::Location(1.2, 3.4);
std::stringstream out;
out << b;
REQUIRE(out.str() == "(undefined)");
}
TEST_CASE("Output of undefined Box (top right)") {
osmium::Box b;
b.bottom_left() = osmium::Location(1.2, 3.4);
std::stringstream out;
out << b;
REQUIRE(out.str() == "(undefined)");
}
TEST_CASE("Create box from locations") {
const osmium::Box b{osmium::Location{1.23, 2.34}, osmium::Location{3.45, 4.56}};
REQUIRE(!!b);
REQUIRE(b.bottom_left() == (osmium::Location{1.23, 2.34}));
REQUIRE(b.top_right() == (osmium::Location{3.45, 4.56}));
}
TEST_CASE("Create box from doubles") {
const osmium::Box b{1.23, 2.34, 3.45, 4.56};
REQUIRE(!!b);
REQUIRE(b.bottom_left() == (osmium::Location{1.23, 2.34}));
REQUIRE(b.top_right() == (osmium::Location{3.45, 4.56}));
}
TEST_CASE("Relationship between boxes: contains") {
osmium::Box outer;
outer.extend(osmium::Location{1, 1});
outer.extend(osmium::Location{10, 10});
osmium::Box inner;
inner.extend(osmium::Location{2, 2});
inner.extend(osmium::Location{4, 4});
osmium::Box overlap;
overlap.extend(osmium::Location{3, 3});
overlap.extend(osmium::Location{5, 5});
REQUIRE( osmium::geom::contains(inner, outer));
REQUIRE_FALSE(osmium::geom::contains(outer, inner));
REQUIRE_FALSE(osmium::geom::contains(overlap, inner));
REQUIRE_FALSE(osmium::geom::contains(inner, overlap));
}
TEST_CASE("Relationship between boxes: overlaps") {
osmium::Box outer;
outer.extend(osmium::Location{1, 1});
outer.extend(osmium::Location{10, 10});
osmium::Box inner;
inner.extend(osmium::Location{2, 2});
inner.extend(osmium::Location{4, 4});
osmium::Box overlap;
overlap.extend(osmium::Location{3, 3});
overlap.extend(osmium::Location{5, 5});
osmium::Box outside;
overlap.extend(osmium::Location{30, 30});
overlap.extend(osmium::Location{50, 50});
REQUIRE(osmium::geom::overlaps(inner, outer));
REQUIRE(osmium::geom::overlaps(outer, inner));
REQUIRE(osmium::geom::overlaps(overlap, inner));
REQUIRE(osmium::geom::overlaps(inner, overlap));
REQUIRE_FALSE(osmium::geom::overlaps(outside, inner));
REQUIRE_FALSE(osmium::geom::overlaps(inner, outside));
}
+144
View File
@@ -0,0 +1,144 @@
#include "catch.hpp"
#include <boost/crc.hpp>
#include <osmium/builder/attr.hpp>
#include <osmium/osm/changeset.hpp>
#include <osmium/osm/crc.hpp>
using namespace osmium::builder::attr;
TEST_CASE("Build changeset") {
osmium::memory::Buffer buffer{10 * 1000};
osmium::builder::add_changeset(buffer,
_cid(42),
_created_at(time_t(100)),
_closed_at(time_t(200)),
_num_changes(7),
_num_comments(3),
_uid(9),
_user("user"),
_tag("comment", "foo")
);
const osmium::Changeset& cs1 = buffer.get<osmium::Changeset>(0);
REQUIRE(42 == cs1.id());
REQUIRE(9 == cs1.uid());
REQUIRE(7 == cs1.num_changes());
REQUIRE(3 == cs1.num_comments());
REQUIRE(true == cs1.closed());
REQUIRE(osmium::Timestamp(100) == cs1.created_at());
REQUIRE(osmium::Timestamp(200) == cs1.closed_at());
REQUIRE(1 == cs1.tags().size());
REQUIRE(std::string("user") == cs1.user());
osmium::CRC<boost::crc_32_type> crc32;
crc32.update(cs1);
REQUIRE(crc32().checksum() == 0x502e8c0e);
const auto pos = osmium::builder::add_changeset(buffer,
_cid(43),
_created_at(time_t(120)),
_num_changes(21),
_num_comments(0),
_uid(9),
_user("user"),
_tag("comment", "foo"),
_tag("foo", "bar"),
_comment({time_t(300), 10, "user2", "foo"}),
_comments({{time_t(400), 9, "user", "bar"}})
);
const osmium::Changeset& cs2 = buffer.get<osmium::Changeset>(pos);
REQUIRE(43 == cs2.id());
REQUIRE(9 == cs2.uid());
REQUIRE(21 == cs2.num_changes());
REQUIRE(0 == cs2.num_comments());
REQUIRE(false == cs2.closed());
REQUIRE(osmium::Timestamp(120) == cs2.created_at());
REQUIRE(osmium::Timestamp() == cs2.closed_at());
REQUIRE(2 == cs2.tags().size());
REQUIRE(std::string("user") == cs2.user());
REQUIRE(cs1 != cs2);
REQUIRE(cs1 < cs2);
REQUIRE(cs1 <= cs2);
REQUIRE(false == (cs1 > cs2));
REQUIRE(false == (cs1 >= cs2));
auto cit = cs2.discussion().begin();
REQUIRE(cit != cs2.discussion().end());
REQUIRE(cit->date() == osmium::Timestamp(300));
REQUIRE(cit->uid() == 10);
REQUIRE(std::string("user2") == cit->user());
REQUIRE(std::string("foo") == cit->text());
REQUIRE(++cit != cs2.discussion().end());
REQUIRE(cit->date() == osmium::Timestamp(400));
REQUIRE(cit->uid() == 9);
REQUIRE(std::string("user") == cit->user());
REQUIRE(std::string("bar") == cit->text());
REQUIRE(++cit == cs2.discussion().end());
}
TEST_CASE("Create changeset without helper") {
osmium::memory::Buffer buffer{10 * 1000};
{
osmium::builder::ChangesetBuilder builder{buffer};
builder.set_id(42)
.set_created_at(100)
.set_closed_at(200)
.set_num_changes(7)
.set_num_comments(2)
.set_uid(9)
.set_user("user");
{
osmium::builder::TagListBuilder tl_builder{builder};
tl_builder.add_tag("key1", "val1");
tl_builder.add_tag("key2", "val2");
}
osmium::builder::ChangesetDiscussionBuilder disc_builder{builder};
disc_builder.add_comment(osmium::Timestamp(300), 10, "user2");
disc_builder.add_comment_text("foo");
disc_builder.add_comment(osmium::Timestamp(400), 9, "user");
disc_builder.add_comment_text("bar");
}
const auto& cs = buffer.get<osmium::Changeset>(buffer.commit());
REQUIRE(42 == cs.id());
REQUIRE(9 == cs.uid());
REQUIRE(7 == cs.num_changes());
REQUIRE(2 == cs.num_comments());
REQUIRE(true == cs.closed());
REQUIRE(osmium::Timestamp(100) == cs.created_at());
REQUIRE(osmium::Timestamp(200) == cs.closed_at());
REQUIRE(2 == cs.tags().size());
REQUIRE(std::string("user") == cs.user());
auto cit = cs.discussion().begin();
REQUIRE(cit != cs.discussion().end());
REQUIRE(cit->date() == osmium::Timestamp(300));
REQUIRE(cit->uid() == 10);
REQUIRE(std::string("user2") == cit->user());
REQUIRE(std::string("foo") == cit->text());
REQUIRE(++cit != cs.discussion().end());
REQUIRE(cit->date() == osmium::Timestamp(400));
REQUIRE(cit->uid() == 9);
REQUIRE(std::string("user") == cit->user());
REQUIRE(std::string("bar") == cit->text());
REQUIRE(++cit == cs.discussion().end());
}
+78
View File
@@ -0,0 +1,78 @@
#include "catch.hpp"
#include <boost/crc.hpp>
#include <osmium/osm/crc.hpp>
TEST_CASE("CRC of bool") {
osmium::CRC<boost::crc_32_type> crc32;
crc32.update_bool(true);
crc32.update_bool(false);
REQUIRE(crc32().checksum() == 0x58c223be);
}
TEST_CASE("CRC of char") {
osmium::CRC<boost::crc_32_type> crc32;
crc32.update_int8('x');
crc32.update_int8('y');
REQUIRE(crc32().checksum() == 0x8fe62899);
}
TEST_CASE("CRC of int16") {
osmium::CRC<boost::crc_32_type> crc32;
crc32.update_int16(0x0123U);
crc32.update_int16(0x1234U);
REQUIRE(crc32().checksum() == 0xda923744);
}
TEST_CASE("CRC of int32") {
osmium::CRC<boost::crc_32_type> crc32;
crc32.update_int32(0x01234567UL);
crc32.update_int32(0x12345678UL);
REQUIRE(crc32().checksum() == 0x9b4e2af3);
}
TEST_CASE("CRC of int64") {
osmium::CRC<boost::crc_32_type> crc32;
crc32.update_int64(0x0123456789abcdefULL);
crc32.update_int64(0x123456789abcdef0ULL);
REQUIRE(crc32().checksum() == 0x6d8b7267);
}
TEST_CASE("CRC of string") {
osmium::CRC<boost::crc_32_type> crc32;
const char* str = "foobar";
crc32.update_string(str);
REQUIRE(crc32().checksum() == 0x9ef61f95);
}
TEST_CASE("CRC of Timestamp") {
osmium::CRC<boost::crc_32_type> crc32;
const osmium::Timestamp t{"2015-07-12T13:10:46Z"};
crc32.update(t);
REQUIRE(crc32().checksum() == 0x58a29d7);
}
TEST_CASE("CRC of Location") {
osmium::CRC<boost::crc_32_type> crc32;
const osmium::Location loc{3.46, 2.001};
crc32.update(loc);
REQUIRE(crc32().checksum() == 0xddee042c);
}
+62
View File
@@ -0,0 +1,62 @@
#include "catch.hpp"
#include <osmium/osm/entity_bits.hpp>
static_assert((osmium::osm_entity_bits::node
|osmium::osm_entity_bits::way
|osmium::osm_entity_bits::relation)
== osmium::osm_entity_bits::nwr, "entity_bits nwr failed");
static_assert((osmium::osm_entity_bits::node
|osmium::osm_entity_bits::way
|osmium::osm_entity_bits::relation
|osmium::osm_entity_bits::area)
== osmium::osm_entity_bits::nwra, "entity_bits nwra failed");
static_assert((osmium::osm_entity_bits::nwra
|osmium::osm_entity_bits::changeset)
== osmium::osm_entity_bits::all, "entity_bits all failed");
static_assert((osmium::osm_entity_bits::all
&osmium::osm_entity_bits::node)
== osmium::osm_entity_bits::node, "entity_bits node failed");
static_assert((~osmium::osm_entity_bits::all) == osmium::osm_entity_bits::nothing, "entity_bits nothing is the inverse of all");
static_assert((~osmium::osm_entity_bits::nothing) == osmium::osm_entity_bits::all, "entity_bits all is the inverse of nothing");
static_assert((~osmium::osm_entity_bits::changeset) == osmium::osm_entity_bits::nwra, "entity_bits nwra is the inverse of changeset");
TEST_CASE("Bitwise 'and' and 'or' on entity bits") {
osmium::osm_entity_bits::type entities = osmium::osm_entity_bits::node | osmium::osm_entity_bits::way;
REQUIRE(entities == (osmium::osm_entity_bits::node | osmium::osm_entity_bits::way));
entities |= osmium::osm_entity_bits::relation;
REQUIRE((entities & osmium::osm_entity_bits::object));
entities |= osmium::osm_entity_bits::area;
REQUIRE(entities == osmium::osm_entity_bits::object);
REQUIRE_FALSE((entities & osmium::osm_entity_bits::changeset));
entities &= osmium::osm_entity_bits::node;
REQUIRE((entities & osmium::osm_entity_bits::node));
REQUIRE_FALSE((entities & osmium::osm_entity_bits::way));
REQUIRE(entities == osmium::osm_entity_bits::node);
}
TEST_CASE("Bitwise 'not' on entity bits") {
REQUIRE(~osmium::osm_entity_bits::all == osmium::osm_entity_bits::nothing);
REQUIRE(~osmium::osm_entity_bits::nothing == osmium::osm_entity_bits::all);
REQUIRE(~osmium::osm_entity_bits::node == (osmium::osm_entity_bits::way | osmium::osm_entity_bits::relation | osmium::osm_entity_bits::area | osmium::osm_entity_bits::changeset));
REQUIRE(~osmium::osm_entity_bits::nwr == (osmium::osm_entity_bits::area | osmium::osm_entity_bits::changeset));
REQUIRE(~osmium::osm_entity_bits::nwra == osmium::osm_entity_bits::changeset);
}
TEST_CASE("Converting item types to entity bits") {
REQUIRE(osmium::osm_entity_bits::nothing == osmium::osm_entity_bits::from_item_type(osmium::item_type::undefined));
REQUIRE(osmium::osm_entity_bits::node == osmium::osm_entity_bits::from_item_type(osmium::item_type::node));
REQUIRE(osmium::osm_entity_bits::way == osmium::osm_entity_bits::from_item_type(osmium::item_type::way));
REQUIRE(osmium::osm_entity_bits::relation == osmium::osm_entity_bits::from_item_type(osmium::item_type::relation));
REQUIRE(osmium::osm_entity_bits::changeset == osmium::osm_entity_bits::from_item_type(osmium::item_type::changeset));
REQUIRE(osmium::osm_entity_bits::area == osmium::osm_entity_bits::from_item_type(osmium::item_type::area));
}
+428
View File
@@ -0,0 +1,428 @@
#include "catch.hpp"
#include <limits>
#include <sstream>
#include <type_traits>
#include <osmium/osm/location.hpp>
// fails on MSVC and doesn't really matter
// static_assert(std::is_literal_type<osmium::Location>::value, "osmium::Location not literal type");
TEST_CASE("Location instantiation with default parameters") {
const osmium::Location loc;
REQUIRE_FALSE(loc);
REQUIRE_FALSE(loc.is_defined());
REQUIRE(loc.is_undefined());
REQUIRE_THROWS_AS(loc.lon(), const osmium::invalid_location&);
REQUIRE_THROWS_AS(loc.lat(), const osmium::invalid_location&);
}
TEST_CASE("Location instantiation with double parameters") {
const osmium::Location loc1{1.2, 4.5};
REQUIRE(bool(loc1));
REQUIRE(loc1.is_defined());
REQUIRE_FALSE(loc1.is_undefined());
REQUIRE(12000000 == loc1.x());
REQUIRE(45000000 == loc1.y());
REQUIRE(1.2 == Approx(loc1.lon()));
REQUIRE(4.5 == Approx(loc1.lat()));
const osmium::Location loc2{loc1};
REQUIRE(4.5 == Approx(loc2.lat()));
const osmium::Location loc3 = loc1;
REQUIRE(4.5 == Approx(loc3.lat()));
}
TEST_CASE("Location instantiation with double parameters constructor with universal initializer") {
const osmium::Location loc{2.2, 3.3};
REQUIRE(2.2 == Approx(loc.lon()));
REQUIRE(3.3 == Approx(loc.lat()));
}
TEST_CASE("Location instantiation with double parameters constructor with initializer list") {
const osmium::Location loc({4.4, 5.5});
REQUIRE(4.4 == Approx(loc.lon()));
REQUIRE(5.5 == Approx(loc.lat()));
}
TEST_CASE("Location instantiation with double parameters operator equal") {
const osmium::Location loc = {5.5, 6.6};
REQUIRE(5.5 == Approx(loc.lon()));
REQUIRE(6.6 == Approx(loc.lat()));
}
TEST_CASE("Location equality") {
const osmium::Location loc1{1.2, 4.5};
const osmium::Location loc2{1.2, 4.5};
const osmium::Location loc3{1.5, 1.5};
REQUIRE(loc1 == loc2);
REQUIRE(loc1 != loc3);
}
TEST_CASE("Location order") {
REQUIRE(osmium::Location(-1.2, 10.0) < osmium::Location(1.2, 10.0));
REQUIRE(osmium::Location(1.2, 10.0) > osmium::Location(-1.2, 10.0));
REQUIRE(osmium::Location(10.2, 20.0) < osmium::Location(11.2, 20.2));
REQUIRE(osmium::Location(10.2, 20.2) < osmium::Location(11.2, 20.0));
REQUIRE(osmium::Location(11.2, 20.2) > osmium::Location(10.2, 20.0));
}
TEST_CASE("Location validity") {
REQUIRE(osmium::Location(0.0, 0.0).valid());
REQUIRE(osmium::Location(1.2, 4.5).valid());
REQUIRE(osmium::Location(-1.2, 4.5).valid());
REQUIRE(osmium::Location(-180.0, -90.0).valid());
REQUIRE(osmium::Location(180.0, -90.0).valid());
REQUIRE(osmium::Location(-180.0, 90.0).valid());
REQUIRE(osmium::Location(180.0, 90.0).valid());
REQUIRE_FALSE(osmium::Location(200.0, 4.5).valid());
REQUIRE_FALSE(osmium::Location(-1.2, -100.0).valid());
REQUIRE_FALSE(osmium::Location(-180.0, 90.005).valid());
}
TEST_CASE("Location output to iterator comma separator") {
char buffer[100];
const osmium::Location loc{-3.2, 47.3};
*loc.as_string(buffer, ',') = 0;
REQUIRE(std::string("-3.2,47.3") == buffer);
}
TEST_CASE("Location output to iterator space separator") {
char buffer[100];
const osmium::Location loc{0.0, 7.0};
*loc.as_string(buffer, ' ') = 0;
REQUIRE(std::string("0 7") == buffer);
}
TEST_CASE("Location output to iterator check precision") {
char buffer[100];
const osmium::Location loc{-179.9999999, -90.0};
*loc.as_string(buffer, ' ') = 0;
REQUIRE(std::string("-179.9999999 -90") == buffer);
}
TEST_CASE("Location output to iterator undefined location") {
char buffer[100];
const osmium::Location loc;
REQUIRE_THROWS_AS(loc.as_string(buffer, ','), const osmium::invalid_location&);
}
TEST_CASE("Location output to string comman separator") {
std::string s;
const osmium::Location loc{-3.2, 47.3};
loc.as_string(std::back_inserter(s), ',');
REQUIRE(s == "-3.2,47.3");
}
TEST_CASE("Location output to string space separator") {
std::string s;
const osmium::Location loc{0.0, 7.0};
loc.as_string(std::back_inserter(s), ' ');
REQUIRE(s == "0 7");
}
TEST_CASE("Location output to string check precision") {
std::string s;
const osmium::Location loc{-179.9999999, -90.0};
loc.as_string(std::back_inserter(s), ' ');
REQUIRE(s == "-179.9999999 -90");
}
TEST_CASE("Location output to string undefined location") {
std::string s;
const osmium::Location loc;
REQUIRE_THROWS_AS(loc.as_string(std::back_inserter(s), ','), const osmium::invalid_location&);
}
TEST_CASE("Location output defined") {
const osmium::Location loc{-3.20, 47.30};
std::stringstream out;
out << loc;
REQUIRE(out.str() == "(-3.2,47.3)");
}
TEST_CASE("Location output undefined") {
const osmium::Location loc;
std::stringstream out;
out << loc;
REQUIRE(out.str() == "(undefined,undefined)");
}
TEST_CASE("Location hash") {
if (sizeof(size_t) == 8) {
REQUIRE(std::hash<osmium::Location>{}({0, 0}) == 0);
REQUIRE(std::hash<osmium::Location>{}({0, 1}) == 1);
const int64_t a = std::hash<osmium::Location>{}({1, 0});
REQUIRE(a == 0x100000000);
const int64_t b = std::hash<osmium::Location>{}({1, 1});
REQUIRE(b == 0x100000001);
} else {
REQUIRE(std::hash<osmium::Location>{}({0, 0}) == 0);
REQUIRE(std::hash<osmium::Location>{}({0, 1}) == 1);
REQUIRE(std::hash<osmium::Location>{}({1, 0}) == 1);
REQUIRE(std::hash<osmium::Location>{}({1, 1}) == 0);
}
}
void C(const char* s, long v, const char* r = "") {
std::string strm{"-"};
strm += s;
REQUIRE(std::atof(strm.c_str() + 1) == Approx( v / 10000000.0));
REQUIRE(std::atof(strm.c_str() ) == Approx(-v / 10000000.0));
const char* x = strm.c_str() + 1;
const char** data = &x;
REQUIRE(osmium::detail::string_to_location_coordinate(data) == v);
REQUIRE(std::string{*data} == r);
x = strm.c_str();
data = &x;
REQUIRE(osmium::detail::string_to_location_coordinate(data) == -v);
REQUIRE(std::string{*data} == r);
}
void F(const char* s) {
std::string strm{"-"};
strm += s;
const char* x = strm.c_str();
const char** data = &x;
REQUIRE_THROWS_AS(osmium::detail::string_to_location_coordinate(data), const osmium::invalid_location&);
++x;
data = &x;
REQUIRE_THROWS_AS(osmium::detail::string_to_location_coordinate(data), const osmium::invalid_location&);
}
TEST_CASE("Parsing coordinates from strings") {
F("x");
F(".");
F(".e2");
F("--");
F("");
F(" ");
F(" 123");
C("123 ", 1230000000, " ");
C("123x", 1230000000, "x");
C("1.2x", 12000000, "x");
C("0", 0);
C("1", 10000000);
C("2", 20000000);
C("9", 90000000);
C("10", 100000000);
C("11", 110000000);
C("90", 900000000);
C("100", 1000000000);
C("101", 1010000000);
C("00", 0);
C("01", 10000000);
C("001", 10000000);
C("0001", 10000000);
F("1234");
F("1234.");
F("12345678901234567890");
F("1.1234568111111111111111111111111111111");
F("112.34568111111111111111111111111111111");
C("0.", 0);
C(".0", 0);
C("0.0", 0);
C("1.", 10000000);
C("1.0", 10000000);
C("1.2", 12000000);
C("0.1", 1000000);
C(".1", 1000000);
C("0.01", 100000);
C(".01", 100000);
C("0.001", 10000);
C("0.0001", 1000);
C("0.00001", 100);
C("0.000001", 10);
C("0.0000001", 1);
C("1.1234567", 11234567);
C("1.12345670", 11234567);
C("1.12345674", 11234567);
C("1.123456751", 11234568);
C("1.12345679", 11234568);
C("1.12345680", 11234568);
C("1.12345681", 11234568);
C("180.0000000", 1800000000);
C("180.0000001", 1800000001);
C("179.9999999", 1799999999);
C("179.99999999", 1800000000);
C("200.123", 2001230000);
C("214.7483647", 2147483647);
C("8.109E-4" , 8109);
C("8.1090E-4" , 8109);
C("8.10909E-4" , 8109);
C("8.109095E-4" , 8109);
C("8.1090959E-4" , 8109);
C("8.10909598E-4" , 8109);
C("8.109095988E-4" , 8109);
C("8.1090959887E-4" , 8109);
C("8.10909598870E-4" , 8109);
C("8.109095988709E-4" , 8109);
C("8.1090959887098E-4" , 8109);
C("8.10909598870983E-4" , 8109);
C("8.109095988709837E-4" , 8109);
C("81.09095988709837E-4" , 81091);
C("810.9095988709837E-4" , 810910);
C(".8109095988709837E-4" , 811);
C(".08109095988709837E-4" , 81);
C("1e2", 1000000000);
C("1e1", 100000000);
C("1e0", 10000000);
C("1e-1", 1000000);
C("1e-2", 100000);
C("1e-3", 10000);
C("1e-4", 1000);
C("1e-5", 100);
C("1e-6", 10);
C("1e-7", 1);
C("1.0e2", 1000000000);
C("1.e2", 1000000000);
C("1.1e1", 110000000);
C("0.1e1", 10000000);
C(".1e1", 10000000);
C("1.2e0", 12000000);
C("1.9e-1", 1900000);
C("2.0e-2", 200000);
C("2.1e-3", 21000);
C("9.0e-4", 9000);
C("9.1e-5", 910);
C("1.0e-6", 10);
C("1.0e-7", 1);
C("1.4e-7", 1);
C("1.5e-7", 2);
C("1.9e-7", 2);
C("0.5e-7", 1);
C("0.1e-7", 0);
C("0.0e-7", 0);
C("1.9e-8", 0);
C("1.9e-9", 0);
C("1.9e-10", 0);
F("e");
F(" e");
F(" 1.1e2");
F("1.0e3");
F("5e4");
F("5.0e2");
F("3e2");
F("1e");
F("1e-");
F("1e1234567");
F("0.5e");
F("1e10");
C("1e2 ", 1000000000, " ");
C("1.1e2 ", 1100000000, " ");
C("1.1e2x", 1100000000, "x");
C("1.1e2:", 1100000000, ":");
}
TEST_CASE("Parsing min coordinate from string") {
const char* minval = "-214.7483648";
const char** data = &minval;
REQUIRE(osmium::detail::string_to_location_coordinate(data) == std::numeric_limits<int32_t>::min());
}
TEST_CASE("Writing zero coordinate into string") {
std::string buffer;
osmium::detail::append_location_coordinate_to_string(std::back_inserter(buffer), 0);
REQUIRE(buffer == "0");
}
void CW(long v, const char* s) {
std::string buffer;
osmium::detail::append_location_coordinate_to_string(std::back_inserter(buffer), v);
REQUIRE(buffer == s);
buffer.clear();
osmium::detail::append_location_coordinate_to_string(std::back_inserter(buffer), -v);
REQUIRE(buffer[0] == '-');
REQUIRE_FALSE(std::strcmp(buffer.c_str() + 1, s));
}
TEST_CASE("Writing coordinate into string") {
CW( 10000000, "1");
CW( 90000000, "9");
CW( 100000000, "10");
CW(1000000000, "100");
CW(2000000000, "200");
CW( 1000000, "0.1");
CW( 100000, "0.01");
CW( 10000, "0.001");
CW( 1000, "0.0001");
CW( 100, "0.00001");
CW( 10, "0.000001");
CW( 1, "0.0000001");
CW( 1230000, "0.123");
CW( 9999999, "0.9999999");
CW( 40101010, "4.010101");
CW( 494561234, "49.4561234");
CW(1799999999, "179.9999999");
CW(2147483647, "214.7483647");
}
TEST_CASE("Writing min coordinate into string") {
std::string buffer;
osmium::detail::append_location_coordinate_to_string(std::back_inserter(buffer), std::numeric_limits<int32_t>::min());
REQUIRE(buffer == "-214.7483648");
}
TEST_CASE("set lon/lat from string") {
osmium::Location loc;
REQUIRE(loc.is_undefined());
REQUIRE_FALSE(loc.is_defined());
REQUIRE_FALSE(loc.valid());
loc.set_lon("1.2");
REQUIRE_FALSE(loc.is_undefined());
REQUIRE(loc.is_defined());
REQUIRE_FALSE(loc.valid());
loc.set_lat("3.4");
REQUIRE_FALSE(loc.is_undefined());
REQUIRE(loc.is_defined());
REQUIRE(loc.valid());
REQUIRE(loc.lon() == Approx(1.2));
REQUIRE(loc.lat() == Approx(3.4));
}
TEST_CASE("set lon/lat from string with trailing characters") {
osmium::Location loc;
REQUIRE_THROWS_AS(loc.set_lon("1.2x"), const osmium::invalid_location&);
REQUIRE_THROWS_AS(loc.set_lat("3.4e1 "), const osmium::invalid_location&);
}
TEST_CASE("set lon/lat from string with trailing characters using partial") {
osmium::Location loc;
const char* x = "1.2x";
const char* y = "3.4 ";
loc.set_lon_partial(&x);
loc.set_lat_partial(&y);
REQUIRE(loc.lon() == Approx(1.2));
REQUIRE(loc.lat() == Approx(3.4));
REQUIRE(*x == 'x');
REQUIRE(*y == ' ');
}
+189
View File
@@ -0,0 +1,189 @@
#include "catch.hpp"
#include <boost/crc.hpp>
#include <osmium/builder/attr.hpp>
#include <osmium/osm/crc.hpp>
#include <osmium/osm/node.hpp>
using namespace osmium::builder::attr;
TEST_CASE("Build node") {
osmium::memory::Buffer buffer{10000};
osmium::builder::add_node(buffer,
_id(17),
_version(3),
_visible(true),
_cid(333),
_uid(21),
_timestamp(time_t(123)),
_user("foo"),
_tag("amenity", "pub"),
_tag("name", "OSM BAR"),
_location(3.5, 4.7)
);
osmium::Node& node = buffer.get<osmium::Node>(0);
REQUIRE(osmium::item_type::node == node.type());
REQUIRE(node.type_is_in(osmium::osm_entity_bits::node));
REQUIRE(node.type_is_in(osmium::osm_entity_bits::nwr));
REQUIRE(17l == node.id());
REQUIRE(17ul == node.positive_id());
REQUIRE(3 == node.version());
REQUIRE(true == node.visible());
REQUIRE(false == node.deleted());
REQUIRE(333 == node.changeset());
REQUIRE(21 == node.uid());
REQUIRE(std::string{"foo"} == node.user());
REQUIRE(123 == uint32_t(node.timestamp()));
REQUIRE(osmium::Location(3.5, 4.7) == node.location());
REQUIRE(2 == node.tags().size());
osmium::CRC<boost::crc_32_type> crc32;
crc32.update(node);
REQUIRE(crc32().checksum() == 0x7dc553f9);
node.set_visible(false);
REQUIRE(false == node.visible());
REQUIRE(true == node.deleted());
}
TEST_CASE("default values for node attributes") {
osmium::memory::Buffer buffer{10000};
osmium::builder::add_node(buffer, _id(0));
const osmium::Node& node = buffer.get<osmium::Node>(0);
REQUIRE(0l == node.id());
REQUIRE(0ul == node.positive_id());
REQUIRE(0 == node.version());
REQUIRE(true == node.visible());
REQUIRE(0 == node.changeset());
REQUIRE(0 == node.uid());
REQUIRE(std::string{} == node.user());
REQUIRE(0 == uint32_t(node.timestamp()));
REQUIRE(osmium::Location() == node.location());
REQUIRE(0 == node.tags().size());
}
TEST_CASE("set node attributes from strings") {
osmium::memory::Buffer buffer{10000};
osmium::builder::add_node(buffer, _id(0));
osmium::Node& node = buffer.get<osmium::Node>(0);
node.set_id("-17")
.set_version("3")
.set_visible("true")
.set_changeset("333")
.set_timestamp("2014-03-17T16:23:08Z")
.set_uid("21");
REQUIRE(-17l == node.id());
REQUIRE(17ul == node.positive_id());
REQUIRE(3 == node.version());
REQUIRE(true == node.visible());
REQUIRE(333 == node.changeset());
REQUIRE(std::string{"2014-03-17T16:23:08Z"} == node.timestamp().to_iso());
REQUIRE(21 == node.uid());
}
TEST_CASE("set node attributes from strings using set_attribute()") {
osmium::memory::Buffer buffer{10000};
osmium::builder::add_node(buffer, _id(0));
osmium::Node& node = buffer.get<osmium::Node>(0);
node.set_attribute("id", "-17")
.set_attribute("version", "3")
.set_attribute("visible", "true")
.set_attribute("changeset", "333")
.set_attribute("timestamp", "2014-03-17T16:23:08Z")
.set_attribute("uid", "21");
REQUIRE(-17l == node.id());
REQUIRE(17ul == node.positive_id());
REQUIRE(3 == node.version());
REQUIRE(true == node.visible());
REQUIRE(333 == node.changeset());
REQUIRE(std::string{"2014-03-17T16:23:08Z"} == node.timestamp().to_iso());
REQUIRE(21 == node.uid());
}
TEST_CASE("Setting attributes from bad data on strings should fail") {
osmium::memory::Buffer buffer{10000};
osmium::builder::add_node(buffer, _id(0));
osmium::Node& node = buffer.get<osmium::Node>(0);
REQUIRE_THROWS(node.set_id("bar"));
REQUIRE_THROWS(node.set_id("123x"));
REQUIRE_THROWS(node.set_version("123x"));
REQUIRE_THROWS(node.set_visible("foo"));
REQUIRE_THROWS(node.set_changeset("123x"));
REQUIRE_THROWS(node.set_changeset("NULL"));
REQUIRE_THROWS(node.set_timestamp("2014-03-17T16:23:08Zx"));
REQUIRE_THROWS(node.set_timestamp("2014-03-17T16:23:99Z"));
REQUIRE_THROWS(node.set_uid("123x"));
REQUIRE_THROWS(node.set_uid("anonymous"));
}
TEST_CASE("set large id") {
osmium::memory::Buffer buffer{10000};
const int64_t id = 3000000000l;
osmium::builder::add_node(buffer, _id(id));
osmium::Node& node = buffer.get<osmium::Node>(0);
REQUIRE(id == node.id());
REQUIRE(static_cast<osmium::unsigned_object_id_type>(id) == node.positive_id());
node.set_id(-id);
REQUIRE(-id == node.id());
REQUIRE(static_cast<osmium::unsigned_object_id_type>(id) == node.positive_id());
}
TEST_CASE("set tags on node") {
osmium::memory::Buffer buffer{10000};
osmium::builder::add_node(buffer,
_user("foo"),
_tag("amenity", "pub"),
_tag("name", "OSM BAR")
);
const osmium::Node& node = buffer.get<osmium::Node>(0);
REQUIRE(nullptr == node.tags().get_value_by_key("fail"));
REQUIRE(std::string{"pub"} == node.tags().get_value_by_key("amenity"));
REQUIRE(std::string{"pub"} == node.get_value_by_key("amenity"));
REQUIRE(std::string{"default"} == node.tags().get_value_by_key("fail", "default"));
REQUIRE(std::string{"pub"} == node.tags().get_value_by_key("amenity", "default"));
REQUIRE(std::string{"pub"} == node.get_value_by_key("amenity", "default"));
}
TEST_CASE("Setting diff flags on node") {
osmium::memory::Buffer buffer{1000};
osmium::builder::add_node(buffer, _id(17));
osmium::Node& node = buffer.get<osmium::Node>(0);
REQUIRE(node.diff() == osmium::diff_indicator_type::none);
REQUIRE(node.diff_as_char() == '*');
node.set_diff(osmium::diff_indicator_type::left);
REQUIRE(node.diff() == osmium::diff_indicator_type::left);
REQUIRE(node.diff_as_char() == '-');
node.set_diff(osmium::diff_indicator_type::right);
REQUIRE(node.diff() == osmium::diff_indicator_type::right);
REQUIRE(node.diff_as_char() == '+');
node.set_diff(osmium::diff_indicator_type::both);
REQUIRE(node.diff() == osmium::diff_indicator_type::both);
REQUIRE(node.diff_as_char() == ' ');
}
+126
View File
@@ -0,0 +1,126 @@
#include "catch.hpp"
#include <osmium/builder/attr.hpp>
#include <osmium/memory/buffer.hpp>
#include <osmium/osm/node_ref.hpp>
#include <osmium/osm/node_ref_list.hpp>
TEST_CASE("Default construct a NodeRef") {
const osmium::NodeRef node_ref;
REQUIRE(node_ref.ref() == 0);
REQUIRE(node_ref.location() == osmium::Location{});
}
TEST_CASE("Construct a NodeRef with an id") {
const osmium::NodeRef node_ref{7};
REQUIRE(node_ref.ref() == 7);
}
TEST_CASE("Equality comparison fo NodeRefs") {
const osmium::NodeRef node_ref1{7, {1.2, 3.4}};
const osmium::NodeRef node_ref2{7, {1.4, 3.1}};
const osmium::NodeRef node_ref3{9, {1.2, 3.4}};
REQUIRE(node_ref1 == node_ref2);
REQUIRE(node_ref1 != node_ref3);
REQUIRE_FALSE(osmium::location_equal()(node_ref1, node_ref2));
REQUIRE_FALSE(osmium::location_equal()(node_ref2, node_ref3));
REQUIRE( osmium::location_equal()(node_ref1, node_ref3));
}
TEST_CASE("Set location on a NodeRef") {
osmium::NodeRef node_ref{7};
REQUIRE_FALSE(node_ref.location().valid());
REQUIRE(node_ref.location() == osmium::Location());
node_ref.set_location(osmium::Location(13.5, -7.2));
REQUIRE(node_ref.location().lon() == 13.5);
REQUIRE(node_ref.location().valid());
}
TEST_CASE("Ordering of NodeRefs") {
const osmium::NodeRef node_ref1{1, {1.0, 3.0}};
const osmium::NodeRef node_ref2{2, {1.4, 2.9}};
const osmium::NodeRef node_ref3{3, {1.2, 3.0}};
const osmium::NodeRef node_ref4{4, {1.2, 3.3}};
REQUIRE(node_ref1 < node_ref2);
REQUIRE(node_ref2 < node_ref3);
REQUIRE(node_ref1 < node_ref3);
REQUIRE(node_ref1 >= node_ref1);
REQUIRE(osmium::location_less()(node_ref1, node_ref2));
REQUIRE_FALSE(osmium::location_less()(node_ref2, node_ref3));
REQUIRE(osmium::location_less()(node_ref1, node_ref3));
REQUIRE(osmium::location_less()(node_ref3, node_ref4));
REQUIRE_FALSE(osmium::location_less()(node_ref1, node_ref1));
}
TEST_CASE("WayNodeList") {
osmium::memory::Buffer buffer{1024};
SECTION("Empty list") {
{
osmium::builder::WayNodeListBuilder builder{buffer};
}
REQUIRE(buffer.commit() == 0);
REQUIRE(buffer.committed() > 0);
const osmium::WayNodeList& nrl = buffer.get<osmium::WayNodeList>(0);
REQUIRE(nrl.empty());
REQUIRE(nrl.size() == 0);
}
SECTION("Change a WayNodeList") {
osmium::builder::add_way_node_list(buffer, osmium::builder::attr::_nodes({
{1, {0.0, 0.0}},
{2, {0.0, 1.0}},
{3, {1.0, 1.0}}
}));
osmium::WayNodeList& nrl = buffer.get<osmium::WayNodeList>(0);
REQUIRE(nrl.size() == 3);
REQUIRE(nrl[1].location() == osmium::Location(0.0, 1.0));
nrl[1].set_location(osmium::Location{13.5, -7.2});
REQUIRE(nrl[1].location() == osmium::Location(13.5, -7.2));
}
SECTION("Small area") {
osmium::builder::add_way_node_list(buffer, osmium::builder::attr::_nodes({
{1, {0.0, 0.0}},
{2, {0.0, 1.0}},
{3, {1.0, 1.0}},
{4, {1.0, 0.0}},
{1, {0.0, 0.0}},
}));
const osmium::WayNodeList& nrl = buffer.get<osmium::WayNodeList>(0);
REQUIRE_FALSE(nrl.empty());
REQUIRE(nrl.size() == 5);
REQUIRE(nrl.is_closed());
REQUIRE(nrl.ends_have_same_id());
REQUIRE(nrl.ends_have_same_location());
const osmium::Box envelope = nrl.envelope();
REQUIRE(envelope.bottom_left().lon() == Approx(0));
REQUIRE(envelope.bottom_left().lat() == Approx(0));
REQUIRE(envelope.top_right().lon() == Approx(1));
REQUIRE(envelope.top_right().lat() == Approx(1));
}
SECTION("Not an area") {
osmium::builder::add_way_node_list(buffer, osmium::builder::attr::_nodes({
{1, {0.0, 0.0}},
{2, {1.0, 0.0}},
{1, {0.0, 0.0}},
}));
const osmium::WayNodeList& nrl = buffer.get<osmium::WayNodeList>(0);
REQUIRE_FALSE(nrl.empty());
REQUIRE(nrl.size() == 3);
REQUIRE(nrl.is_closed());
REQUIRE(nrl.ends_have_same_id());
REQUIRE(nrl.ends_have_same_location());
}
}
+146
View File
@@ -0,0 +1,146 @@
#include "catch.hpp"
#include <algorithm>
#include <functional>
#include <vector>
#include <osmium/builder/attr.hpp>
#include <osmium/builder/osm_object_builder.hpp>
#include <osmium/osm.hpp>
#include <osmium/osm/object_comparisons.hpp>
using namespace osmium::builder::attr;
TEST_CASE("Object ID comparisons") {
osmium::object_id_type a = 0;
osmium::object_id_type b = -1;
osmium::object_id_type c = -10;
osmium::object_id_type d = -11;
osmium::object_id_type e = 1;
osmium::object_id_type f = 11;
osmium::object_id_type g = 12;
REQUIRE_FALSE(osmium::id_order{}(a, a));
REQUIRE(osmium::id_order{}(a, b));
REQUIRE(osmium::id_order{}(a, c));
REQUIRE(osmium::id_order{}(a, d));
REQUIRE(osmium::id_order{}(a, e));
REQUIRE(osmium::id_order{}(a, f));
REQUIRE(osmium::id_order{}(a, g));
REQUIRE_FALSE(osmium::id_order{}(b, a));
REQUIRE_FALSE(osmium::id_order{}(b, b));
REQUIRE(osmium::id_order{}(b, c));
REQUIRE(osmium::id_order{}(b, d));
REQUIRE(osmium::id_order{}(b, e));
REQUIRE(osmium::id_order{}(b, f));
REQUIRE(osmium::id_order{}(b, g));
REQUIRE_FALSE(osmium::id_order{}(c, a));
REQUIRE_FALSE(osmium::id_order{}(c, b));
REQUIRE_FALSE(osmium::id_order{}(c, c));
REQUIRE(osmium::id_order{}(c, d));
REQUIRE(osmium::id_order{}(c, e));
REQUIRE(osmium::id_order{}(c, f));
REQUIRE(osmium::id_order{}(c, g));
REQUIRE_FALSE(osmium::id_order{}(d, a));
REQUIRE_FALSE(osmium::id_order{}(d, b));
REQUIRE_FALSE(osmium::id_order{}(d, c));
REQUIRE_FALSE(osmium::id_order{}(d, d));
REQUIRE(osmium::id_order{}(d, e));
REQUIRE(osmium::id_order{}(d, f));
REQUIRE(osmium::id_order{}(d, g));
REQUIRE_FALSE(osmium::id_order{}(e, a));
REQUIRE_FALSE(osmium::id_order{}(e, b));
REQUIRE_FALSE(osmium::id_order{}(e, c));
REQUIRE_FALSE(osmium::id_order{}(e, d));
REQUIRE_FALSE(osmium::id_order{}(e, e));
REQUIRE(osmium::id_order{}(e, f));
REQUIRE(osmium::id_order{}(e, g));
REQUIRE_FALSE(osmium::id_order{}(f, a));
REQUIRE_FALSE(osmium::id_order{}(f, b));
REQUIRE_FALSE(osmium::id_order{}(f, c));
REQUIRE_FALSE(osmium::id_order{}(f, d));
REQUIRE_FALSE(osmium::id_order{}(f, e));
REQUIRE_FALSE(osmium::id_order{}(f, f));
REQUIRE(osmium::id_order{}(f, g));
REQUIRE_FALSE(osmium::id_order{}(g, a));
REQUIRE_FALSE(osmium::id_order{}(g, b));
REQUIRE_FALSE(osmium::id_order{}(g, c));
REQUIRE_FALSE(osmium::id_order{}(g, d));
REQUIRE_FALSE(osmium::id_order{}(g, e));
REQUIRE_FALSE(osmium::id_order{}(g, f));
REQUIRE_FALSE(osmium::id_order{}(g, g));
}
TEST_CASE("Node comparisons") {
osmium::memory::Buffer buffer(10 * 1000);
std::vector<std::reference_wrapper<osmium::Node>> nodes;
SECTION("nodes are ordered by id, version, and timestamp") {
nodes.emplace_back(buffer.get<osmium::Node>(osmium::builder::add_node(buffer, _id( 0), _version(2), _timestamp("2016-01-01T00:00:00Z"))));
nodes.emplace_back(buffer.get<osmium::Node>(osmium::builder::add_node(buffer, _id( 1), _version(2), _timestamp("2016-01-01T00:00:00Z"))));
nodes.emplace_back(buffer.get<osmium::Node>(osmium::builder::add_node(buffer, _id( 10), _version(2), _timestamp("2016-01-01T00:01:00Z"))));
nodes.emplace_back(buffer.get<osmium::Node>(osmium::builder::add_node(buffer, _id( 10), _version(3), _timestamp("2016-01-01T00:00:00Z"))));
nodes.emplace_back(buffer.get<osmium::Node>(osmium::builder::add_node(buffer, _id( 12), _version(2), _timestamp("2016-01-01T00:00:00Z"))));
nodes.emplace_back(buffer.get<osmium::Node>(osmium::builder::add_node(buffer, _id( 12), _version(2), _timestamp("2016-01-01T00:01:00Z"))));
nodes.emplace_back(buffer.get<osmium::Node>(osmium::builder::add_node(buffer, _id( 15), _version(1), _timestamp("2016-01-01T00:00:00Z"))));
nodes.emplace_back(buffer.get<osmium::Node>(osmium::builder::add_node(buffer, _id(10000000000ll), _version(2), _timestamp("2016-01-01T00:00:00Z"))));
REQUIRE(std::is_sorted(nodes.cbegin(), nodes.cend()));
}
SECTION("equal nodes are not different") {
nodes.emplace_back(buffer.get<osmium::Node>(osmium::builder::add_node(buffer, _id(1), _version(2), _timestamp("2016-01-01T00:00:00Z"))));
nodes.emplace_back(buffer.get<osmium::Node>(osmium::builder::add_node(buffer, _id(1), _version(2), _timestamp("2016-01-01T00:00:00Z"))));
REQUIRE(nodes[0] == nodes[1]);
REQUIRE_FALSE(nodes[0] < nodes[1]);
REQUIRE_FALSE(nodes[0] > nodes[1]);
}
SECTION("IDs are ordered by sign and then absolute value") {
nodes.emplace_back(buffer.get<osmium::Node>(osmium::builder::add_node(buffer, _id( 0))));
nodes.emplace_back(buffer.get<osmium::Node>(osmium::builder::add_node(buffer, _id( -1))));
nodes.emplace_back(buffer.get<osmium::Node>(osmium::builder::add_node(buffer, _id(-10))));
nodes.emplace_back(buffer.get<osmium::Node>(osmium::builder::add_node(buffer, _id( 1))));
nodes.emplace_back(buffer.get<osmium::Node>(osmium::builder::add_node(buffer, _id( 10))));
REQUIRE(std::is_sorted(nodes.cbegin(), nodes.cend()));
}
SECTION("reverse version ordering") {
nodes.emplace_back(buffer.get<osmium::Node>(osmium::builder::add_node(buffer, _id( 0), _version(2), _timestamp("2016-01-01T00:00:00Z"))));
nodes.emplace_back(buffer.get<osmium::Node>(osmium::builder::add_node(buffer, _id( 1), _version(2), _timestamp("2016-01-01T00:00:00Z"))));
nodes.emplace_back(buffer.get<osmium::Node>(osmium::builder::add_node(buffer, _id( 10), _version(3), _timestamp("2016-01-01T00:00:00Z"))));
nodes.emplace_back(buffer.get<osmium::Node>(osmium::builder::add_node(buffer, _id( 10), _version(2), _timestamp("2016-01-01T00:01:00Z"))));
nodes.emplace_back(buffer.get<osmium::Node>(osmium::builder::add_node(buffer, _id( 12), _version(2), _timestamp("2016-01-01T00:01:00Z"))));
nodes.emplace_back(buffer.get<osmium::Node>(osmium::builder::add_node(buffer, _id( 12), _version(2), _timestamp("2016-01-01T00:00:00Z"))));
nodes.emplace_back(buffer.get<osmium::Node>(osmium::builder::add_node(buffer, _id( 15), _version(1), _timestamp("2016-01-01T00:00:00Z"))));
nodes.emplace_back(buffer.get<osmium::Node>(osmium::builder::add_node(buffer, _id(10000000000ll), _version(2), _timestamp("2016-01-01T00:00:00Z"))));
REQUIRE(std::is_sorted(nodes.cbegin(), nodes.cend(), osmium::object_order_type_id_reverse_version{}));
}
}
TEST_CASE("Object comparisons") {
osmium::memory::Buffer buffer(10 * 1000);
std::vector<std::reference_wrapper<osmium::OSMObject>> objects;
SECTION("types are ordered nodes, then ways, then relations") {
objects.emplace_back(buffer.get<osmium::Node>( osmium::builder::add_node( buffer, _id(3))));
objects.emplace_back(buffer.get<osmium::Way>( osmium::builder::add_way( buffer, _id(2))));
objects.emplace_back(buffer.get<osmium::Relation>(osmium::builder::add_relation(buffer, _id(1))));
REQUIRE(std::is_sorted(objects.cbegin(), objects.cend()));
}
}
+75
View File
@@ -0,0 +1,75 @@
#include "catch.hpp"
#include <boost/crc.hpp>
#include <osmium/builder/attr.hpp>
#include <osmium/osm/crc.hpp>
#include <osmium/osm/relation.hpp>
using namespace osmium::builder::attr;
TEST_CASE("Build relation") {
osmium::memory::Buffer buffer(10000);
osmium::builder::add_relation(buffer,
_id(17),
_version(3),
_visible(),
_cid(333),
_uid(21),
_timestamp(time_t(123)),
_user("foo"),
_tag("type", "multipolygon"),
_tag("name", "Sherwood Forest"),
_member(osmium::item_type::way, 1, "inner"),
_member(osmium::item_type::way, 2, ""),
_member(osmium::item_type::way, 3, "outer")
);
const osmium::Relation& relation = buffer.get<osmium::Relation>(0);
REQUIRE(17 == relation.id());
REQUIRE(3 == relation.version());
REQUIRE(true == relation.visible());
REQUIRE(333 == relation.changeset());
REQUIRE(21 == relation.uid());
REQUIRE(std::string("foo") == relation.user());
REQUIRE(123 == uint32_t(relation.timestamp()));
REQUIRE(2 == relation.tags().size());
REQUIRE(3 == relation.members().size());
int n=1;
for (auto& member : relation.members()) {
REQUIRE(osmium::item_type::way == member.type());
REQUIRE(n == member.ref());
switch (n) {
case 1:
REQUIRE(std::string("inner") == member.role());
break;
case 2:
REQUIRE(std::string("") == member.role());
break;
case 3:
REQUIRE(std::string("outer") == member.role());
break;
default:
REQUIRE(false);
}
++n;
}
osmium::CRC<boost::crc_32_type> crc32;
crc32.update(relation);
REQUIRE(crc32().checksum() == 0x2c2352e);
}
TEST_CASE("Member role too long") {
osmium::memory::Buffer buffer(10000);
osmium::builder::RelationMemberListBuilder builder(buffer);
const char role[2000] = "";
builder.add_member(osmium::item_type::node, 1, role, 1024);
REQUIRE_THROWS(builder.add_member(osmium::item_type::node, 1, role, 1025));
}
+119
View File
@@ -0,0 +1,119 @@
#include "catch.hpp"
#include <sstream>
#include <string>
#include <vector>
#include <osmium/osm/timestamp.hpp>
TEST_CASE("Timestamp can be default initialized to invalid value") {
const osmium::Timestamp t;
REQUIRE(0 == uint32_t(t));
REQUIRE("" == t.to_iso());
REQUIRE_FALSE(t.valid());
}
TEST_CASE("Timestamp invalid value is zero") {
const osmium::Timestamp t{static_cast<time_t>(0)};
REQUIRE(0 == uint32_t(t));
REQUIRE("" == t.to_iso());
REQUIRE_FALSE(t.valid());
}
TEST_CASE("Timestamp can be initialized from time_t") {
const osmium::Timestamp t{static_cast<time_t>(1)};
REQUIRE(1 == uint32_t(t));
REQUIRE("1970-01-01T00:00:01Z" == t.to_iso());
REQUIRE(t.valid());
}
TEST_CASE("Timestamp can be initialized from const char*") {
const osmium::Timestamp t{"2000-01-01T00:00:00Z"};
REQUIRE("2000-01-01T00:00:00Z" == t.to_iso());
REQUIRE(t.valid());
}
TEST_CASE("Timestamp can be initialized from string") {
const std::string s = "2000-01-01T00:00:00Z";
const osmium::Timestamp t{s};
REQUIRE("2000-01-01T00:00:00Z" == t.to_iso());
REQUIRE(t.valid());
}
TEST_CASE("Timestamp throws if initialized from bad string") {
REQUIRE_THROWS_AS(osmium::Timestamp("x"), const std::invalid_argument&);
}
TEST_CASE("Timestamp can be explicitly cast to time_t") {
const osmium::Timestamp t{4242};
const time_t x = t.seconds_since_epoch();
REQUIRE(x == 4242);
}
TEST_CASE("Timestamp uint32_t can be initialized from Timestamp") {
const osmium::Timestamp t{4242};
const uint32_t x { t };
REQUIRE(x == 4242);
}
TEST_CASE("Timestamps can be compared") {
const osmium::Timestamp t1{10};
const osmium::Timestamp t2{50};
REQUIRE(t1 < t2);
REQUIRE(t1 > osmium::start_of_time());
REQUIRE(t2 > osmium::start_of_time());
REQUIRE(t1 < osmium::end_of_time());
REQUIRE(t2 < osmium::end_of_time());
}
TEST_CASE("Timestamp can be written to stream") {
const osmium::Timestamp t{1};
std::stringstream ss;
ss << t;
REQUIRE("1970-01-01T00:00:01Z" == ss.str());
}
TEST_CASE("Valid timestamps") {
std::vector<std::string> test_cases = {
"1970-01-01T00:00:01Z",
"2000-01-01T00:00:00Z",
"2006-12-31T23:59:59Z",
"2030-12-31T23:59:59Z",
"2016-02-28T23:59:59Z",
"2016-03-31T23:59:59Z"
};
for (const auto& tc : test_cases) {
const osmium::Timestamp t{tc};
REQUIRE(tc == t.to_iso());
}
}
TEST_CASE("Invalid timestamps") {
REQUIRE_THROWS_AS(osmium::Timestamp{""}, const std::invalid_argument&);
REQUIRE_THROWS_AS(osmium::Timestamp{"x"}, const std::invalid_argument&);
REQUIRE_THROWS_AS(osmium::Timestamp{"xxxxxxxxxxxxxxxxxxxx"}, const std::invalid_argument&);
REQUIRE_THROWS_AS(osmium::Timestamp{"2000-01-01x00:00:00Z"}, const std::invalid_argument&);
REQUIRE_THROWS_AS(osmium::Timestamp{"2000-01-01T00:00:00x"}, const std::invalid_argument&);
REQUIRE_THROWS_AS(osmium::Timestamp{"2000x01-01T00:00:00Z"}, const std::invalid_argument&);
REQUIRE_THROWS_AS(osmium::Timestamp{"2000-01x01T00:00:00Z"}, const std::invalid_argument&);
REQUIRE_THROWS_AS(osmium::Timestamp{"2000-01-01T00x00:00Z"}, const std::invalid_argument&);
REQUIRE_THROWS_AS(osmium::Timestamp{"2000-01-01T00:00x00Z"}, const std::invalid_argument&);
REQUIRE_THROWS_AS(osmium::Timestamp{"0000-00-01T00:00:00Z"}, const std::invalid_argument&);
REQUIRE_THROWS_AS(osmium::Timestamp{"2000-00-01T00:00:00Z"}, const std::invalid_argument&);
REQUIRE_THROWS_AS(osmium::Timestamp{"2000-01-00T00:00:00Z"}, const std::invalid_argument&);
REQUIRE_THROWS_AS(osmium::Timestamp{"2000-01-01T24:00:00Z"}, const std::invalid_argument&);
REQUIRE_THROWS_AS(osmium::Timestamp{"2000-01-01T00:60:00Z"}, const std::invalid_argument&);
REQUIRE_THROWS_AS(osmium::Timestamp{"2000-01-01T00:00:61Z"}, const std::invalid_argument&);
REQUIRE_THROWS_AS(osmium::Timestamp{"2000-01-32T00:00:00Z"}, const std::invalid_argument&);
REQUIRE_THROWS_AS(osmium::Timestamp{"2000-02-30T00:00:00Z"}, const std::invalid_argument&);
REQUIRE_THROWS_AS(osmium::Timestamp{"2000-03-32T00:00:00Z"}, const std::invalid_argument&);
}
+98
View File
@@ -0,0 +1,98 @@
#include "catch.hpp"
#include <osmium/osm/types.hpp>
#include <osmium/osm/types_from_string.hpp>
TEST_CASE("set ID from string") {
REQUIRE(osmium::string_to_object_id("0") == 0);
REQUIRE(osmium::string_to_object_id("17") == 17);
REQUIRE(osmium::string_to_object_id("-17") == -17);
REQUIRE(osmium::string_to_object_id("01") == 1);
REQUIRE_THROWS_AS(osmium::string_to_object_id(""), const std::range_error&);
REQUIRE_THROWS_AS(osmium::string_to_object_id(" "), const std::range_error&);
REQUIRE_THROWS_AS(osmium::string_to_object_id(" 22"), const std::range_error&);
REQUIRE_THROWS_AS(osmium::string_to_object_id("x"), const std::range_error&);
REQUIRE_THROWS_AS(osmium::string_to_object_id("0x1"), const std::range_error&);
REQUIRE_THROWS_AS(osmium::string_to_object_id("12a"), const std::range_error&);
REQUIRE_THROWS_AS(osmium::string_to_object_id("12345678901234567890"), const std::range_error&);
}
TEST_CASE("set type and ID from string") {
const auto n17 = osmium::string_to_object_id("n17", osmium::osm_entity_bits::nwr);
REQUIRE(n17.first == osmium::item_type::node);
REQUIRE(n17.second == 17);
const auto w42 = osmium::string_to_object_id("w42", osmium::osm_entity_bits::nwr);
REQUIRE(w42.first == osmium::item_type::way);
REQUIRE(w42.second == 42);
const auto r_2 = osmium::string_to_object_id("r-2", osmium::osm_entity_bits::nwr);
REQUIRE(r_2.first == osmium::item_type::relation);
REQUIRE(r_2.second == -2);
const auto d3 = osmium::string_to_object_id("3", osmium::osm_entity_bits::nwr);
REQUIRE(d3.first == osmium::item_type::undefined);
REQUIRE(d3.second == 3);
const auto u3 = osmium::string_to_object_id("3", osmium::osm_entity_bits::nwr, osmium::item_type::undefined);
REQUIRE(u3.first == osmium::item_type::undefined);
REQUIRE(u3.second == 3);
const auto n3 = osmium::string_to_object_id("3", osmium::osm_entity_bits::nwr, osmium::item_type::node);
REQUIRE(n3.first == osmium::item_type::node);
REQUIRE(n3.second == 3);
REQUIRE_THROWS_AS(osmium::string_to_object_id("", osmium::osm_entity_bits::nwr), const std::range_error&);
REQUIRE_THROWS_AS(osmium::string_to_object_id("n", osmium::osm_entity_bits::nwr), const std::range_error&);
REQUIRE_THROWS_AS(osmium::string_to_object_id("x3", osmium::osm_entity_bits::nwr), const std::range_error&);
REQUIRE_THROWS_AS(osmium::string_to_object_id("nx3", osmium::osm_entity_bits::nwr), const std::range_error&);
REQUIRE_THROWS_AS(osmium::string_to_object_id("n3", osmium::osm_entity_bits::way), const std::range_error&);
REQUIRE_THROWS_AS(osmium::string_to_object_id("n3a", osmium::osm_entity_bits::nwr), const std::range_error&);
}
TEST_CASE("set object version from string") {
REQUIRE(osmium::string_to_object_version("0") == 0);
REQUIRE(osmium::string_to_object_version("1") == 1);
REQUIRE_THROWS_AS(osmium::string_to_object_version("-1"), const std::range_error&);
REQUIRE_THROWS_AS(osmium::string_to_object_version(""), const std::range_error&);
REQUIRE_THROWS_AS(osmium::string_to_object_version(" "), const std::range_error&);
REQUIRE_THROWS_AS(osmium::string_to_object_version(" 22"), const std::range_error&);
REQUIRE_THROWS_AS(osmium::string_to_object_version("x"), const std::range_error&);
}
TEST_CASE("set changeset id from string") {
REQUIRE(osmium::string_to_changeset_id("0") == 0);
REQUIRE(osmium::string_to_changeset_id("1") == 1);
REQUIRE_THROWS_AS(osmium::string_to_changeset_id("-1"), const std::range_error&);
REQUIRE_THROWS_AS(osmium::string_to_changeset_id(""), const std::range_error&);
REQUIRE_THROWS_AS(osmium::string_to_changeset_id(" "), const std::range_error&);
REQUIRE_THROWS_AS(osmium::string_to_changeset_id(" 22"), const std::range_error&);
REQUIRE_THROWS_AS(osmium::string_to_changeset_id("x"), const std::range_error&);
}
TEST_CASE("set user id from string") {
REQUIRE(osmium::string_to_user_id("0") == 0);
REQUIRE(osmium::string_to_user_id("1") == 1);
REQUIRE(osmium::string_to_user_id("-1") == -1);
REQUIRE_THROWS_AS(osmium::string_to_user_id("-2"), const std::range_error&);
REQUIRE_THROWS_AS(osmium::string_to_user_id(""), const std::range_error&);
REQUIRE_THROWS_AS(osmium::string_to_user_id(" "), const std::range_error&);
REQUIRE_THROWS_AS(osmium::string_to_user_id(" 22"), const std::range_error&);
REQUIRE_THROWS_AS(osmium::string_to_user_id("x"), const std::range_error&);
}
TEST_CASE("set num changes from string") {
REQUIRE(osmium::string_to_num_changes("0") == 0);
REQUIRE(osmium::string_to_num_changes("1") == 1);
REQUIRE_THROWS_AS(osmium::string_to_num_changes("-1"), const std::range_error&);
REQUIRE_THROWS_AS(osmium::string_to_num_changes(""), const std::range_error&);
REQUIRE_THROWS_AS(osmium::string_to_num_changes(" "), const std::range_error&);
REQUIRE_THROWS_AS(osmium::string_to_num_changes(" 22"), const std::range_error&);
REQUIRE_THROWS_AS(osmium::string_to_num_changes("x"), const std::range_error&);
}
+101
View File
@@ -0,0 +1,101 @@
#include "catch.hpp"
#include <boost/crc.hpp>
#include <osmium/builder/attr.hpp>
#include <osmium/builder/osm_object_builder.hpp>
#include <osmium/osm/crc.hpp>
#include <osmium/osm/way.hpp>
using namespace osmium::builder::attr;
TEST_CASE("Build way") {
osmium::memory::Buffer buffer{10000};
osmium::builder::add_way(buffer,
_id(17),
_version(3),
_visible(true),
_cid(333),
_uid(21),
_timestamp(time_t(123)),
_user("foo"),
_tag("highway", "residential"),
_tag("name", "High Street"),
_nodes({1, 3, 2})
);
const osmium::Way& way = buffer.get<osmium::Way>(0);
REQUIRE(osmium::item_type::way == way.type());
REQUIRE(way.type_is_in(osmium::osm_entity_bits::way));
REQUIRE(way.type_is_in(osmium::osm_entity_bits::node | osmium::osm_entity_bits::way));
REQUIRE(17 == way.id());
REQUIRE(3 == way.version());
REQUIRE(true == way.visible());
REQUIRE(333 == way.changeset());
REQUIRE(21 == way.uid());
REQUIRE(std::string("foo") == way.user());
REQUIRE(123 == uint32_t(way.timestamp()));
REQUIRE(2 == way.tags().size());
REQUIRE(3 == way.nodes().size());
REQUIRE(1 == way.nodes()[0].ref());
REQUIRE(3 == way.nodes()[1].ref());
REQUIRE(2 == way.nodes()[2].ref());
REQUIRE_FALSE(way.is_closed());
osmium::CRC<boost::crc_32_type> crc32;
crc32.update(way);
REQUIRE(crc32().checksum() == 0x65f6ba91);
}
TEST_CASE("build closed way") {
osmium::memory::Buffer buffer{10000};
osmium::builder::add_way(buffer,
_tag("highway", "residential"),
_tag("name", "High Street"),
_nodes({1, 3, 1})
);
const osmium::Way& way = buffer.get<osmium::Way>(0);
REQUIRE(way.is_closed());
}
TEST_CASE("build way with helpers") {
osmium::memory::Buffer buffer{10000};
{
osmium::builder::WayBuilder builder(buffer);
builder.set_user("username");
builder.add_tags({
{"amenity", "restaurant"},
{"name", "Zum goldenen Schwanen"}
});
builder.add_node_refs({
{22, {3.5, 4.7}},
{67, {4.1, 2.2}}
});
}
buffer.commit();
const osmium::Way& way = buffer.get<osmium::Way>(0);
REQUIRE(std::string("username") == way.user());
REQUIRE(2 == way.tags().size());
REQUIRE(std::string("amenity") == way.tags().begin()->key());
REQUIRE(std::string("Zum goldenen Schwanen") == way.tags()["name"]);
REQUIRE(2 == way.nodes().size());
REQUIRE(22 == way.nodes()[0].ref());
REQUIRE(4.1 == Approx(way.nodes()[1].location().lon()));
const osmium::Box envelope = way.envelope();
REQUIRE(envelope.bottom_left().lon() == Approx(3.5));
REQUIRE(envelope.bottom_left().lat() == Approx(2.2));
REQUIRE(envelope.top_right().lon() == Approx(4.1));
REQUIRE(envelope.top_right().lat() == Approx(4.7));
}