format dir test

format dir test

fix
This commit is contained in:
Mathis Logemann 2022-01-26 23:25:53 +01:00
parent d5a873e81c
commit 6dcf754077
101 changed files with 9420 additions and 9408 deletions

View file

@ -261,6 +261,10 @@ auto const feature_part_def = feature_type
| |
(omit[geojson_string] > lit(':') > omit[value]) (omit[geojson_string] > lit(':') > omit[value])
; ;
auto const feature_rule_def = lit('{') > feature_part % lit(',') > lit('}');
auto const geometry_rule_def = (lit('{') > geometry_tuple[create_geometry] > lit('}')) | lit("null");
// clang-format on // clang-format on
#include <mapnik/warning.hpp> #include <mapnik/warning.hpp>

View file

@ -46,6 +46,6 @@ inline void run_cleanup()
u_cleanup(); u_cleanup();
} }
} } // namespace testing
#endif #endif

View file

@ -14,11 +14,16 @@
#include <iostream> #include <iostream>
// geojson box of the world // geojson box of the world
const std::string geojson("{ \"type\": \"Feature\", \"properties\": { }, \"geometry\": { \"type\": \"Polygon\", \"coordinates\": [ [ [ -17963313.143242701888084, -6300857.11560364998877 ], [ -17963313.143242701888084, 13071343.332991421222687 ], [ 7396658.353099936619401, 13071343.332991421222687 ], [ 7396658.353099936619401, -6300857.11560364998877 ], [ -17963313.143242701888084, -6300857.11560364998877 ] ] ] } }"); const std::string
geojson("{ \"type\": \"Feature\", \"properties\": { }, \"geometry\": { \"type\": \"Polygon\", \"coordinates\": [ [ [ "
"-17963313.143242701888084, -6300857.11560364998877 ], [ -17963313.143242701888084, 13071343.332991421222687 "
"], [ 7396658.353099936619401, 13071343.332991421222687 ], [ 7396658.353099936619401, "
"-6300857.11560364998877 ], [ -17963313.143242701888084, -6300857.11560364998877 ] ] ] } }");
TEST_CASE("agg_rasterizer_integer_overflow") { TEST_CASE("agg_rasterizer_integer_overflow")
{
SECTION("coordinates_do_not_overflow_and_polygon_is_rendered") { SECTION("coordinates_do_not_overflow_and_polygon_is_rendered")
{
auto expected_color = mapnik::color("white"); auto expected_color = mapnik::color("white");
mapnik::Map m(256, 256); mapnik::Map m(256, 256);
@ -48,7 +53,8 @@ SECTION("coordinates_do_not_overflow_and_polygon_is_rendered") {
m.add_layer(std::move(lyr)); m.add_layer(std::move(lyr));
// 17/20864/45265.png // 17/20864/45265.png
m.zoom_to_box(mapnik::box2d<double>(-13658379.710221574,6197514.253362091,-13657768.213995293,6198125.749588372)); m.zoom_to_box(
mapnik::box2d<double>(-13658379.710221574, 6197514.253362091, -13657768.213995293, 6198125.749588372));
// works 15/5216/11316.png // works 15/5216/11316.png
// m.zoom_to_box(mapnik::box2d<double>(-13658379.710221574,6195679.764683247,-13655933.72531645,6198125.749588372)); // m.zoom_to_box(mapnik::box2d<double>(-13658379.710221574,6195679.764683247,-13655933.72531645,6198125.749588372));

View file

@ -9,9 +9,10 @@
#include <vector> #include <vector>
#include <algorithm> #include <algorithm>
TEST_CASE("datasource_cache") { TEST_CASE("datasource_cache")
{
SECTION("registration") { SECTION("registration")
{
try try
{ {
mapnik::logger logger; mapnik::logger logger;
@ -41,12 +42,10 @@ SECTION("registration") {
success = cache.register_datasources("plugins/input", true); success = cache.register_datasources("plugins/input", true);
CHECK(success == false); CHECK(success == false);
} }
} } catch (std::exception const& ex)
catch (std::exception const & ex)
{ {
std::clog << ex.what() << "\n"; std::clog << ex.what() << "\n";
REQUIRE(false); REQUIRE(false);
} }
} }
} }

View file

@ -11,9 +11,10 @@
#include <vector> #include <vector>
#include <algorithm> #include <algorithm>
TEST_CASE("font") { TEST_CASE("font")
{
SECTION("registration") { SECTION("registration")
{
try try
{ {
mapnik::logger logger; mapnik::logger logger;
@ -164,12 +165,10 @@ SECTION("registration") {
mapnik::freetype_engine::register_fonts("C:\\Windows\\Fonts", true); mapnik::freetype_engine::register_fonts("C:\\Windows\\Fonts", true);
face_names = mapnik::freetype_engine::face_names(); face_names = mapnik::freetype_engine::face_names();
REQUIRE(face_names.size() > 22); REQUIRE(face_names.size() > 22);
} } catch (std::exception const& ex)
catch (std::exception const & ex)
{ {
std::clog << ex.what() << "\n"; std::clog << ex.what() << "\n";
REQUIRE(false); REQUIRE(false);
} }
} }
} }

View file

@ -17,17 +17,20 @@ namespace bfs = boost::filesystem;
namespace { namespace {
class tmp_dir { class tmp_dir
{
private: private:
bfs::path m_path; bfs::path m_path;
public: public:
tmp_dir() tmp_dir()
: m_path(bfs::temp_directory_path() / bfs::unique_path("mapnik-test-%%%%-%%%%-%%%%-%%%%")) { : m_path(bfs::temp_directory_path() / bfs::unique_path("mapnik-test-%%%%-%%%%-%%%%-%%%%"))
{
bfs::create_directories(m_path); bfs::create_directories(m_path);
} }
~tmp_dir() { ~tmp_dir()
{
// files might be deleted by other things while the test is // files might be deleted by other things while the test is
// running, which isn't necessarily an error as far as this // running, which isn't necessarily an error as far as this
// code is concerned - it just wants to delete everything // code is concerned - it just wants to delete everything
@ -35,38 +38,40 @@ public:
boost::system::error_code err; boost::system::error_code err;
// catch all errors - we don't want to throw in the destructor // catch all errors - we don't want to throw in the destructor
try { try
{
// but loop while the path exists and the errors are // but loop while the path exists and the errors are
// ignorable. // ignorable.
while (bfs::exists(m_path)) { while (bfs::exists(m_path))
{
bfs::remove_all(m_path, err); bfs::remove_all(m_path, err);
// for any non-ignorable error, there's not much we can // for any non-ignorable error, there's not much we can
// do from the destructor. it's in /tmp anyway, so it'll // do from the destructor. it's in /tmp anyway, so it'll
// get reclaimed next boot. // get reclaimed next boot.
if (err && (err != boost::system::errc::no_such_file_or_directory)) { if (err && (err != boost::system::errc::no_such_file_or_directory))
{
break; break;
} }
} }
} catch (const std::exception &e) { } catch (const std::exception& e)
{
std::cerr << "Exception caught while trying to remove " std::cerr << "Exception caught while trying to remove "
<< "temporary directory " << m_path << "temporary directory " << m_path << ": " << e.what() << "\n";
<< ": " << e.what() << "\n";
} catch (...) { } catch (...)
{
std::cerr << "Unknown exception caught while trying to " std::cerr << "Unknown exception caught while trying to "
<< "remove temporary directory " << m_path << "remove temporary directory " << m_path << "\n";
<< "\n";
} }
} }
bfs::path path() const { bfs::path path() const { return m_path; }
return m_path;
}
}; };
void compare_map(bfs::path xml) { void compare_map(bfs::path xml)
{
tmp_dir dir; tmp_dir dir;
mapnik::Map m(256, 256); mapnik::Map m(256, 256);
REQUIRE(m.register_fonts("fonts", true)); REQUIRE(m.register_fonts("fonts", true));
@ -94,34 +99,37 @@ void compare_map(bfs::path xml) {
REQUIRE(bfs::is_regular_file(test_map2)); REQUIRE(bfs::is_regular_file(test_map2));
REQUIRE(bfs::file_size(test_map1) == bfs::file_size(test_map2)); REQUIRE(bfs::file_size(test_map1) == bfs::file_size(test_map2));
std::ifstream in_map1(test_map1.native()), in_map2(test_map2.native()); std::ifstream in_map1(test_map1.native()), in_map2(test_map2.native());
REQUIRE(std::equal(std::istream_iterator<char>(in_map1), std::istream_iterator<char>(), REQUIRE(std::equal(std::istream_iterator<char>(in_map1),
std::istream_iterator<char>(),
std::istream_iterator<char>(in_map2))); std::istream_iterator<char>(in_map2)));
} }
void add_xml_files(bfs::path dir, std::vector<bfs::path> &xml_files) { void add_xml_files(bfs::path dir, std::vector<bfs::path>& xml_files)
for (auto const &entry : boost::make_iterator_range( {
bfs::directory_iterator(dir), bfs::directory_iterator())) { for (auto const& entry : boost::make_iterator_range(bfs::directory_iterator(dir), bfs::directory_iterator()))
{
auto path = entry.path(); auto path = entry.path();
if (path.extension().generic_string() == ".xml") { if (path.extension().generic_string() == ".xml")
{
xml_files.emplace_back(path); xml_files.emplace_back(path);
} }
} }
} }
void load_map(mapnik::Map &m, bfs::path const &path) { void load_map(mapnik::Map& m, bfs::path const& path)
{
try try
{ {
mapnik::load_map(m, path.generic_string()); mapnik::load_map(m, path.generic_string());
} } catch (std::exception const& ex)
catch (std::exception const &ex)
{ {
// errors which come from the datasource not being loaded or // errors which come from the datasource not being loaded or
// database not being set up aren't really useful - they're // database not being set up aren't really useful - they're
// more likely to be spurious than meaningful, so ignore them. // more likely to be spurious than meaningful, so ignore them.
std::string what = ex.what(); std::string what = ex.what();
if ((what.find("Could not create datasource") == std::string::npos) && if ((what.find("Could not create datasource") == std::string::npos) &&
(what.find("Postgis Plugin: could not connect to server") == std::string::npos)) { (what.find("Postgis Plugin: could not connect to server") == std::string::npos))
{
throw; throw;
} }
} }
@ -129,9 +137,11 @@ void load_map(mapnik::Map &m, bfs::path const &path) {
} // anonymous namespace } // anonymous namespace
const bool registered = mapnik::datasource_cache::instance().register_datasources((bfs::path("plugins") / "input").generic_string()); const bool registered =
mapnik::datasource_cache::instance().register_datasources((bfs::path("plugins") / "input").generic_string());
TEST_CASE("map xml I/O") { TEST_CASE("map xml I/O")
{
// make sure plugins are loaded // make sure plugins are loaded
REQUIRE(registered); REQUIRE(registered);
@ -139,11 +149,13 @@ TEST_CASE("map xml I/O") {
auto const severity = mapnik::logger::instance().get_severity(); auto const severity = mapnik::logger::instance().get_severity();
mapnik::logger::instance().set_severity(mapnik::logger::none); mapnik::logger::instance().set_severity(mapnik::logger::none);
SECTION("good maps") { SECTION("good maps")
{
std::vector<bfs::path> good_maps; std::vector<bfs::path> good_maps;
add_xml_files(bfs::path("test") / "data" / "good_maps", good_maps); add_xml_files(bfs::path("test") / "data" / "good_maps", good_maps);
for (auto const &path : good_maps) { for (auto const& path : good_maps)
{
CAPTURE(path.generic_string()); CAPTURE(path.generic_string());
// check that it can load // check that it can load
@ -156,8 +168,10 @@ TEST_CASE("map xml I/O") {
} }
} // END SECTION } // END SECTION
SECTION("duplicate styles only throw in strict mode") { SECTION("duplicate styles only throw in strict mode")
std::string duplicate_stylename((bfs::path("test") / "data" / "broken_maps" / "duplicate_stylename.xml").generic_string()); {
std::string duplicate_stylename(
(bfs::path("test") / "data" / "broken_maps" / "duplicate_stylename.xml").generic_string());
CAPTURE(duplicate_stylename); CAPTURE(duplicate_stylename);
mapnik::Map m(256, 256); mapnik::Map m(256, 256);
REQUIRE(m.register_fonts("fonts", true)); REQUIRE(m.register_fonts("fonts", true));
@ -167,12 +181,14 @@ TEST_CASE("map xml I/O") {
REQUIRE_THROWS(mapnik::load_map(m2, duplicate_stylename, true)); REQUIRE_THROWS(mapnik::load_map(m2, duplicate_stylename, true));
} // END SECTION } // END SECTION
SECTION("broken maps") { SECTION("broken maps")
{
std::vector<bfs::path> broken_maps; std::vector<bfs::path> broken_maps;
add_xml_files(bfs::path("test") / "data" / "broken_maps", broken_maps); add_xml_files(bfs::path("test") / "data" / "broken_maps", broken_maps);
broken_maps.emplace_back(bfs::path("test") / "data" / "broken_maps" / "does_not_exist.xml"); broken_maps.emplace_back(bfs::path("test") / "data" / "broken_maps" / "does_not_exist.xml");
for (auto const &path : broken_maps) { for (auto const& path : broken_maps)
{
CAPTURE(path.generic_string()); CAPTURE(path.generic_string());
mapnik::Map m(256, 256); mapnik::Map m(256, 256);

View file

@ -7,8 +7,8 @@
#include <sstream> #include <sstream>
TEST_CASE("CSS color") { TEST_CASE("CSS color")
{
SECTION("conversions") SECTION("conversions")
{ {
using namespace mapnik::css_color_grammar; using namespace mapnik::css_color_grammar;

View file

@ -4,15 +4,18 @@
#include <mapnik/geometry/box2d.hpp> #include <mapnik/geometry/box2d.hpp>
#include "agg_trans_affine.h" #include "agg_trans_affine.h"
TEST_CASE("box2d") { TEST_CASE("box2d")
SECTION("coord init") { {
SECTION("coord init")
{
auto c = mapnik::coord2d(100, 100); auto c = mapnik::coord2d(100, 100);
REQUIRE(c.x == 100); REQUIRE(c.x == 100);
REQUIRE(c.y == 100); REQUIRE(c.y == 100);
} }
SECTION("coord multiplication") { SECTION("coord multiplication")
{
auto c = mapnik::coord2d(100, 100); auto c = mapnik::coord2d(100, 100);
c *= 2; c *= 2;
@ -20,7 +23,8 @@ SECTION("coord multiplication") {
REQUIRE(c.y == 200); REQUIRE(c.y == 200);
} }
SECTION("envelope init") { SECTION("envelope init")
{
auto e = mapnik::box2d<double>(100, 100, 200, 200); auto e = mapnik::box2d<double>(100, 100, 200, 200);
REQUIRE(e.contains(100, 100)); REQUIRE(e.contains(100, 100));
@ -59,7 +63,8 @@ SECTION("envelope init") {
REQUIRE(c.y == 150); REQUIRE(c.y == 150);
} }
SECTION("envelope static init") { SECTION("envelope static init")
{
auto e = mapnik::box2d<double>(100, 100, 200, 200); auto e = mapnik::box2d<double>(100, 100, 200, 200);
mapnik::box2d<double> e1, e2, e3; mapnik::box2d<double> e1, e2, e3;
@ -72,7 +77,8 @@ SECTION("envelope static init") {
REQUIRE(e == e3); REQUIRE(e == e3);
} }
SECTION("envelope multiplication") { SECTION("envelope multiplication")
{
// no width then no impact of multiplication // no width then no impact of multiplication
{ {
auto a = mapnik::box2d<int>(100, 100, 100, 100); auto a = mapnik::box2d<int>(100, 100, 100, 100);
@ -141,7 +147,8 @@ SECTION("envelope multiplication") {
} }
} }
SECTION("envelope clipping") { SECTION("envelope clipping")
{
auto e1 = mapnik::box2d<double>(-180, -90, 180, 90); auto e1 = mapnik::box2d<double>(-180, -90, 180, 90);
auto e2 = mapnik::box2d<double>(-120, 40, -110, 48); auto e2 = mapnik::box2d<double>(-120, 40, -110, 48);
e1.clip(e2); e1.clip(e2);

View file

@ -52,7 +52,6 @@ TEST_CASE("comparison")
REQUIRE(v0 != v3); REQUIRE(v0 != v3);
REQUIRE(v1 != v3); REQUIRE(v1 != v3);
REQUIRE(v2 != v3); REQUIRE(v2 != v3);
} }
SECTION("operator<,<=,>,>=") SECTION("operator<,<=,>,>=")
{ {

View file

@ -13,16 +13,16 @@
#include <cstdio> #include <cstdio>
#endif #endif
TEST_CASE("conversions") { TEST_CASE("conversions")
{
SECTION("to string") { SECTION("to string")
{
#if defined(_MSC_VER) && _MSC_VER < 1900 #if defined(_MSC_VER) && _MSC_VER < 1900
unsigned int old = _set_output_format(_TWO_DIGIT_EXPONENT); unsigned int old = _set_output_format(_TWO_DIGIT_EXPONENT);
#endif #endif
using mapnik::util::to_string;
using mapnik::util::string2bool; using mapnik::util::string2bool;
using mapnik::util::to_string;
try try
{ {
@ -301,12 +301,10 @@ SECTION("to string") {
s << streamable; s << streamable;
CHECK(s.str() == std::string("hello world!")); CHECK(s.str() == std::string("hello world!"));
} } catch (std::exception const& ex)
catch (std::exception const & ex)
{ {
std::clog << ex.what() << "\n"; std::clog << ex.what() << "\n";
REQUIRE(false); REQUIRE(false);
} }
} }
} }

View file

@ -8,11 +8,10 @@
#include "catch.hpp" #include "catch.hpp"
TEST_CASE("copy")
TEST_CASE("copy") { {
SECTION("layers")
SECTION("layers") { {
try try
{ {
mapnik::Map m0(100, 100); mapnik::Map m0(100, 100);
@ -69,8 +68,7 @@ SECTION("layers") {
REQUIRE((m0 == m2)); REQUIRE((m0 == m2));
} }
} } catch (std::exception const& ex)
catch (std::exception const & ex)
{ {
std::clog << ex.what() << "\n"; std::clog << ex.what() << "\n";
REQUIRE(false); REQUIRE(false);

View file

@ -20,34 +20,41 @@
#include <vector> #include <vector>
#include <algorithm> #include <algorithm>
TEST_CASE("exceptions") { TEST_CASE("exceptions")
{
SECTION("handling") { SECTION("handling")
try { {
try
{
mapnik::projection srs("FAIL"); mapnik::projection srs("FAIL");
// to avoid unused variable warning // to avoid unused variable warning
srs.params(); srs.params();
REQUIRE(false); REQUIRE(false);
} catch (...) { } catch (...)
{
REQUIRE(true); REQUIRE(true);
} }
// https://github.com/mapnik/mapnik/issues/2170 // https://github.com/mapnik/mapnik/issues/2170
try { try
{
mapnik::projection srs("epsg:4326 foo", true); mapnik::projection srs("epsg:4326 foo", true);
REQUIRE(srs.is_geographic()); REQUIRE(srs.is_geographic());
REQUIRE(true); REQUIRE(true);
srs.init_proj(); srs.init_proj();
// oddly init_proj does not throw with old proj/ubuntu precise // oddly init_proj does not throw with old proj/ubuntu precise
// REQUIRE(false); // REQUIRE(false);
} catch (...) { } catch (...)
{
REQUIRE(true); REQUIRE(true);
} }
try { try
{
mapnik::transcoder tr("bogus encoding"); mapnik::transcoder tr("bogus encoding");
REQUIRE(false); REQUIRE(false);
} catch (...) { } catch (...)
{
REQUIRE(true); REQUIRE(true);
} }
@ -60,8 +67,10 @@ SECTION("handling") {
map.insert_style("style", std::move(style)); map.insert_style("style", std::move(style));
std::string csv_plugin("./plugins/input/csv.input"); std::string csv_plugin("./plugins/input/csv.input");
if (mapnik::util::exists(csv_plugin)) { if (mapnik::util::exists(csv_plugin))
try { {
try
{
mapnik::parameters p; mapnik::parameters p;
p["type"] = "csv"; p["type"] = "csv";
p["inline"] = "x,y\n0,0"; p["inline"] = "x,y\n0,0";
@ -79,23 +88,26 @@ SECTION("handling") {
// should throw here with "CSV Plugin: no attribute 'foo'. Valid attributes are: x,y." // should throw here with "CSV Plugin: no attribute 'foo'. Valid attributes are: x,y."
ren.apply(); ren.apply();
REQUIRE(false); REQUIRE(false);
} catch (...) { } catch (...)
{
REQUIRE(true); REQUIRE(true);
} }
} }
std::string shape_plugin("./plugins/input/shape.input"); std::string shape_plugin("./plugins/input/shape.input");
if (mapnik::util::exists(shape_plugin)) { if (mapnik::util::exists(shape_plugin))
try { {
try
{
mapnik::parameters p2; mapnik::parameters p2;
p2["type"] = "shape"; p2["type"] = "shape";
p2["file"] = "foo"; p2["file"] = "foo";
mapnik::datasource_cache::instance().create(p2); mapnik::datasource_cache::instance().create(p2);
REQUIRE(false); REQUIRE(false);
} catch (...) { } catch (...)
{
REQUIRE(true); REQUIRE(true);
} }
} }
} }
} }

View file

@ -36,8 +36,8 @@ template <typename Feature, typename Expression>
mapnik::value_type evaluate(Feature const& feature, Expression const& expr) mapnik::value_type evaluate(Feature const& feature, Expression const& expr)
{ {
auto value = mapnik::util::apply_visitor( auto value = mapnik::util::apply_visitor(
mapnik::evaluate<Feature, mapnik::value_type, mapnik::attributes>( mapnik::evaluate<Feature, mapnik::value_type, mapnik::attributes>(feature, mapnik::attributes()),
feature, mapnik::attributes()), expr); expr);
return value; return value;
} }
@ -218,7 +218,6 @@ TEST_CASE("expressions")
TRY_CHECK(val7.to_string() == val8.to_string()); // UTF-8 TRY_CHECK(val7.to_string() == val8.to_string()); // UTF-8
TRY_CHECK(val7.to_unicode() == val8.to_unicode()); // Unicode TRY_CHECK(val7.to_unicode() == val8.to_unicode()); // Unicode
// following test will fail if boost_regex is built without ICU support (unpaired surrogates in output) // following test will fail if boost_regex is built without ICU support (unpaired surrogates in output)
TRY_CHECK(eval("[name].replace('(\\B)|( )',' ') ") == tr.transcode("Q u é b e c")); TRY_CHECK(eval("[name].replace('(\\B)|( )',' ') ") == tr.transcode("Q u é b e c"));
TRY_CHECK(eval("'Москва'.replace('(?<!^)(\\B|b)(?!$)',' ')") == tr.transcode("М о с к в а")); TRY_CHECK(eval("'Москва'.replace('(?<!^)(\\B|b)(?!$)',' ')") == tr.transcode("М о с к в а"));

View file

@ -9,24 +9,24 @@
namespace detail { namespace detail {
class string_holder { class string_holder
public:
string_holder() :
member_("member") {}
std::string const& get_string() const
{ {
return member_; public:
} string_holder()
: member_("member")
{}
std::string const& get_string() const { return member_; }
private: private:
std::string member_; std::string member_;
}; };
} } // namespace detail
TEST_CASE("parameters") {
SECTION("get/set") {
TEST_CASE("parameters")
{
SECTION("get/set")
{
try try
{ {
mapnik::parameters params; mapnik::parameters params;
@ -89,7 +89,8 @@ SECTION("get/set") {
// value_null // value_null
params["null"] = mapnik::value_null(); params["null"] = mapnik::value_null();
// https://github.com/mapnik/mapnik/issues/2471 // https://github.com/mapnik/mapnik/issues/2471
//REQUIRE( (params.get<mapnik::value_null>("null") && *params.get<mapnik::value_null>("null") == mapnik::value_null()) ); // REQUIRE( (params.get<mapnik::value_null>("null") && *params.get<mapnik::value_null>("null") ==
// mapnik::value_null()) );
std::string value("value"); std::string value("value");
params["value"] = value; params["value"] = value;
@ -102,12 +103,10 @@ SECTION("get/set") {
params["member"] = holder_member; params["member"] = holder_member;
REQUIRE((params.get<std::string>("member") == std::string("member"))); REQUIRE((params.get<std::string>("member") == std::string("member")));
REQUIRE((holder_member == std::string("member"))); REQUIRE((holder_member == std::string("member")));
} } catch (std::exception const& ex)
catch (std::exception const& ex)
{ {
std::cerr << ex.what() << "\n"; std::cerr << ex.what() << "\n";
REQUIRE(false); REQUIRE(false);
} }
} }
} }

View file

@ -5,14 +5,13 @@
namespace { namespace {
bool test_transform_expressions(std::string const& in, std::string const& out) bool test_transform_expressions(std::string const& in, std::string const& out)
{ {
auto tr_list = mapnik::parse_transform(in); auto tr_list = mapnik::parse_transform(in);
return mapnik::to_expression_string(*tr_list) == out; return mapnik::to_expression_string(*tr_list) == out;
} }
} } // namespace
TEST_CASE("transform-expressions") TEST_CASE("transform-expressions")
{ {
@ -56,5 +55,6 @@ TEST_CASE("transform-expressions")
// compound // compound
CHECK(test_transform_expressions("translate([tx]) rotate([a])", "translate([tx]) rotate([a])")); CHECK(test_transform_expressions("translate([tx]) rotate([a])", "translate([tx]) rotate([a])"));
CHECK(test_transform_expressions("rotate(30+@global_value) scale(2*[sx],[sy])", "rotate((30+@global_value)) scale(2*[sx], [sy])")); CHECK(test_transform_expressions("rotate(30+@global_value) scale(2*[sx],[sy])",
"rotate((30+@global_value)) scale(2*[sx], [sy])"));
} }

View file

@ -46,13 +46,11 @@ MAPNIK_DISABLE_WARNING_POP
#include <iostream> #include <iostream>
namespace { namespace {
bool is_csv(std::string const& filename) bool is_csv(std::string const& filename)
{ {
return boost::iends_with(filename,".csv") return boost::iends_with(filename, ".csv") || boost::iends_with(filename, ".tsv");
|| boost::iends_with(filename,".tsv");
} }
void add_csv_files(std::string dir, std::vector<std::string>& csv_files) void add_csv_files(std::string dir, std::vector<std::string>& csv_files)
@ -84,7 +82,8 @@ mapnik::datasource_ptr get_csv_ds(std::string const& file_name, bool strict = tr
} // anonymous namespace } // anonymous namespace
TEST_CASE("csv") { TEST_CASE("csv")
{
using mapnik::util::from_u8string; using mapnik::util::from_u8string;
std::string csv_plugin("./plugins/input/csv.input"); std::string csv_plugin("./plugins/input/csv.input");
if (mapnik::util::exists(csv_plugin)) if (mapnik::util::exists(csv_plugin))
@ -94,10 +93,8 @@ TEST_CASE("csv") {
mapnik::logger::instance().set_severity(mapnik::logger::none); mapnik::logger::instance().set_severity(mapnik::logger::none);
// check the CSV datasource is loaded // check the CSV datasource is loaded
const std::vector<std::string> plugin_names = const std::vector<std::string> plugin_names = mapnik::datasource_cache::instance().plugin_names();
mapnik::datasource_cache::instance().plugin_names(); const bool have_csv_plugin = std::find(plugin_names.begin(), plugin_names.end(), "csv") != plugin_names.end();
const bool have_csv_plugin =
std::find(plugin_names.begin(), plugin_names.end(), "csv") != plugin_names.end();
SECTION("CSV I/O errors") SECTION("CSV I/O errors")
{ {
@ -191,7 +188,9 @@ TEST_CASE("csv") {
int ret_posix = (ret >> 8) & 0x000000ff; int ret_posix = (ret >> 8) & 0x000000ff;
INFO(ret); INFO(ret);
INFO(ret_posix); INFO(ret_posix);
if (!boost::iends_with(path,"more_headers_than_column_values.csv")) // mapnik-index won't create *.index for 0 features if (!boost::iends_with(path,
"more_headers_than_column_values.csv")) // mapnik-index won't create
// *.index for 0 features
{ {
CHECK(mapnik::util::exists(path + ".index")); CHECK(mapnik::util::exists(path + ".index"));
} }
@ -243,10 +242,9 @@ TEST_CASE("csv") {
auto features = ds->features(query); auto features = ds->features(query);
auto feature = features->next(); auto feature = features->next();
REQUIRE_ATTRIBUTES(feature, { REQUIRE_ATTRIBUTES(
attr { lon_name, mapnik::value_integer(0) }, feature,
attr { "lat", mapnik::value_integer(0) } {attr{lon_name, mapnik::value_integer(0)}, attr{"lat", mapnik::value_integer(0)}});
});
if (mapnik::util::exists(filename + ".index")) if (mapnik::util::exists(filename + ".index"))
{ {
mapnik::util::remove(filename + ".index"); mapnik::util::remove(filename + ".index");
@ -278,8 +276,17 @@ TEST_CASE("csv") {
auto ds = get_csv_ds(filename, true, base); auto ds = get_csv_ds(filename, true, base);
CHECK(ds->type() == mapnik::datasource::datasource_t::Vector); CHECK(ds->type() == mapnik::datasource::datasource_t::Vector);
auto fields = ds->get_descriptor().get_descriptors(); auto fields = ds->get_descriptor().get_descriptors();
require_field_names(fields, {"Precinct", "Phone", "Address", "City", "geo_longitude", "geo_latitude", "geo_accuracy"}); require_field_names(
require_field_types(fields, {mapnik::String, mapnik::String, mapnik::String, mapnik::String, mapnik::Double, mapnik::Double, mapnik::String}); fields,
{"Precinct", "Phone", "Address", "City", "geo_longitude", "geo_latitude", "geo_accuracy"});
require_field_types(fields,
{mapnik::String,
mapnik::String,
mapnik::String,
mapnik::String,
mapnik::Double,
mapnik::Double,
mapnik::String});
CHECK(ds->get_geometry_type() == mapnik::datasource_geometry_t::Point); CHECK(ds->get_geometry_type() == mapnik::datasource_geometry_t::Point);
CHECK(count_features(all_features(ds)) == 2); CHECK(count_features(all_features(ds)) == 2);
@ -291,15 +298,13 @@ TEST_CASE("csv") {
auto feature2 = fs2->next(); auto feature2 = fs2->next();
REQUIRE(feature != nullptr); REQUIRE(feature != nullptr);
REQUIRE(feature2 != nullptr); REQUIRE(feature2 != nullptr);
auto expected_attr = { auto expected_attr = {attr{"City", mapnik::value_unicode_string("New York, NY")},
attr { "City", mapnik::value_unicode_string("New York, NY") } attr{"geo_accuracy", mapnik::value_unicode_string("house")},
, attr { "geo_accuracy", mapnik::value_unicode_string("house") } attr{"Phone", mapnik::value_unicode_string("(212) 334-0711")},
, attr { "Phone", mapnik::value_unicode_string("(212) 334-0711") } attr{"Address", mapnik::value_unicode_string("19 Elizabeth Street")},
, attr { "Address", mapnik::value_unicode_string("19 Elizabeth Street") } attr{"Precinct", mapnik::value_unicode_string("5th Precinct")},
, attr { "Precinct", mapnik::value_unicode_string("5th Precinct") } attr{"geo_longitude", mapnik::value_double(-70.0)},
, attr { "geo_longitude", mapnik::value_double(-70.0) } attr{"geo_latitude", mapnik::value_double(40.0)}};
, attr { "geo_latitude", mapnik::value_double(40.0) }
};
REQUIRE_ATTRIBUTES(feature, expected_attr); REQUIRE_ATTRIBUTES(feature, expected_attr);
REQUIRE_ATTRIBUTES(feature2, expected_attr); REQUIRE_ATTRIBUTES(feature2, expected_attr);
if (mapnik::util::exists(filepath + ".index")) if (mapnik::util::exists(filepath + ".index"))
@ -361,28 +366,39 @@ TEST_CASE("csv") {
auto ds = get_csv_ds(filename); auto ds = get_csv_ds(filename);
auto fields = ds->get_descriptor().get_descriptors(); auto fields = ds->get_descriptor().get_descriptors();
require_field_names(fields, {"x", "y", "text", "date", "integer", "boolean", "float", "time", "datetime", "empty_column"}); require_field_names(
require_field_types(fields, {mapnik::Integer, mapnik::Integer, mapnik::String, mapnik::String, fields,
mapnik::Integer, mapnik::Boolean, mapnik::Double, mapnik::String, mapnik::String, mapnik::String}); {"x", "y", "text", "date", "integer", "boolean", "float", "time", "datetime", "empty_column"});
require_field_types(fields,
{mapnik::Integer,
mapnik::Integer,
mapnik::String,
mapnik::String,
mapnik::Integer,
mapnik::Boolean,
mapnik::Double,
mapnik::String,
mapnik::String,
mapnik::String});
CHECK(ds->get_geometry_type() == mapnik::datasource_geometry_t::Point); CHECK(ds->get_geometry_type() == mapnik::datasource_geometry_t::Point);
CHECK(count_features(all_features(ds)) == 4); CHECK(count_features(all_features(ds)) == 4);
auto featureset = all_features(ds); auto featureset = all_features(ds);
auto feature = featureset->next(); auto feature = featureset->next();
REQUIRE_ATTRIBUTES(feature, { REQUIRE_ATTRIBUTES(feature,
attr { "x", mapnik::value_integer(0) } {attr{"x", mapnik::value_integer(0)},
, attr { "empty_column", mapnik::value_unicode_string("") } attr{"empty_column", mapnik::value_unicode_string("")},
, attr { "text", mapnik::value_unicode_string("a b") } attr{"text", mapnik::value_unicode_string("a b")},
, attr { "float", mapnik::value_double(1.0) } attr{"float", mapnik::value_double(1.0)},
, attr { "datetime", mapnik::value_unicode_string("1971-01-01T04:14:00") } attr{"datetime", mapnik::value_unicode_string("1971-01-01T04:14:00")},
, attr { "y", mapnik::value_integer(0) } attr{"y", mapnik::value_integer(0)},
, attr { "boolean", mapnik::value_bool(true) } attr{"boolean", mapnik::value_bool(true)},
, attr { "time", mapnik::value_unicode_string("04:14:00") } attr{"time", mapnik::value_unicode_string("04:14:00")},
, attr { "date", mapnik::value_unicode_string("1971-01-01") } attr{"date", mapnik::value_unicode_string("1971-01-01")},
, attr { "integer", mapnik::value_integer(40) } attr{"integer", mapnik::value_integer(40)}});
});
while (bool(feature = featureset->next())) { while (bool(feature = featureset->next()))
{
CHECK(feature->size() == 10); CHECK(feature->size() == 10);
CHECK(feature->get("empty_column") == mapnik::value_unicode_string("")); CHECK(feature->get("empty_column") == mapnik::value_unicode_string(""));
} }
@ -418,18 +434,12 @@ TEST_CASE("csv") {
require_field_types(fields, {mapnik::Integer, mapnik::Integer, mapnik::String}); require_field_types(fields, {mapnik::Integer, mapnik::Integer, mapnik::String});
auto featureset = all_features(ds); auto featureset = all_features(ds);
REQUIRE_ATTRIBUTES(featureset->next(), { REQUIRE_ATTRIBUTES(featureset->next(),
attr{"x", 0} {attr{"x", 0}, attr{"y", 0}, attr{"name", mapnik::value_unicode_string("a/a")}});
, attr{"y", 0} REQUIRE_ATTRIBUTES(featureset->next(),
, attr{"name", mapnik::value_unicode_string("a/a") } }); {attr{"x", 1}, attr{"y", 4}, attr{"name", mapnik::value_unicode_string("b/b")}});
REQUIRE_ATTRIBUTES(featureset->next(), { REQUIRE_ATTRIBUTES(featureset->next(),
attr{"x", 1} {attr{"x", 10}, attr{"y", 2.5}, attr{"name", mapnik::value_unicode_string("c/c")}});
, attr{"y", 4}
, attr{"name", mapnik::value_unicode_string("b/b") } });
REQUIRE_ATTRIBUTES(featureset->next(), {
attr{"x", 10}
, attr{"y", 2.5}
, attr{"name", mapnik::value_unicode_string("c/c") } });
if (mapnik::util::exists(filename + ".index")) if (mapnik::util::exists(filename + ".index"))
{ {
mapnik::util::remove(filename + ".index"); mapnik::util::remove(filename + ".index");
@ -533,18 +543,14 @@ TEST_CASE("csv") {
auto fields = ds->get_descriptor().get_descriptors(); auto fields = ds->get_descriptor().get_descriptors();
require_field_names(fields, {"x", "y", "1990", "1991", "1992"}); require_field_names(fields, {"x", "y", "1990", "1991", "1992"});
auto feature = all_features(ds)->next(); auto feature = all_features(ds)->next();
REQUIRE_ATTRIBUTES(feature, { REQUIRE_ATTRIBUTES(feature,
attr{"x", 0} {attr{"x", 0}, attr{"y", 0}, attr{"1990", 1}, attr{"1991", 2}, attr{"1992", 3}});
, attr{"y", 0}
, attr{"1990", 1}
, attr{"1991", 2}
, attr{"1992", 3}
});
auto expression = mapnik::parse_expression("[1991]=2"); auto expression = mapnik::parse_expression("[1991]=2");
REQUIRE(bool(expression)); REQUIRE(bool(expression));
auto value = mapnik::util::apply_visitor( auto value = mapnik::util::apply_visitor(
mapnik::evaluate<mapnik::feature_impl, mapnik::value_type, mapnik::attributes>( mapnik::evaluate<mapnik::feature_impl, mapnik::value_type, mapnik::attributes>(*feature,
*feature, mapnik::attributes()), *expression); mapnik::attributes()),
*expression);
CHECK(value == true); CHECK(value == true);
if (mapnik::util::exists(filename + ".index")) if (mapnik::util::exists(filename + ".index"))
{ {
@ -577,16 +583,12 @@ TEST_CASE("csv") {
require_field_names(fields, {"x", "y", "label"}); require_field_names(fields, {"x", "y", "label"});
auto featureset = all_features(ds); auto featureset = all_features(ds);
REQUIRE_ATTRIBUTES(featureset->next(), { REQUIRE_ATTRIBUTES(featureset->next(), {attr{"x", 0}, attr{"y", 0}, attr{"label", ustring("0,0")}});
attr{"x", 0}, attr{"y", 0}, attr{"label", ustring("0,0") } }); REQUIRE_ATTRIBUTES(featureset->next(), {attr{"x", 5}, attr{"y", 5}, attr{"label", ustring("5,5")}});
REQUIRE_ATTRIBUTES(featureset->next(), { REQUIRE_ATTRIBUTES(featureset->next(), {attr{"x", 0}, attr{"y", 5}, attr{"label", ustring("0,5")}});
attr{"x", 5}, attr{"y", 5}, attr{"label", ustring("5,5") } }); REQUIRE_ATTRIBUTES(featureset->next(), {attr{"x", 5}, attr{"y", 0}, attr{"label", ustring("5,0")}});
REQUIRE_ATTRIBUTES(featureset->next(), { REQUIRE_ATTRIBUTES(featureset->next(),
attr{"x", 0}, attr{"y", 5}, attr{"label", ustring("0,5") } }); {attr{"x", 2.5}, attr{"y", 2.5}, attr{"label", ustring("2.5,2.5")}});
REQUIRE_ATTRIBUTES(featureset->next(), {
attr{"x", 5}, attr{"y", 0}, attr{"label", ustring("5,0") } });
REQUIRE_ATTRIBUTES(featureset->next(), {
attr{"x", 2.5}, attr{"y", 2.5}, attr{"label", ustring("2.5,2.5") } });
if (mapnik::util::exists(filename + ".index")) if (mapnik::util::exists(filename + ".index"))
{ {
mapnik::util::remove(filename + ".index"); mapnik::util::remove(filename + ".index");
@ -617,8 +619,7 @@ TEST_CASE("csv") {
auto ds = get_csv_ds(filename); auto ds = get_csv_ds(filename);
auto fields = ds->get_descriptor().get_descriptors(); auto fields = ds->get_descriptor().get_descriptors();
require_field_names(fields, {"x", "y", "z"}); require_field_names(fields, {"x", "y", "z"});
REQUIRE_ATTRIBUTES(all_features(ds)->next(), { REQUIRE_ATTRIBUTES(all_features(ds)->next(), {attr{"x", 1}, attr{"y", 10}, attr{"z", 9999.9999}});
attr{"x", 1}, attr{"y", 10}, attr{"z", 9999.9999} });
if (mapnik::util::exists(filename + ".index")) if (mapnik::util::exists(filename + ".index"))
{ {
mapnik::util::remove(filename + ".index"); mapnik::util::remove(filename + ".index");
@ -632,12 +633,11 @@ TEST_CASE("csv") {
using ustring = mapnik::value_unicode_string; using ustring = mapnik::value_unicode_string;
for (auto create_index : {false, true}) for (auto create_index : {false, true})
{ {
for (auto const& filename : { for (auto const& filename :
std::string("test/data/csv/mac_newlines_with_unix_inline.csv") {std::string("test/data/csv/mac_newlines_with_unix_inline.csv"),
, std::string("test/data/csv/mac_newlines_with_unix_inline_escaped.csv") std::string("test/data/csv/mac_newlines_with_unix_inline_escaped.csv"),
, std::string("test/data/csv/windows_newlines_with_unix_inline.csv") std::string("test/data/csv/windows_newlines_with_unix_inline.csv"),
, std::string("test/data/csv/windows_newlines_with_unix_inline_escaped.csv") std::string("test/data/csv/windows_newlines_with_unix_inline_escaped.csv")})
})
{ {
// cleanup in the case of a failed previous run // cleanup in the case of a failed previous run
if (mapnik::util::exists(filename + ".index")) if (mapnik::util::exists(filename + ".index"))
@ -655,9 +655,10 @@ TEST_CASE("csv") {
auto ds = get_csv_ds(filename); auto ds = get_csv_ds(filename);
auto fields = ds->get_descriptor().get_descriptors(); auto fields = ds->get_descriptor().get_descriptors();
require_field_names(fields, {"x", "y", "line"}); require_field_names(fields, {"x", "y", "line"});
REQUIRE_ATTRIBUTES(all_features(ds)->next(), { REQUIRE_ATTRIBUTES(all_features(ds)->next(),
attr{"x", 0}, attr{"y", 0} {attr{"x", 0},
, attr{"line", ustring("many\n lines\n of text\n with unix newlines")} }); attr{"y", 0},
attr{"line", ustring("many\n lines\n of text\n with unix newlines")}});
if (mapnik::util::exists(filename + ".index")) if (mapnik::util::exists(filename + ".index"))
{ {
mapnik::util::remove(filename + ".index"); mapnik::util::remove(filename + ".index");
@ -686,8 +687,7 @@ TEST_CASE("csv") {
auto ds = get_csv_ds(filename); auto ds = get_csv_ds(filename);
auto fields = ds->get_descriptor().get_descriptors(); auto fields = ds->get_descriptor().get_descriptors();
require_field_names(fields, {"x", "y", "z"}); require_field_names(fields, {"x", "y", "z"});
REQUIRE_ATTRIBUTES(all_features(ds)->next(), { REQUIRE_ATTRIBUTES(all_features(ds)->next(), {attr{"x", -122}, attr{"y", 48}, attr{"z", 0}});
attr{"x", -122}, attr{"y", 48}, attr{"z", 0} });
if (mapnik::util::exists(filename + ".index")) if (mapnik::util::exists(filename + ".index"))
{ {
mapnik::util::remove(filename + ".index"); mapnik::util::remove(filename + ".index");
@ -698,10 +698,8 @@ TEST_CASE("csv") {
SECTION("separators") SECTION("separators")
{ {
using ustring = mapnik::value_unicode_string; using ustring = mapnik::value_unicode_string;
for (auto const& filename : { for (auto const& filename : {std::string("test/data/csv/pipe_delimiters.csv"),
std::string("test/data/csv/pipe_delimiters.csv") std::string("test/data/csv/semicolon_delimiters.csv")})
, std::string("test/data/csv/semicolon_delimiters.csv")
})
{ {
for (auto create_index : {false, true}) for (auto create_index : {false, true})
{ {
@ -721,8 +719,8 @@ TEST_CASE("csv") {
auto ds = get_csv_ds(filename); auto ds = get_csv_ds(filename);
auto fields = ds->get_descriptor().get_descriptors(); auto fields = ds->get_descriptor().get_descriptors();
require_field_names(fields, {"x", "y", "z"}); require_field_names(fields, {"x", "y", "z"});
REQUIRE_ATTRIBUTES(all_features(ds)->next(), { REQUIRE_ATTRIBUTES(all_features(ds)->next(),
attr{"x", 0}, attr{"y", 0}, attr{"z", ustring("hello")} }); {attr{"x", 0}, attr{"y", 0}, attr{"z", ustring("hello")}});
if (mapnik::util::exists(filename + ".index")) if (mapnik::util::exists(filename + ".index"))
{ {
mapnik::util::remove(filename + ".index"); mapnik::util::remove(filename + ".index");
@ -756,10 +754,10 @@ TEST_CASE("csv") {
require_field_types(fields, {mapnik::Integer, mapnik::Integer, mapnik::String, mapnik::Boolean}); require_field_types(fields, {mapnik::Integer, mapnik::Integer, mapnik::String, mapnik::Boolean});
auto featureset = all_features(ds); auto featureset = all_features(ds);
REQUIRE_ATTRIBUTES(featureset->next(), { REQUIRE_ATTRIBUTES(featureset->next(),
attr{"x", 0}, attr{"y", 0}, attr{"null", ustring("null")}, attr{"boolean", true}}); {attr{"x", 0}, attr{"y", 0}, attr{"null", ustring("null")}, attr{"boolean", true}});
REQUIRE_ATTRIBUTES(featureset->next(), { REQUIRE_ATTRIBUTES(featureset->next(),
attr{"x", 0}, attr{"y", 0}, attr{"null", ustring("")}, attr{"boolean", false}}); {attr{"x", 0}, attr{"y", 0}, attr{"null", ustring("")}, attr{"boolean", false}});
if (mapnik::util::exists(filename + ".index")) if (mapnik::util::exists(filename + ".index"))
{ {
@ -831,12 +829,9 @@ TEST_CASE("csv") {
require_field_types(fields, {mapnik::Integer, mapnik::Integer, mapnik::String}); require_field_types(fields, {mapnik::Integer, mapnik::Integer, mapnik::String});
auto featureset = all_features(ds); auto featureset = all_features(ds);
REQUIRE_ATTRIBUTES(featureset->next(), { REQUIRE_ATTRIBUTES(featureset->next(), {attr{"x", 0}, attr{"y", 0}, attr{"fips", ustring("001")}});
attr{"x", 0}, attr{"y", 0}, attr{"fips", ustring("001")}}); REQUIRE_ATTRIBUTES(featureset->next(), {attr{"x", 0}, attr{"y", 0}, attr{"fips", ustring("003")}});
REQUIRE_ATTRIBUTES(featureset->next(), { REQUIRE_ATTRIBUTES(featureset->next(), {attr{"x", 0}, attr{"y", 0}, attr{"fips", ustring("005")}});
attr{"x", 0}, attr{"y", 0}, attr{"fips", ustring("003")}});
REQUIRE_ATTRIBUTES(featureset->next(), {
attr{"x", 0}, attr{"y", 0}, attr{"fips", ustring("005")}});
if (mapnik::util::exists(filename + ".index")) if (mapnik::util::exists(filename + ".index"))
{ {
mapnik::util::remove(filename + ".index"); mapnik::util::remove(filename + ".index");
@ -847,12 +842,11 @@ TEST_CASE("csv") {
SECTION("advanced geometry detection") SECTION("advanced geometry detection")
{ {
using row = std::pair<std::string, mapnik::datasource_geometry_t>; using row = std::pair<std::string, mapnik::datasource_geometry_t>;
for (row r : { for (row r : {row{"point", mapnik::datasource_geometry_t::Point},
row{"point", mapnik::datasource_geometry_t::Point} row{"poly", mapnik::datasource_geometry_t::Polygon},
, row{"poly", mapnik::datasource_geometry_t::Polygon} row{"multi_poly", mapnik::datasource_geometry_t::Polygon},
, row{"multi_poly", mapnik::datasource_geometry_t::Polygon} row{"line", mapnik::datasource_geometry_t::LineString}})
, row{"line", mapnik::datasource_geometry_t::LineString} {
}) {
std::string file_name = (boost::format("test/data/csv/%1%_wkt.csv") % r.first).str(); std::string file_name = (boost::format("test/data/csv/%1%_wkt.csv") % r.first).str();
auto ds = get_csv_ds(file_name); auto ds = get_csv_ds(file_name);
CHECK(ds->get_geometry_type() == r.second); CHECK(ds->get_geometry_type() == r.second);
@ -863,12 +857,12 @@ TEST_CASE("csv") {
{ {
using ustring = mapnik::value_unicode_string; using ustring = mapnik::value_unicode_string;
for (auto const &name : {std::string("Winthrop, WA"), from_u8string(u8"Qu\u00e9bec")}) { for (auto const& name : {std::string("Winthrop, WA"), from_u8string(u8"Qu\u00e9bec")})
std::string csv_string = {
(boost::format( std::string csv_string = (boost::format("wkt,Name\n"
"wkt,Name\n" "\"POINT (120.15 48.47)\",\"%1%\"\n") %
"\"POINT (120.15 48.47)\",\"%1%\"\n" name)
) % name).str(); .str();
mapnik::parameters params; mapnik::parameters params;
params["type"] = std::string("csv"); params["type"] = std::string("csv");
@ -927,14 +921,14 @@ TEST_CASE("csv") {
} // END SECTION } // END SECTION
SECTION("geojson quoting") { SECTION("geojson quoting")
{
using mapnik::geometry::geometry_types; using mapnik::geometry::geometry_types;
for (auto const &file : { for (auto const& file : {std::string("test/data/csv/geojson_double_quote_escape.csv"),
std::string("test/data/csv/geojson_double_quote_escape.csv") std::string("test/data/csv/geojson_single_quote.csv"),
, std::string("test/data/csv/geojson_single_quote.csv") std::string("test/data/csv/geojson_2x_double_quote_filebakery_style.csv")})
, std::string("test/data/csv/geojson_2x_double_quote_filebakery_style.csv") {
}) {
auto ds = get_csv_ds(file); auto ds = get_csv_ds(file);
auto fields = ds->get_descriptor().get_descriptors(); auto fields = ds->get_descriptor().get_descriptors();
require_field_names(fields, {"type"}); require_field_names(fields, {"type"});
@ -952,11 +946,13 @@ TEST_CASE("csv") {
} }
} // END SECTION } // END SECTION
SECTION("fewer headers than rows throws") { SECTION("fewer headers than rows throws")
{
REQUIRE_THROWS(get_csv_ds("test/data/csv/more_column_values_than_headers.csv")); REQUIRE_THROWS(get_csv_ds("test/data/csv/more_column_values_than_headers.csv"));
} // END SECTION } // END SECTION
SECTION("feature ID only incremented for valid rows") { SECTION("feature ID only incremented for valid rows")
{
auto ds = get_csv_ds("test/data/csv/warns/feature_id_counting.csv", false); auto ds = get_csv_ds("test/data/csv/warns/feature_id_counting.csv", false);
auto fs = all_features(ds); auto fs = all_features(ds);
@ -974,12 +970,12 @@ TEST_CASE("csv") {
CHECK(!feature); CHECK(!feature);
} // END SECTION } // END SECTION
SECTION("dynamically defining headers") { SECTION("dynamically defining headers")
{
using ustring = mapnik::value_unicode_string; using ustring = mapnik::value_unicode_string;
using row = std::pair<std::string, std::size_t>; using row = std::pair<std::string, std::size_t>;
for (auto const& r : { for (auto const& r : {row{"test/data/csv/fails/needs_headers_two_lines.csv", 2},
row{"test/data/csv/fails/needs_headers_two_lines.csv", 2},
row{"test/data/csv/fails/needs_headers_one_line.csv", 1}, row{"test/data/csv/fails/needs_headers_one_line.csv", 1},
row{"test/data/csv/fails/needs_headers_one_line_no_newline.csv", 1}}) row{"test/data/csv/fails/needs_headers_one_line_no_newline.csv", 1}})
{ {
@ -992,17 +988,17 @@ TEST_CASE("csv") {
auto fields = ds->get_descriptor().get_descriptors(); auto fields = ds->get_descriptor().get_descriptors();
require_field_names(fields, {"x", "y", "name"}); require_field_names(fields, {"x", "y", "name"});
require_field_types(fields, {mapnik::Integer, mapnik::Integer, mapnik::String}); require_field_types(fields, {mapnik::Integer, mapnik::Integer, mapnik::String});
REQUIRE_ATTRIBUTES(all_features(ds)->next(), { REQUIRE_ATTRIBUTES(all_features(ds)->next(),
attr{"x", 0}, attr{"y", 0}, attr{"name", ustring("data_name")} }); {attr{"x", 0}, attr{"y", 0}, attr{"name", ustring("data_name")}});
REQUIRE(count_features(all_features(ds)) == r.second); REQUIRE(count_features(all_features(ds)) == r.second);
CHECK(ds->get_geometry_type() == mapnik::datasource_geometry_t::Point); CHECK(ds->get_geometry_type() == mapnik::datasource_geometry_t::Point);
} }
} // END SECTION } // END SECTION
MAPNIK_DISABLE_WARNING_PUSH MAPNIK_DISABLE_WARNING_PUSH
MAPNIK_DISABLE_LONG_LONG MAPNIK_DISABLE_LONG_LONG
SECTION("64bit int fields work") { SECTION("64bit int fields work")
{
auto ds = get_csv_ds("test/data/csv/64bit_int.csv"); auto ds = get_csv_ds("test/data/csv/64bit_int.csv");
auto fields = ds->get_descriptor().get_descriptors(); auto fields = ds->get_descriptor().get_descriptors();
require_field_names(fields, {"x", "y", "bigint"}); require_field_names(fields, {"x", "y", "bigint"});
@ -1010,31 +1006,31 @@ MAPNIK_DISABLE_LONG_LONG
auto fs = all_features(ds); auto fs = all_features(ds);
auto feature = fs->next(); auto feature = fs->next();
REQUIRE_ATTRIBUTES(feature, { REQUIRE_ATTRIBUTES(feature, {attr{"x", 0}, attr{"y", 0}, attr{"bigint", 2147483648}});
attr{"x", 0}, attr{"y", 0}, attr{"bigint", 2147483648} });
feature = fs->next(); feature = fs->next();
REQUIRE_ATTRIBUTES(feature, { REQUIRE_ATTRIBUTES(feature, {attr{"x", 0}, attr{"y", 0}, attr{"bigint", 9223372036854775807ll}});
attr{"x", 0}, attr{"y", 0}, attr{"bigint", 9223372036854775807ll} }); REQUIRE_ATTRIBUTES(feature, {attr{"x", 0}, attr{"y", 0}, attr{"bigint", 0x7FFFFFFFFFFFFFFFll}});
REQUIRE_ATTRIBUTES(feature, {
attr{"x", 0}, attr{"y", 0}, attr{"bigint", 0x7FFFFFFFFFFFFFFFll} });
} // END SECTION } // END SECTION
MAPNIK_DISABLE_WARNING_POP MAPNIK_DISABLE_WARNING_POP
SECTION("various number types") { SECTION("various number types")
{
auto ds = get_csv_ds("test/data/csv/number_types.csv"); auto ds = get_csv_ds("test/data/csv/number_types.csv");
auto fields = ds->get_descriptor().get_descriptors(); auto fields = ds->get_descriptor().get_descriptors();
require_field_names(fields, {"x", "y", "floats"}); require_field_names(fields, {"x", "y", "floats"});
require_field_types(fields, {mapnik::Integer, mapnik::Integer, mapnik::Double}); require_field_types(fields, {mapnik::Integer, mapnik::Integer, mapnik::Double});
auto fs = all_features(ds); auto fs = all_features(ds);
for (double d : { .0, +.0, 1e-06, -1e-06, 0.000001, 1.234e+16, 1.234e+16 }) { for (double d : {.0, +.0, 1e-06, -1e-06, 0.000001, 1.234e+16, 1.234e+16})
{
auto feature = fs->next(); auto feature = fs->next();
REQUIRE(bool(feature)); REQUIRE(bool(feature));
CHECK(feature->get("floats").get<mapnik::value_double>() == Approx(d)); CHECK(feature->get("floats").get<mapnik::value_double>() == Approx(d));
} }
} // END SECTION } // END SECTION
SECTION("manually supplied extent") { SECTION("manually supplied extent")
{
std::string csv_string("wkt,Name\n"); std::string csv_string("wkt,Name\n");
mapnik::parameters params; mapnik::parameters params;
params["type"] = std::string("csv"); params["type"] = std::string("csv");
@ -1049,7 +1045,8 @@ MAPNIK_DISABLE_WARNING_POP
CHECK(box.maxy() == 90); CHECK(box.maxy() == 90);
} // END SECTION } // END SECTION
SECTION("inline geojson") { SECTION("inline geojson")
{
std::string csv_string = "geojson\n'{\"coordinates\":[-92.22568,38.59553],\"type\":\"Point\"}'"; std::string csv_string = "geojson\n'{\"coordinates\":[-92.22568,38.59553],\"type\":\"Point\"}'";
mapnik::parameters params; mapnik::parameters params;
params["type"] = std::string("csv"); params["type"] = std::string("csv");

View file

@ -20,7 +20,6 @@
* *
*****************************************************************************/ *****************************************************************************/
#ifndef MAPNIK_UNIT_DATSOURCE_UTIL #ifndef MAPNIK_UNIT_DATSOURCE_UTIL
#define MAPNIK_UNIT_DATSOURCE_UTIL #define MAPNIK_UNIT_DATSOURCE_UTIL
@ -65,7 +64,7 @@ std::string vector_to_string(std::vector<mapnik::attribute_descriptor> const& ve
for (; itr_a != end_a; ++itr_a, ++itr_b) \ for (; itr_a != end_a; ++itr_a, ++itr_b) \
{ \ { \
CHECK(itr_a->get_name() == *itr_b); \ CHECK(itr_a->get_name() == *itr_b); \
} \ }
inline void require_field_names(std::vector<mapnik::attribute_descriptor> const& fields, inline void require_field_names(std::vector<mapnik::attribute_descriptor> const& fields,
std::initializer_list<std::string> const& names) std::initializer_list<std::string> const& names)
@ -78,9 +77,10 @@ inline void require_field_names(std::vector<mapnik::attribute_descriptor> const
auto itr_a = fields.begin(); \ auto itr_a = fields.begin(); \
auto const end_a = fields.end(); \ auto const end_a = fields.end(); \
auto itr_b = types.begin(); \ auto itr_b = types.begin(); \
for (; itr_a != end_a; ++itr_a, ++itr_b) { \ for (; itr_a != end_a; ++itr_a, ++itr_b) \
{ \
CHECK(itr_a->get_type() == *itr_b); \ CHECK(itr_a->get_type() == *itr_b); \
} \ }
inline void require_field_types(std::vector<mapnik::attribute_descriptor> const& fields, inline void require_field_types(std::vector<mapnik::attribute_descriptor> const& fields,
std::initializer_list<mapnik::eAttributeType> const& types) std::initializer_list<mapnik::eAttributeType> const& types)
@ -88,18 +88,22 @@ inline void require_field_types(std::vector<mapnik::attribute_descriptor> const
REQUIRE_FIELD_TYPES(fields, types); REQUIRE_FIELD_TYPES(fields, types);
} }
inline mapnik::featureset_ptr all_features(mapnik::datasource_ptr ds) { inline mapnik::featureset_ptr all_features(mapnik::datasource_ptr ds)
{
auto fields = ds->get_descriptor().get_descriptors(); auto fields = ds->get_descriptor().get_descriptors();
mapnik::query query(ds->envelope()); mapnik::query query(ds->envelope());
for (auto const &field : fields) { for (auto const& field : fields)
{
query.add_property_name(field.get_name()); query.add_property_name(field.get_name());
} }
return ds->features(query); return ds->features(query);
} }
inline std::size_t count_features(mapnik::featureset_ptr features) { inline std::size_t count_features(mapnik::featureset_ptr features)
{
std::size_t count = 0; std::size_t count = 0;
while (features->next()) { while (features->next())
{
++count; ++count;
} }
return count; return count;
@ -108,14 +112,17 @@ inline std::size_t count_features(mapnik::featureset_ptr features) {
using attr = std::tuple<std::string, mapnik::value>; using attr = std::tuple<std::string, mapnik::value>;
#define REQUIRE_ATTRIBUTES(feature, ...) \ #define REQUIRE_ATTRIBUTES(feature, ...) \
do { \ do \
{ \
auto const& _feat = (feature); /* evaluate feature only once */ \ auto const& _feat = (feature); /* evaluate feature only once */ \
REQUIRE(_feat != nullptr); \ REQUIRE(_feat != nullptr); \
for (auto const& kv : __VA_ARGS__) { \ for (auto const& kv : __VA_ARGS__) \
{ \
auto& key = std::get<0>(kv); \ auto& key = std::get<0>(kv); \
auto& val = std::get<1>(kv); \ auto& val = std::get<1>(kv); \
CAPTURE(key); \ CAPTURE(key); \
CHECKED_IF(_feat->has_key(key)) { \ CHECKED_IF(_feat->has_key(key)) \
{ \
CHECK(_feat->get(key) == val); \ CHECK(_feat->get(key) == val); \
CHECK(_feat->get(key).which() == val.which()); \ CHECK(_feat->get(key).which() == val.which()); \
} \ } \
@ -133,45 +140,25 @@ struct feature_count
return mapnik::util::apply_visitor(*this, geom); return mapnik::util::apply_visitor(*this, geom);
} }
std::size_t operator()(mapnik::geometry::geometry_empty const &) const std::size_t operator()(mapnik::geometry::geometry_empty const&) const { return 0; }
{
return 0;
}
std::size_t operator()(mapnik::geometry::point<T> const &) const std::size_t operator()(mapnik::geometry::point<T> const&) const { return 1; }
{
return 1;
}
std::size_t operator()(mapnik::geometry::line_string<T> const &) const std::size_t operator()(mapnik::geometry::line_string<T> const&) const { return 1; }
{
return 1;
}
std::size_t operator()(mapnik::geometry::polygon<T> const &) const std::size_t operator()(mapnik::geometry::polygon<T> const&) const { return 1; }
{
return 1;
}
std::size_t operator()(mapnik::geometry::multi_point<T> const &mp) const std::size_t operator()(mapnik::geometry::multi_point<T> const& mp) const { return mp.size(); }
{
return mp.size();
}
std::size_t operator()(mapnik::geometry::multi_line_string<T> const &mls) const std::size_t operator()(mapnik::geometry::multi_line_string<T> const& mls) const { return mls.size(); }
{
return mls.size();
}
std::size_t operator()(mapnik::geometry::multi_polygon<T> const &mp) const std::size_t operator()(mapnik::geometry::multi_polygon<T> const& mp) const { return mp.size(); }
{
return mp.size();
}
std::size_t operator()(mapnik::geometry::geometry_collection<T> const& col) const std::size_t operator()(mapnik::geometry::geometry_collection<T> const& col) const
{ {
std::size_t sum = 0; std::size_t sum = 0;
for (auto const &geom : col) { for (auto const& geom : col)
{
sum += operator()(geom); sum += operator()(geom);
} }
return sum; return sum;
@ -180,13 +167,13 @@ struct feature_count
} // namespace detail } // namespace detail
template<typename T> template<typename T>
inline std::size_t feature_count(mapnik::geometry::geometry<T> const &g) { inline std::size_t feature_count(mapnik::geometry::geometry<T> const& g)
{
return detail::feature_count<T>()(g); return detail::feature_count<T>()(g);
} }
inline void require_geometry(mapnik::feature_ptr feature, inline void require_geometry(mapnik::feature_ptr feature, std::size_t num_parts, mapnik::geometry::geometry_types type)
std::size_t num_parts, {
mapnik::geometry::geometry_types type) {
REQUIRE(bool(feature)); REQUIRE(bool(feature));
CHECK(mapnik::geometry::geometry_type(feature->get_geometry()) == type); CHECK(mapnik::geometry::geometry_type(feature->get_geometry()) == type);
CHECK(feature_count(feature->get_geometry()) == num_parts); CHECK(feature_count(feature->get_geometry()) == num_parts);
@ -215,6 +202,6 @@ inline int create_disk_index(std::string const& filename, bool silent = true)
return std::system(cmd.c_str()); return std::system(cmd.c_str());
} }
} } // namespace
#endif // MAPNIK_UNIT_DATSOURCE_UTIL #endif // MAPNIK_UNIT_DATSOURCE_UTIL

View file

@ -29,8 +29,7 @@
namespace { namespace {
mapnik::datasource_ptr get_gdal_ds(std::string const& file_name, mapnik::datasource_ptr get_gdal_ds(std::string const& file_name, boost::optional<mapnik::value_integer> band)
boost::optional<mapnik::value_integer> band)
{ {
std::string gdal_plugin("./plugins/input/gdal.input"); std::string gdal_plugin("./plugins/input/gdal.input");
if (!mapnik::util::exists(gdal_plugin)) if (!mapnik::util::exists(gdal_plugin))
@ -54,8 +53,8 @@ mapnik::datasource_ptr get_gdal_ds(std::string const& file_name,
} // anonymous namespace } // anonymous namespace
TEST_CASE("gdal") { TEST_CASE("gdal")
{
SECTION("upsampling") SECTION("upsampling")
{ {
std::string dataset = "test/data/tiff/ndvi_256x256_gray32f_tiled.tif"; std::string dataset = "test/data/tiff/ndvi_256x256_gray32f_tiled.tif";

View file

@ -35,9 +35,8 @@
#include <locale> #include <locale>
#include <boost/optional/optional_io.hpp> #include <boost/optional/optional_io.hpp>
TEST_CASE("Geobuf")
TEST_CASE("Geobuf") { {
std::string geobuf_plugin("./plugins/input/geobuf.input"); std::string geobuf_plugin("./plugins/input/geobuf.input");
if (mapnik::util::exists(geobuf_plugin)) if (mapnik::util::exists(geobuf_plugin))
{ {
@ -127,12 +126,9 @@ TEST_CASE("Geobuf") {
SECTION("Polygon") SECTION("Polygon")
{ {
//{"type":"Feature","id":1,"geometry":{"type":"Polygon","coordinates":[[[100,0],[101,0],[101,1],[100,1],[100,0]],[[100.8,0.8],[100.8,0.2],[100.2,0.2],[100.2,0.8],[100.8,0.8]]]},"properties":{"prop0":"value0","prop1":"{\"this\":\"that\"}"}} //{"type":"Feature","id":1,"geometry":{"type":"Polygon","coordinates":[[[100,0],[101,0],[101,1],[100,1],[100,0]],[[100.8,0.8],[100.8,0.2],[100.2,0.2],[100.2,0.8],[100.8,0.8]]]},"properties":{"prop0":"value0","prop1":"{\"this\":\"that\"}"}}
auto files = auto files = {"./test/data/geobuf/polygon.geobuf",
{
"./test/data/geobuf/polygon.geobuf",
"./test/data/geobuf/standalone-feature.geobuf", "./test/data/geobuf/standalone-feature.geobuf",
"./test/data/geobuf/standalone-geometry.geobuf" "./test/data/geobuf/standalone-geometry.geobuf"};
};
mapnik::parameters params; mapnik::parameters params;
params["type"] = "geobuf"; params["type"] = "geobuf";

View file

@ -48,7 +48,8 @@ clang++ -o test-geojson -g -I./test/ test/unit/run.cpp test/unit/datasource/geoj
namespace { namespace {
std::pair<mapnik::datasource_ptr,mapnik::feature_ptr> fetch_first_feature(std::string const& filename, bool cache_features) std::pair<mapnik::datasource_ptr, mapnik::feature_ptr> fetch_first_feature(std::string const& filename,
bool cache_features)
{ {
mapnik::parameters params; mapnik::parameters params;
params["type"] = "geojson"; params["type"] = "geojson";
@ -67,7 +68,6 @@ std::pair<mapnik::datasource_ptr,mapnik::feature_ptr> fetch_first_feature(std::s
return std::make_pair(ds, feature); return std::make_pair(ds, feature);
} }
void iterate_over_features(mapnik::featureset_ptr features) void iterate_over_features(mapnik::featureset_ptr features)
{ {
auto feature = features->next(); auto feature = features->next();
@ -77,10 +77,10 @@ void iterate_over_features(mapnik::featureset_ptr features)
} }
} }
} } // namespace
TEST_CASE("geojson") {
TEST_CASE("geojson")
{
std::string geojson_plugin("./plugins/input/geojson.input"); std::string geojson_plugin("./plugins/input/geojson.input");
if (mapnik::util::exists(geojson_plugin)) if (mapnik::util::exists(geojson_plugin))
{ {
@ -124,15 +124,12 @@ TEST_CASE("geojson") {
SECTION("GeoJSON empty Geometries handling") SECTION("GeoJSON empty Geometries handling")
{ {
auto valid_empty_geometries = auto valid_empty_geometries = {"null", // Point can't be empty
{
"null", // Point can't be empty
"{ \"type\": \"LineString\", \"coordinates\": [] }", "{ \"type\": \"LineString\", \"coordinates\": [] }",
"{ \"type\": \"Polygon\", \"coordinates\": [ [ ] ] } ", "{ \"type\": \"Polygon\", \"coordinates\": [ [ ] ] } ",
"{ \"type\": \"MultiPoint\", \"coordinates\": [ ] }", "{ \"type\": \"MultiPoint\", \"coordinates\": [ ] }",
"{ \"type\": \"MultiLineString\", \"coordinates\": [ [] ] }", "{ \"type\": \"MultiLineString\", \"coordinates\": [ [] ] }",
"{ \"type\": \"MultiPolygon\", \"coordinates\": [[ []] ] }" "{ \"type\": \"MultiPolygon\", \"coordinates\": [[ []] ] }"};
};
for (auto const& in : valid_empty_geometries) for (auto const& in : valid_empty_geometries)
{ {
@ -142,22 +139,19 @@ TEST_CASE("geojson") {
// round trip // round trip
std::string json_out; std::string json_out;
CHECK(mapnik::util::to_geojson(json_out, geom)); CHECK(mapnik::util::to_geojson(json_out, geom));
json.erase(std::remove_if( json.erase(std::remove_if(std::begin(json),
std::begin(json), std::end(json), std::end(json),
[l = std::locale{}](auto ch) { return std::isspace(ch, l); } [l = std::locale{}](auto ch) { return std::isspace(ch, l); }),
), std::end(json)); std::end(json));
REQUIRE(json == json_out); REQUIRE(json == json_out);
} }
auto invalid_empty_geometries = auto invalid_empty_geometries = {"{ \"type\": \"Point\", \"coordinates\": [] }",
{
"{ \"type\": \"Point\", \"coordinates\": [] }",
"{ \"type\": \"LineString\", \"coordinates\": [[]] }" "{ \"type\": \"LineString\", \"coordinates\": [[]] }"
"{ \"type\": \"Polygon\", \"coordinates\": [[[]]] }", "{ \"type\": \"Polygon\", \"coordinates\": [[[]]] }",
"{ \"type\": \"MultiPoint\", \"coordinates\": [[]] }", "{ \"type\": \"MultiPoint\", \"coordinates\": [[]] }",
"{ \"type\": \"MultiLineString\", \"coordinates\": [[[]]] }", "{ \"type\": \"MultiLineString\", \"coordinates\": [[[]]] }",
"{ \"type\": \"MultiPolygon\", \"coordinates\": [[[[]]]] }" "{ \"type\": \"MultiPolygon\", \"coordinates\": [[[[]]]] }"};
};
for (auto const& json : invalid_empty_geometries) for (auto const& json : invalid_empty_geometries)
{ {
@ -279,7 +273,6 @@ TEST_CASE("geojson") {
auto const& line = mapnik::util::get<mapnik::geometry::line_string<double>>(geometry); auto const& line = mapnik::util::get<mapnik::geometry::line_string<double>>(geometry);
REQUIRE(line.size() == 2); REQUIRE(line.size() == 2);
REQUIRE(mapnik::geometry::envelope(line) == mapnik::box2d<double>(100, 0, 101, 1)); REQUIRE(mapnik::geometry::envelope(line) == mapnik::box2d<double>(100, 0, 101, 1));
} }
} }
@ -298,7 +291,6 @@ TEST_CASE("geojson") {
REQUIRE(poly[0].size() == 5); REQUIRE(poly[0].size() == 5);
REQUIRE(poly[1].size() == 5); REQUIRE(poly[1].size() == 5);
REQUIRE(mapnik::geometry::envelope(poly) == mapnik::box2d<double>(100, 0, 101, 1)); REQUIRE(mapnik::geometry::envelope(poly) == mapnik::box2d<double>(100, 0, 101, 1));
} }
} }
@ -333,7 +325,6 @@ TEST_CASE("geojson") {
REQUIRE(multi_line[0].size() == 2); REQUIRE(multi_line[0].size() == 2);
REQUIRE(multi_line[1].size() == 2); REQUIRE(multi_line[1].size() == 2);
REQUIRE(mapnik::geometry::envelope(multi_line) == mapnik::box2d<double>(100, 0, 103, 3)); REQUIRE(mapnik::geometry::envelope(multi_line) == mapnik::box2d<double>(100, 0, 103, 3));
} }
} }
@ -353,7 +344,6 @@ TEST_CASE("geojson") {
REQUIRE(multi_poly[0].size() == 1); REQUIRE(multi_poly[0].size() == 1);
REQUIRE(multi_poly[1].size() == 2); REQUIRE(multi_poly[1].size() == 2);
REQUIRE(mapnik::geometry::envelope(multi_poly) == mapnik::box2d<double>(100, 0, 103, 3)); REQUIRE(mapnik::geometry::envelope(multi_poly) == mapnik::box2d<double>(100, 0, 103, 3));
} }
} }
@ -447,8 +437,8 @@ TEST_CASE("geojson") {
mapnik::parameters params; mapnik::parameters params;
params["type"] = "geojson"; params["type"] = "geojson";
for (auto const& c_str : {"./test/data/json/feature-null-properties.json", for (auto const& c_str :
"./test/data/json/feature-empty-properties.json"}) {"./test/data/json/feature-null-properties.json", "./test/data/json/feature-empty-properties.json"})
{ {
std::string filename(c_str); std::string filename(c_str);
params["file"] = filename; params["file"] = filename;
@ -536,9 +526,12 @@ TEST_CASE("geojson") {
{ {
auto feature = features->next(); auto feature = features->next();
auto feature2 = features2->next(); auto feature2 = features2->next();
if (!feature || !feature2) break; if (!feature || !feature2)
if (!bbox.valid()) bbox = feature->envelope(); break;
else bbox.expand_to_include(feature->envelope()); if (!bbox.valid())
bbox = feature->envelope();
else
bbox.expand_to_include(feature->envelope());
++count; ++count;
REQUIRE(feature->id() == count); REQUIRE(feature->id() == count);
REQUIRE(feature2->id() == count); REQUIRE(feature2->id() == count);
@ -924,7 +917,17 @@ TEST_CASE("geojson") {
auto ds = mapnik::datasource_cache::instance().create(params); auto ds = mapnik::datasource_cache::instance().create(params);
REQUIRE(bool(ds)); REQUIRE(bool(ds));
auto fields = ds->get_descriptor().get_descriptors(); auto fields = ds->get_descriptor().get_descriptors();
std::initializer_list<std::string> names = {"NOM_FR","array","boolean","description","double","empty_array", "empty_object","int","name","object","spaces"}; std::initializer_list<std::string> names = {"NOM_FR",
"array",
"boolean",
"description",
"double",
"empty_array",
"empty_object",
"int",
"name",
"object",
"spaces"};
REQUIRE_FIELD_NAMES(fields, names); REQUIRE_FIELD_NAMES(fields, names);
auto fs = all_features(ds); auto fs = all_features(ds);
@ -935,11 +938,15 @@ TEST_CASE("geojson") {
attr{"description", tr.transcode("Test: \u005C")}, attr{"description", tr.transcode("Test: \u005C")},
attr{"double", mapnik::value_double(1.1)}, attr{"double", mapnik::value_double(1.1)},
attr{"int", mapnik::value_integer(1)}, attr{"int", mapnik::value_integer(1)},
attr{"object", tr.transcode("{\"name\":\"waka\",\"spaces\":\"value with spaces\",\"int\":1,\"double\":1.1,\"boolean\":false" attr{"object",
tr.transcode(
"{\"name\":\"waka\",\"spaces\":\"value with "
"spaces\",\"int\":1,\"double\":1.1,\"boolean\":false"
",\"NOM_FR\":\"Québec\",\"array\":[\"string\",\"value with spaces\",3,1.1,null,true" ",\"NOM_FR\":\"Québec\",\"array\":[\"string\",\"value with spaces\",3,1.1,null,true"
",\"Québec\"],\"another_object\":{\"name\":\"nested object\"}}")}, ",\"Québec\"],\"another_object\":{\"name\":\"nested object\"}}")},
attr{"spaces", tr.transcode("this has spaces")}, attr{"spaces", tr.transcode("this has spaces")},
attr{"array", tr.transcode("[\"string\",\"value with spaces\",3,1.1,null,true," attr{"array",
tr.transcode("[\"string\",\"value with spaces\",3,1.1,null,true,"
"\"Québec\",{\"name\":\"object within an array\"}," "\"Québec\",{\"name\":\"object within an array\"},"
"[\"array\",\"within\",\"an\",\"array\"]]")}, "[\"array\",\"within\",\"an\",\"array\"]]")},
attr{"empty_array", tr.transcode("[]")}, attr{"empty_array", tr.transcode("[]")},

View file

@ -28,9 +28,8 @@
#include <mapnik/memory_datasource.hpp> #include <mapnik/memory_datasource.hpp>
#include <mapnik/datasource_cache.hpp> #include <mapnik/datasource_cache.hpp>
TEST_CASE("memory datasource")
TEST_CASE("memory datasource") { {
SECTION("empty featureset") SECTION("empty featureset")
{ {
mapnik::parameters params; mapnik::parameters params;

View file

@ -30,8 +30,8 @@
#include <mapnik/image_util.hpp> #include <mapnik/image_util.hpp>
#include <mapnik/util/fs.hpp> #include <mapnik/util/fs.hpp>
TEST_CASE("ogr") { TEST_CASE("ogr")
{
std::string geojson_plugin("./plugins/input/ogr.input"); std::string geojson_plugin("./plugins/input/ogr.input");
if (mapnik::util::exists(geojson_plugin)) if (mapnik::util::exists(geojson_plugin))
{ {
@ -46,7 +46,8 @@ TEST_CASE("ogr") {
mapnik::agg_renderer<mapnik::image_rgba8> ren(m, im); mapnik::agg_renderer<mapnik::image_rgba8> ren(m, im);
ren.apply(); ren.apply();
std::string filename("./test/data/images/point_json.png"); std::string filename("./test/data/images/point_json.png");
if (std::getenv("UPDATE") != nullptr) { if (std::getenv("UPDATE") != nullptr)
{
mapnik::save_to_file(im, filename); mapnik::save_to_file(im, filename);
} }
std::unique_ptr<mapnik::image_reader> reader(mapnik::get_image_reader(filename, "png")); std::unique_ptr<mapnik::image_reader> reader(mapnik::get_image_reader(filename, "png"));
@ -54,6 +55,5 @@ TEST_CASE("ogr") {
mapnik::image_rgba8 expected = mapnik::util::get<mapnik::image_rgba8>(data); mapnik::image_rgba8 expected = mapnik::util::get<mapnik::image_rgba8>(data);
REQUIRE(mapnik::compare(expected, im) == 0); REQUIRE(mapnik::compare(expected, im) == 0);
} }
} }
} }

View file

@ -32,7 +32,8 @@
/* /*
Compile and run just this test: Compile and run just this test:
clang++ -o test-postgis -g -I./test/ test/unit/run.cpp test/unit/datasource/postgis.cpp `mapnik-config --all-flags` && ./test-postgis -d yes clang++ -o test-postgis -g -I./test/ test/unit/run.cpp test/unit/datasource/postgis.cpp `mapnik-config --all-flags` &&
./test-postgis -d yes
*/ */
#include <boost/optional/optional_io.hpp> #include <boost/optional/optional_io.hpp>
@ -61,25 +62,24 @@ bool run(std::string const& command, bool okay_to_fail = false)
std::clog << "Running " << cmd << "\n"; std::clog << "Running " << cmd << "\n";
} }
bool worked = (std::system(cmd.c_str()) == 0); bool worked = (std::system(cmd.c_str()) == 0);
if (okay_to_fail == true) return true; if (okay_to_fail == true)
return true;
return worked; return worked;
} }
std::string const dbname("mapnik-tmp-postgis-test-db"); std::string const dbname("mapnik-tmp-postgis-test-db");
bool status = false; bool status = false;
bool ping_postmaster() bool ping_postmaster()
{ {
return (run("psql --version") return (run("psql --version") && run("dropdb --if-exists " + dbname) &&
&& run("dropdb --if-exists " + dbname) run("createdb -T template_postgis " + dbname));
&& run("createdb -T template_postgis " + dbname));
} }
} } // namespace
TEST_CASE("postgis") {
TEST_CASE("postgis")
{
SECTION("Ping Postmaster (check if server is runnging and accessible") SECTION("Ping Postmaster (check if server is runnging and accessible")
{ {
if (!ping_postmaster()) if (!ping_postmaster())
@ -165,7 +165,8 @@ TEST_CASE("postgis") {
CHECK_THROWS(mapnik::datasource_cache::instance().create(params)); CHECK_THROWS(mapnik::datasource_cache::instance().create(params));
} }
SECTION("Postgis initialize dataset with persist_connection, schema, extent, geometry field, autodectect key field, simplify_geometries, row_limit") SECTION("Postgis initialize dataset with persist_connection, schema, extent, geometry field, autodectect key "
"field, simplify_geometries, row_limit")
{ {
mapnik::parameters params(base_params); mapnik::parameters params(base_params);
params["persist_connection"] = "false"; params["persist_connection"] = "false";
@ -213,8 +214,28 @@ TEST_CASE("postgis") {
REQUIRE(ds != nullptr); REQUIRE(ds != nullptr);
REQUIRE(ds->type() == mapnik::datasource::datasource_t::Vector); REQUIRE(ds->type() == mapnik::datasource::datasource_t::Vector);
auto fields = ds->get_descriptor().get_descriptors(); auto fields = ds->get_descriptor().get_descriptors();
require_field_names(fields, { "gid", "colbigint", "col_text", "col-char", "col+bool", "colnumeric", "colsmallint", "colfloat4", "colfloat8", "colcharacter" }); require_field_names(fields,
require_field_types(fields, { mapnik::Integer, mapnik::Integer, mapnik::String, mapnik::String, mapnik::Boolean, mapnik::Double, mapnik::Integer, mapnik::Double, mapnik::Double, mapnik::String }); {"gid",
"colbigint",
"col_text",
"col-char",
"col+bool",
"colnumeric",
"colsmallint",
"colfloat4",
"colfloat8",
"colcharacter"});
require_field_types(fields,
{mapnik::Integer,
mapnik::Integer,
mapnik::String,
mapnik::String,
mapnik::Boolean,
mapnik::Double,
mapnik::Integer,
mapnik::Double,
mapnik::Double,
mapnik::String});
} }
SECTION("Postgis iterate features") SECTION("Postgis iterate features")
@ -229,7 +250,8 @@ TEST_CASE("postgis") {
auto featureset = ds->features_at_point(mapnik::coord2d(1, 1)); auto featureset = ds->features_at_point(mapnik::coord2d(1, 1));
mapnik::feature_ptr feature; mapnik::feature_ptr feature;
while ((bool(feature = featureset->next()))) { while ((bool(feature = featureset->next())))
{
REQUIRE(feature->get(2).to_string() == feature->get("col_text").to_string()); REQUIRE(feature->get(2).to_string() == feature->get("col_text").to_string());
REQUIRE(feature->get(4).to_bool() == feature->get("col+bool").to_bool()); REQUIRE(feature->get(4).to_bool() == feature->get("col+bool").to_bool());
REQUIRE(feature->get(5).to_double() == feature->get("colnumeric").to_double()); REQUIRE(feature->get(5).to_double() == feature->get("colnumeric").to_double());
@ -260,7 +282,8 @@ TEST_CASE("postgis") {
featureset = all_features(ds); featureset = all_features(ds);
mapnik::feature_ptr feature; mapnik::feature_ptr feature;
while (bool(feature = featureset->next())) { while (bool(feature = featureset->next()))
{
CHECK(feature->size() == 10); CHECK(feature->size() == 10);
} }
@ -283,7 +306,8 @@ TEST_CASE("postgis") {
REQUIRE(ds != nullptr); REQUIRE(ds != nullptr);
mapnik::box2d<double> ext = ds->envelope(); mapnik::box2d<double> ext = ds->envelope();
CAPTURE(ext); CAPTURE(ext);
INFO(std::setprecision(6) << std::fixed << ext.minx() << "/" << ext.miny() << " " << ext.maxx() << "/" << ext.maxy()); INFO(std::setprecision(6) << std::fixed << ext.minx() << "/" << ext.miny() << " " << ext.maxx() << "/"
<< ext.maxy());
REQUIRE(ext.minx() == -2); REQUIRE(ext.minx() == -2);
REQUIRE(ext.miny() == -2); REQUIRE(ext.miny() == -2);
REQUIRE(ext.maxx() == 5); REQUIRE(ext.maxx() == 5);
@ -319,10 +343,7 @@ TEST_CASE("postgis") {
REQUIRE(ds != nullptr); REQUIRE(ds != nullptr);
auto featureset = all_features(ds); auto featureset = all_features(ds);
auto feature = featureset->next(); auto feature = featureset->next();
CHECKED_IF(feature != nullptr) CHECKED_IF(feature != nullptr) { CHECK(feature->get("email").to_string() == "fake@mail.ru"); }
{
CHECK(feature->get("email").to_string() == "fake@mail.ru");
}
} }
SECTION("Postgis interpolates !@uservar! tokens in query") SECTION("Postgis interpolates !@uservar! tokens in query")
@ -368,7 +389,8 @@ TEST_CASE("postgis") {
REQUIRE(ds != nullptr); REQUIRE(ds != nullptr);
mapnik::box2d<double> ext = ds->envelope(); mapnik::box2d<double> ext = ds->envelope();
CAPTURE(ext); CAPTURE(ext);
INFO(std::setprecision(6) << std::fixed << ext.minx() << "/" << ext.miny() << " " << ext.maxx() << "/" << ext.maxy()); INFO(std::setprecision(6) << std::fixed << ext.minx() << "/" << ext.miny() << " " << ext.maxx() << "/"
<< ext.maxy());
REQUIRE(ext.minx() == -2); REQUIRE(ext.minx() == -2);
REQUIRE(ext.miny() == -2); REQUIRE(ext.miny() == -2);
REQUIRE(ext.maxx() == 5); REQUIRE(ext.maxx() == 5);
@ -383,11 +405,9 @@ TEST_CASE("postgis") {
REQUIRE(ds != nullptr); REQUIRE(ds != nullptr);
mapnik::box2d<double> ext = ds->envelope(); mapnik::box2d<double> ext = ds->envelope();
CAPTURE(ext); CAPTURE(ext);
INFO(std::setprecision(6) << std::fixed << ext.minx() << "/" << ext.miny() << " " << ext.maxx() << "/" << ext.maxy()); INFO(std::setprecision(6) << std::fixed << ext.minx() << "/" << ext.miny() << " " << ext.maxx() << "/" <<
REQUIRE(ext.minx() == 0); ext.maxy()); REQUIRE(ext.minx() == 0); REQUIRE(ext.miny() == 0); REQUIRE(ext.maxx() == 1); REQUIRE(ext.maxy()
REQUIRE(ext.miny() == 0); == 2);
REQUIRE(ext.maxx() == 1);
REQUIRE(ext.maxy() == 2);
} }
*/ */
SECTION("Postgis query extent: from subquery with 'extent_from_subquery=true'") SECTION("Postgis query extent: from subquery with 'extent_from_subquery=true'")
@ -399,7 +419,8 @@ TEST_CASE("postgis") {
REQUIRE(ds != nullptr); REQUIRE(ds != nullptr);
mapnik::box2d<double> ext = ds->envelope(); mapnik::box2d<double> ext = ds->envelope();
CAPTURE(ext); CAPTURE(ext);
INFO(std::setprecision(6) << std::fixed << ext.minx() << "/" << ext.miny() << " " << ext.maxx() << "/" << ext.maxy()); INFO(std::setprecision(6) << std::fixed << ext.minx() << "/" << ext.miny() << " " << ext.maxx() << "/"
<< ext.maxy());
REQUIRE(ext.minx() == 0); REQUIRE(ext.minx() == 0);
REQUIRE(ext.miny() == 0); REQUIRE(ext.miny() == 0);
REQUIRE(ext.maxx() == 1); REQUIRE(ext.maxx() == 1);
@ -410,27 +431,24 @@ TEST_CASE("postgis") {
{ {
mapnik::parameters params(base_params); mapnik::parameters params(base_params);
// !!!! postgis-vt-util::z() returns 'null' when 'scale_denominator > 600000000' // !!!! postgis-vt-util::z() returns 'null' when 'scale_denominator > 600000000'
// https://github.com/mapbox/postgis-vt-util/blob/559f073877696a6bfea41baf3e1065f9cf4d18d1/postgis-vt-util.sql#L615-L617 //
https://github.com/mapbox/postgis-vt-util/blob/559f073877696a6bfea41baf3e1065f9cf4d18d1/postgis-vt-util.sql#L615-L617
params["table"] = "(SELECT * FROM test where gid=4 AND z(!scale_denominator!) BETWEEN 0 AND 22) as data"; params["table"] = "(SELECT * FROM test where gid=4 AND z(!scale_denominator!) BETWEEN 0 AND 22) as data";
params["extent_from_subquery"] = "true"; params["extent_from_subquery"] = "true";
auto ds = mapnik::datasource_cache::instance().create(params); auto ds = mapnik::datasource_cache::instance().create(params);
REQUIRE(ds != nullptr); REQUIRE(ds != nullptr);
mapnik::box2d<double> ext = ds->envelope(); mapnik::box2d<double> ext = ds->envelope();
CAPTURE(ext); CAPTURE(ext);
INFO("" << std::setprecision(6) << std::fixed << ext.minx() << "/" << ext.miny() << " " << ext.maxx() << "/" << ext.maxy()); INFO("" << std::setprecision(6) << std::fixed << ext.minx() << "/" << ext.miny() << " " << ext.maxx() << "/"
REQUIRE(ext.minx() == 0); << ext.maxy()); REQUIRE(ext.minx() == 0); REQUIRE(ext.miny() == 0); REQUIRE(ext.maxx() == 1);
REQUIRE(ext.miny() == 0);
REQUIRE(ext.maxx() == 1);
REQUIRE(ext.maxy() == 2); REQUIRE(ext.maxy() == 2);
} }
*/ */
} }
} }
TEST_CASE("ConnectionCreator")
TEST_CASE("ConnectionCreator") { {
SECTION("ConnectionCreator::id() should not expose password") SECTION("ConnectionCreator::id() should not expose password")
{ {
mapnik::parameters params; mapnik::parameters params;
@ -444,5 +462,4 @@ SECTION("ConnectionCreator::id() should not expose password")
ConnectionCreator<Connection> creator(params); ConnectionCreator<Connection> creator(params);
CHECK(creator.id() == "host=H port=1234 dbname=D user=U connect_timeout=5 application_name=A"); CHECK(creator.id() == "host=H port=1234 dbname=D user=U connect_timeout=5 application_name=A");
} }
} }

View file

@ -80,7 +80,8 @@ int create_shapefile_index(std::string const& filename, bool index_parts, bool s
cmd += ".exe"; cmd += ".exe";
#endif #endif
cmd += " "; cmd += " ";
if (index_parts) cmd+= "--index-parts "; if (index_parts)
cmd += "--index-parts ";
cmd += filename; cmd += filename;
if (silent) if (silent)
{ {
@ -93,7 +94,7 @@ int create_shapefile_index(std::string const& filename, bool index_parts, bool s
return std::system(cmd.c_str()); return std::system(cmd.c_str());
} }
} } // namespace
TEST_CASE("invalid shapeindex") TEST_CASE("invalid shapeindex")
{ {
@ -102,7 +103,8 @@ TEST_CASE("invalid shapeindex")
{ {
SECTION("Invalid index") SECTION("Invalid index")
{ {
for (auto val : {std::make_tuple(true, std::string("mapnik-invalid-index.................")), // invalid header for (auto val :
{std::make_tuple(true, std::string("mapnik-invalid-index.................")), // invalid header
std::make_tuple(false, std::string("mapnik-index................."))}) // valid header + invalid index std::make_tuple(false, std::string("mapnik-index................."))}) // valid header + invalid index
{ {
std::string path = "test/data/shp/boundaries.shp"; std::string path = "test/data/shp/boundaries.shp";
@ -125,7 +127,8 @@ TEST_CASE("invalid shapeindex")
// ensure number of features are the same // ensure number of features are the same
CHECK(feature_count == feature_count_indexed); CHECK(feature_count == feature_count_indexed);
} }
else // the header is valid but index file itself is not - expect datasource to fail and return 0 features. else // the header is valid but index file itself is not - expect datasource to fail and return 0
// features.
{ {
CHECK(feature_count_indexed == 0); CHECK(feature_count_indexed == 0);
} }

View file

@ -73,13 +73,19 @@ TEST_CASE("spatial_index")
// query first N elements interface // query first N elements interface
results.clear(); results.clear();
in.seekg(0, std::ios::beg); in.seekg(0, std::ios::beg);
mapnik::util::spatial_index<value_type, filter_in_box, std::istringstream>::query_first_n(filter, in, results, 2); mapnik::util::spatial_index<value_type, filter_in_box, std::istringstream>::query_first_n(filter,
in,
results,
2);
REQUIRE(results.size() == 2); REQUIRE(results.size() == 2);
REQUIRE(results[0] == 1); REQUIRE(results[0] == 1);
REQUIRE(results[1] == 4); REQUIRE(results[1] == 4);
results.clear(); results.clear();
in.seekg(0, std::ios::beg); in.seekg(0, std::ios::beg);
mapnik::util::spatial_index<value_type, filter_in_box, std::istringstream>::query_first_n(filter, in, results, 5); mapnik::util::spatial_index<value_type, filter_in_box, std::istringstream>::query_first_n(filter,
in,
results,
5);
REQUIRE(results[0] == 1); REQUIRE(results[0] == 1);
REQUIRE(results[1] == 4); REQUIRE(results[1] == 4);
REQUIRE(results[2] == 3); REQUIRE(results[2] == 3);

View file

@ -41,7 +41,8 @@ bool parse_topology(std::string const& filename, mapnik::topojson::topology & to
std::string buffer; std::string buffer;
buffer.resize(file.size()); buffer.resize(file.size());
std::fread(&buffer[0], buffer.size(), 1, file.get()); std::fread(&buffer[0], buffer.size(), 1, file.get());
if (!file) return false; if (!file)
return false;
return parse_topology_string(buffer, topo); return parse_topology_string(buffer, topo);
} }
@ -59,8 +60,7 @@ bool parse_topology_string(std::string const& buffer, mapnik::topojson::topology
try try
{ {
boost::spirit::x3::phrase_parse(itr, end, mapnik::json::grammar::topology, space_type(), topo); boost::spirit::x3::phrase_parse(itr, end, mapnik::json::grammar::topology, space_type(), topo);
} } catch (boost::spirit::x3::expectation_failure<char const*> const& ex)
catch (boost::spirit::x3::expectation_failure<char const*> const& ex)
{ {
std::cerr << "failed to parse TopoJSON..." << std::endl; std::cerr << "failed to parse TopoJSON..." << std::endl;
std::cerr << ex.what() << std::endl; std::cerr << ex.what() << std::endl;
@ -81,7 +81,7 @@ bool parse_topology_string(std::string const& buffer, mapnik::topojson::topology
return (itr == end); return (itr == end);
} }
} } // namespace
TEST_CASE("TopoJSON") TEST_CASE("TopoJSON")
{ {
@ -89,36 +89,12 @@ TEST_CASE("TopoJSON")
{ {
// + A topology must have a member with the name “objects” whose value is another object. // + A topology must have a member with the name “objects” whose value is another object.
// + A topology must have a member with the name “arcs” whose value is an array of arcs. // + A topology must have a member with the name “arcs” whose value is an array of arcs.
CHECK(parse_topology_string(HEREDOC( CHECK(parse_topology_string(HEREDOC({"type" : "Topology", "objects" : {}, "arcs" : []})));
{ CHECK(parse_topology_string(HEREDOC({"type" : "Topology", "arcs" : [], "objects" : {}})));
"type": "Topology", "objects": {}, "arcs": [] CHECK(parse_topology_string(HEREDOC({"objects" : {}, "type" : "Topology", "arcs" : []})));
} CHECK(parse_topology_string(HEREDOC({"objects" : {}, "arcs" : [], "type" : "Topology"})));
))); CHECK(parse_topology_string(HEREDOC({"arcs" : [], "type" : "Topology", "objects" : {}})));
CHECK(parse_topology_string(HEREDOC( CHECK(parse_topology_string(HEREDOC({"arcs" : [], "objects" : {}, "type" : "Topology"})));
{
"type": "Topology", "arcs": [], "objects": {}
}
)));
CHECK(parse_topology_string(HEREDOC(
{
"objects": {}, "type": "Topology", "arcs": []
}
)));
CHECK(parse_topology_string(HEREDOC(
{
"objects": {}, "arcs": [], "type": "Topology"
}
)));
CHECK(parse_topology_string(HEREDOC(
{
"arcs": [], "type": "Topology", "objects": {}
}
)));
CHECK(parse_topology_string(HEREDOC(
{
"arcs": [], "objects": {}, "type": "Topology"
}
)));
} }
SECTION("geometry parsing") SECTION("geometry parsing")
@ -132,7 +108,8 @@ TEST_CASE("TopoJSON")
REQUIRE(parse_topology(path, topo)); REQUIRE(parse_topology(path, topo));
for (auto const& geom : topo.geometries) for (auto const& geom : topo.geometries)
{ {
mapnik::box2d<double> bbox = mapnik::util::apply_visitor(mapnik::topojson::bounding_box_visitor(topo), geom); mapnik::box2d<double> bbox =
mapnik::util::apply_visitor(mapnik::topojson::bounding_box_visitor(topo), geom);
CHECK(bbox.valid()); CHECK(bbox.valid());
mapnik::topojson::feature_generator<mapnik::context_ptr> visitor(ctx, tr, topo, feature_id++); mapnik::topojson::feature_generator<mapnik::context_ptr> visitor(ctx, tr, topo, feature_id++);
mapnik::feature_ptr feature = mapnik::util::apply_visitor(visitor, geom); mapnik::feature_ptr feature = mapnik::util::apply_visitor(visitor, geom);
@ -152,7 +129,8 @@ TEST_CASE("TopoJSON")
mapnik::value_integer feature_id = 0; mapnik::value_integer feature_id = 0;
for (auto const& geom : topo.geometries) for (auto const& geom : topo.geometries)
{ {
mapnik::box2d<double> bbox = mapnik::util::apply_visitor(mapnik::topojson::bounding_box_visitor(topo), geom); mapnik::box2d<double> bbox =
mapnik::util::apply_visitor(mapnik::topojson::bounding_box_visitor(topo), geom);
CHECK(bbox.valid()); CHECK(bbox.valid());
mapnik::topojson::feature_generator<mapnik::context_ptr> visitor(ctx, tr, topo, feature_id); mapnik::topojson::feature_generator<mapnik::context_ptr> visitor(ctx, tr, topo, feature_id);
mapnik::feature_ptr feature = mapnik::util::apply_visitor(visitor, geom); mapnik::feature_ptr feature = mapnik::util::apply_visitor(visitor, geom);
@ -165,11 +143,14 @@ TEST_CASE("TopoJSON")
attr{"description", tr.transcode("Test: \u005C")}, attr{"description", tr.transcode("Test: \u005C")},
attr{"double", mapnik::value_double(1.1)}, attr{"double", mapnik::value_double(1.1)},
attr{"int", mapnik::value_integer(1)}, attr{"int", mapnik::value_integer(1)},
attr{"object", tr.transcode("{\"name\":\"waka\",\"spaces\":\"value with spaces\",\"int\":1,\"double\":1.1,\"boolean\":false" attr{"object",
tr.transcode(
"{\"name\":\"waka\",\"spaces\":\"value with spaces\",\"int\":1,\"double\":1.1,\"boolean\":false"
",\"NOM_FR\":\"Québec\",\"array\":[\"string\",\"value with spaces\",3,1.1,null,true" ",\"NOM_FR\":\"Québec\",\"array\":[\"string\",\"value with spaces\",3,1.1,null,true"
",\"Québec\"],\"another_object\":{\"name\":\"nested object\"}}")}, ",\"Québec\"],\"another_object\":{\"name\":\"nested object\"}}")},
attr{"spaces", tr.transcode("this has spaces")}, attr{"spaces", tr.transcode("this has spaces")},
attr{"array", tr.transcode("[\"string\",\"value with spaces\",3,1.1,null,true," attr{"array",
tr.transcode("[\"string\",\"value with spaces\",3,1.1,null,true,"
"\"Québec\",{\"name\":\"object within an array\"}," "\"Québec\",{\"name\":\"object within an array\"},"
"[\"array\",\"within\",\"an\",\"array\"]]")}, "[\"array\",\"within\",\"an\",\"array\"]]")},
attr{"empty_array", tr.transcode("[]")}, attr{"empty_array", tr.transcode("[]")},
@ -178,5 +159,4 @@ TEST_CASE("TopoJSON")
REQUIRE_ATTRIBUTES(feature, attrs); REQUIRE_ATTRIBUTES(feature, attrs);
} }
} }
} }

View file

@ -16,12 +16,12 @@
#include <mapnik/text/placements/dummy.hpp> #include <mapnik/text/placements/dummy.hpp>
#include <mapnik/text/formatting/text.hpp> #include <mapnik/text/formatting/text.hpp>
TEST_CASE("fontset") { TEST_CASE("fontset")
{
SECTION("error") { SECTION("error")
{
try { try
{
// create a renderable map with a fontset and a text symbolizer // create a renderable map with a fontset and a text symbolizer
// and do not register any fonts, to ensure the error thrown is reasonable // and do not register any fonts, to ensure the error thrown is reasonable
mapnik::context_ptr ctx = std::make_shared<mapnik::context_type>(); mapnik::context_ptr ctx = std::make_shared<mapnik::context_type>();
@ -54,18 +54,20 @@ SECTION("error") {
placement_finder->defaults.format_defaults.text_size = 10.0; placement_finder->defaults.format_defaults.text_size = 10.0;
placement_finder->defaults.format_defaults.fill = mapnik::color(0, 0, 0); placement_finder->defaults.format_defaults.fill = mapnik::color(0, 0, 0);
placement_finder->defaults.format_defaults.fontset = fontset; placement_finder->defaults.format_defaults.fontset = fontset;
placement_finder->defaults.set_format_tree(std::make_shared<mapnik::formatting::text_node>(mapnik::parse_expression("[name]"))); placement_finder->defaults.set_format_tree(
std::make_shared<mapnik::formatting::text_node>(mapnik::parse_expression("[name]")));
mapnik::put<mapnik::text_placements_ptr>(text_sym, mapnik::keys::text_placements_, placement_finder); mapnik::put<mapnik::text_placements_ptr>(text_sym, mapnik::keys::text_placements_, placement_finder);
r.append(std::move(text_sym)); r.append(std::move(text_sym));
the_style.add_rule(std::move(r)); the_style.add_rule(std::move(r));
m.insert_style("style", std::move(the_style)); m.insert_style("style", std::move(the_style));
m.zoom_to_box(mapnik::box2d<double>(-256,-256, m.zoom_to_box(mapnik::box2d<double>(-256, -256, 256, 256));
256,256));
mapnik::image_rgba8 buf(m.width(), m.height()); mapnik::image_rgba8 buf(m.width(), m.height());
mapnik::agg_renderer<mapnik::image_rgba8> ren(m, buf); mapnik::agg_renderer<mapnik::image_rgba8> ren(m, buf);
ren.apply(); ren.apply();
} catch (std::exception const& ex) { } catch (std::exception const& ex)
REQUIRE(std::string(ex.what()) == std::string("Unable to find specified font face 'DejaVu Sans Book' in font set: 'fontset'")); {
REQUIRE(std::string(ex.what()) ==
std::string("Unable to find specified font face 'DejaVu Sans Book' in font set: 'fontset'"));
} }
} }
} }

View file

@ -2,24 +2,24 @@
#include <mapnik/geometry/centroid.hpp> #include <mapnik/geometry/centroid.hpp>
TEST_CASE("geometry centroid") { TEST_CASE("geometry centroid")
{
SECTION("empty geometry") { SECTION("empty geometry")
{
mapnik::geometry::geometry_empty geom; mapnik::geometry::geometry_empty geom;
mapnik::geometry::point<double> centroid; mapnik::geometry::point<double> centroid;
REQUIRE(!mapnik::geometry::centroid(geom, centroid)); REQUIRE(!mapnik::geometry::centroid(geom, centroid));
} }
SECTION("geometry collection") { SECTION("geometry collection")
{
mapnik::geometry::geometry_collection<double> geom; mapnik::geometry::geometry_collection<double> geom;
mapnik::geometry::point<double> centroid; mapnik::geometry::point<double> centroid;
REQUIRE(!mapnik::geometry::centroid(geom, centroid)); REQUIRE(!mapnik::geometry::centroid(geom, centroid));
} }
SECTION("point") { SECTION("point")
{
mapnik::geometry::point<double> pt(10, 10); mapnik::geometry::point<double> pt(10, 10);
mapnik::geometry::point<double> centroid; mapnik::geometry::point<double> centroid;
REQUIRE(mapnik::geometry::centroid(pt, centroid)); REQUIRE(mapnik::geometry::centroid(pt, centroid));
@ -27,8 +27,8 @@ SECTION("point") {
REQUIRE(pt.y == centroid.y); REQUIRE(pt.y == centroid.y);
} }
SECTION("linestring") { SECTION("linestring")
{
mapnik::geometry::line_string<double> line; mapnik::geometry::line_string<double> line;
line.emplace_back(0, 0); line.emplace_back(0, 0);
line.emplace_back(25, 25); line.emplace_back(25, 25);
@ -39,15 +39,15 @@ SECTION("linestring") {
REQUIRE(centroid.y == 25); REQUIRE(centroid.y == 25);
} }
SECTION("empty linestring") { SECTION("empty linestring")
{
mapnik::geometry::line_string<double> line; mapnik::geometry::line_string<double> line;
mapnik::geometry::point<double> centroid; mapnik::geometry::point<double> centroid;
REQUIRE(!mapnik::geometry::centroid(line, centroid)); REQUIRE(!mapnik::geometry::centroid(line, centroid));
} }
SECTION("polygon") { SECTION("polygon")
{
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
mapnik::geometry::linear_ring<double> ring; mapnik::geometry::linear_ring<double> ring;
ring.emplace_back(0, 0); ring.emplace_back(0, 0);
@ -63,8 +63,8 @@ SECTION("polygon") {
REQUIRE(centroid.y == 0.5); REQUIRE(centroid.y == 0.5);
} }
SECTION("polygon with empty exterior ring") { SECTION("polygon with empty exterior ring")
{
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
mapnik::geometry::linear_ring<double> ring; mapnik::geometry::linear_ring<double> ring;
poly.push_back(std::move(ring)); poly.push_back(std::move(ring));
@ -73,16 +73,16 @@ SECTION("polygon with empty exterior ring") {
REQUIRE(!mapnik::geometry::centroid(poly, centroid)); REQUIRE(!mapnik::geometry::centroid(poly, centroid));
} }
SECTION("empty polygon") { SECTION("empty polygon")
{
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
poly.emplace_back(); poly.emplace_back();
mapnik::geometry::point<double> centroid; mapnik::geometry::point<double> centroid;
REQUIRE(!mapnik::geometry::centroid(poly, centroid)); REQUIRE(!mapnik::geometry::centroid(poly, centroid));
} }
SECTION("multi-point") { SECTION("multi-point")
{
mapnik::geometry::multi_point<double> geom; mapnik::geometry::multi_point<double> geom;
geom.emplace_back(0, 0); geom.emplace_back(0, 0);
geom.emplace_back(25, 25); geom.emplace_back(25, 25);
@ -93,15 +93,15 @@ SECTION("multi-point") {
REQUIRE(centroid.y == 25); REQUIRE(centroid.y == 25);
} }
SECTION("empty multi-point") { SECTION("empty multi-point")
{
mapnik::geometry::multi_point<double> geom; mapnik::geometry::multi_point<double> geom;
mapnik::geometry::point<double> centroid; mapnik::geometry::point<double> centroid;
REQUIRE(!mapnik::geometry::centroid(geom, centroid)); REQUIRE(!mapnik::geometry::centroid(geom, centroid));
} }
SECTION("multi-linestring") { SECTION("multi-linestring")
{
mapnik::geometry::multi_line_string<double> geom; mapnik::geometry::multi_line_string<double> geom;
{ {
mapnik::geometry::line_string<double> line; mapnik::geometry::line_string<double> line;
@ -123,8 +123,8 @@ SECTION("multi-linestring") {
REQUIRE(centroid.y == 12.5); REQUIRE(centroid.y == 12.5);
} }
SECTION("multi-linestring: one component empty") { SECTION("multi-linestring: one component empty")
{
mapnik::geometry::multi_line_string<double> geom; mapnik::geometry::multi_line_string<double> geom;
mapnik::geometry::line_string<double> line; mapnik::geometry::line_string<double> line;
line.emplace_back(0, 0); line.emplace_back(0, 0);
@ -138,15 +138,15 @@ SECTION("multi-linestring: one component empty") {
REQUIRE(centroid.y == 25); REQUIRE(centroid.y == 25);
} }
SECTION("empty multi-linestring") { SECTION("empty multi-linestring")
{
mapnik::geometry::multi_line_string<double> geom; mapnik::geometry::multi_line_string<double> geom;
mapnik::geometry::point<double> centroid; mapnik::geometry::point<double> centroid;
REQUIRE(!mapnik::geometry::centroid(geom, centroid)); REQUIRE(!mapnik::geometry::centroid(geom, centroid));
} }
SECTION("multi-polygon") { SECTION("multi-polygon")
{
mapnik::geometry::multi_polygon<double> geom; mapnik::geometry::multi_polygon<double> geom;
{ {
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
@ -177,8 +177,8 @@ SECTION("multi-polygon") {
REQUIRE(centroid.y == 1); REQUIRE(centroid.y == 1);
} }
SECTION("multi-polygon: one component empty") { SECTION("multi-polygon: one component empty")
{
mapnik::geometry::multi_polygon<double> geom; mapnik::geometry::multi_polygon<double> geom;
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
mapnik::geometry::linear_ring<double> ring; mapnik::geometry::linear_ring<double> ring;
@ -197,8 +197,8 @@ SECTION("multi-polygon: one component empty") {
REQUIRE(centroid.y == 0.5); REQUIRE(centroid.y == 0.5);
} }
SECTION("empty multi-polygon") { SECTION("empty multi-polygon")
{
mapnik::geometry::multi_polygon<double> geom; mapnik::geometry::multi_polygon<double> geom;
mapnik::geometry::point<double> centroid; mapnik::geometry::point<double> centroid;
REQUIRE(!mapnik::geometry::centroid(geom, centroid)); REQUIRE(!mapnik::geometry::centroid(geom, centroid));

View file

@ -2,12 +2,12 @@
#include <mapnik/geometry/closest_point.hpp> #include <mapnik/geometry/closest_point.hpp>
TEST_CASE("geometry closest point") { TEST_CASE("geometry closest point")
{
#if BOOST_VERSION >= 106200 #if BOOST_VERSION >= 106200
SECTION("geometry_empty") { SECTION("geometry_empty")
{
mapnik::geometry::point<double> pt(0, 0); mapnik::geometry::point<double> pt(0, 0);
mapnik::geometry::geometry_empty empty; mapnik::geometry::geometry_empty empty;
auto result = mapnik::geometry::closest_point(empty, pt); auto result = mapnik::geometry::closest_point(empty, pt);
@ -16,8 +16,8 @@ SECTION("geometry_empty") {
REQUIRE(result.distance == -1.0); REQUIRE(result.distance == -1.0);
} }
SECTION("point") { SECTION("point")
{
mapnik::geometry::point<double> pt(0, 0); mapnik::geometry::point<double> pt(0, 0);
mapnik::geometry::point<double> geom(3.0, 4.0); mapnik::geometry::point<double> geom(3.0, 4.0);
auto result = mapnik::geometry::closest_point(geom, pt); auto result = mapnik::geometry::closest_point(geom, pt);
@ -26,8 +26,8 @@ SECTION("point") {
REQUIRE(result.distance == 5.0); REQUIRE(result.distance == 5.0);
} }
SECTION("linestring") { SECTION("linestring")
{
mapnik::geometry::line_string<double> line; mapnik::geometry::line_string<double> line;
line.emplace_back(0, 0); line.emplace_back(0, 0);
line.emplace_back(0, 100); line.emplace_back(0, 100);
@ -40,9 +40,8 @@ SECTION("linestring") {
REQUIRE(result.distance == 50.0); REQUIRE(result.distance == 50.0);
} }
SECTION("polygon")
SECTION("polygon") { {
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
mapnik::geometry::linear_ring<double> ring; mapnik::geometry::linear_ring<double> ring;
ring.emplace_back(0, 0); ring.emplace_back(0, 0);

View file

@ -5,9 +5,10 @@
#include <mapnik/json/geometry_parser.hpp> #include <mapnik/json/geometry_parser.hpp>
#include <mapnik/util/geometry_to_geojson.hpp> #include <mapnik/util/geometry_to_geojson.hpp>
TEST_CASE("geometry") { TEST_CASE("geometry")
{
SECTION("json point") { SECTION("json point")
{
mapnik::util::file input("./test/data/json/point1.json"); mapnik::util::file input("./test/data/json/point1.json");
REQUIRE(input); REQUIRE(input);
mapnik::geometry::geometry<double> geom; mapnik::geometry::geometry<double> geom;
@ -22,7 +23,8 @@ SECTION("json point") {
REQUIRE(mapnik::util::to_geojson(new_json, geom)); REQUIRE(mapnik::util::to_geojson(new_json, geom));
} }
SECTION("json point reversed") { SECTION("json point reversed")
{
mapnik::util::file input("./test/data/json/point2.json"); mapnik::util::file input("./test/data/json/point2.json");
REQUIRE(input); REQUIRE(input);
mapnik::geometry::geometry<double> geom; mapnik::geometry::geometry<double> geom;
@ -35,7 +37,8 @@ SECTION("json point reversed") {
REQUIRE(point.y == 10); REQUIRE(point.y == 10);
} }
SECTION("json point reversed + extra attributes") { SECTION("json point reversed + extra attributes")
{
mapnik::util::file input("./test/data/json/point3.json"); mapnik::util::file input("./test/data/json/point3.json");
REQUIRE(input); REQUIRE(input);
mapnik::geometry::geometry<double> geom; mapnik::geometry::geometry<double> geom;
@ -47,5 +50,4 @@ SECTION("json point reversed + extra attributes") {
REQUIRE(point.x == 30); REQUIRE(point.x == 30);
REQUIRE(point.y == 10); REQUIRE(point.y == 10);
} }
} }

View file

@ -138,15 +138,14 @@ void envelope_test()
} }
} }
} } // namespace
TEST_CASE("geometry ops - envelope") {
TEST_CASE("geometry ops - envelope")
{
SECTION("envelope_test") SECTION("envelope_test")
{ {
envelope_test<int>(); envelope_test<int>();
envelope_test<double>(); envelope_test<double>();
envelope_test<float>(); envelope_test<float>();
} }
} }

View file

@ -25,58 +25,55 @@ template<class T>
auto do_begin(T& v) -> decltype(begin(v)); auto do_begin(T& v) -> decltype(begin(v));
template<class T> template<class T>
auto do_end(T& v) -> decltype(end(v)); auto do_end(T& v) -> decltype(end(v));
} // adl:: } // namespace adl
template<class... Its> template<class... Its>
using zipper_it = boost::zip_iterator<boost::tuple<Its...>>; using zipper_it = boost::zip_iterator<boost::tuple<Its...>>;
template<class T> template<class T>
T const& as_const(T const& v){ return v; } T const& as_const(T const& v)
} // aux:: {
return v;
}
} // namespace aux
template<class... Conts> template<class... Conts>
auto zip_begin(Conts&... conts) auto zip_begin(Conts&... conts) -> aux::zipper_it<decltype(aux::adl::do_begin(conts))...>
-> aux::zipper_it<decltype(aux::adl::do_begin(conts))...>
{ {
using std::begin; using std::begin;
return {boost::make_tuple(begin(conts)...)}; return {boost::make_tuple(begin(conts)...)};
} }
template<class... Conts> template<class... Conts>
auto zip_end(Conts&... conts) auto zip_end(Conts&... conts) -> aux::zipper_it<decltype(aux::adl::do_end(conts))...>
-> aux::zipper_it<decltype(aux::adl::do_end(conts))...>
{ {
using std::end; using std::end;
return {boost::make_tuple(end(conts)...)}; return {boost::make_tuple(end(conts)...)};
} }
template<class... Conts> template<class... Conts>
auto zip_range(Conts&... conts) auto zip_range(Conts&... conts) -> boost::iterator_range<decltype(zip_begin(conts...))>
-> boost::iterator_range<decltype(zip_begin(conts...))>
{ {
return {zip_begin(conts...), zip_end(conts...)}; return {zip_begin(conts...), zip_end(conts...)};
} }
// for const access // for const access
template<class... Conts> template<class... Conts>
auto zip_cbegin(Conts&... conts) auto zip_cbegin(Conts&... conts) -> decltype(zip_begin(aux::as_const(conts)...))
-> decltype(zip_begin(aux::as_const(conts)...))
{ {
using std::begin; using std::begin;
return zip_begin(aux::as_const(conts)...); return zip_begin(aux::as_const(conts)...);
} }
template<class... Conts> template<class... Conts>
auto zip_cend(Conts&... conts) auto zip_cend(Conts&... conts) -> decltype(zip_end(aux::as_const(conts)...))
-> decltype(zip_end(aux::as_const(conts)...))
{ {
using std::end; using std::end;
return zip_end(aux::as_const(conts)...); return zip_end(aux::as_const(conts)...);
} }
template<class... Conts> template<class... Conts>
auto zip_crange(Conts&... conts) auto zip_crange(Conts&... conts) -> decltype(zip_range(aux::as_const(conts)...))
-> decltype(zip_range(aux::as_const(conts)...))
{ {
return zip_range(aux::as_const(conts)...); return zip_range(aux::as_const(conts)...);
} }
@ -86,14 +83,14 @@ auto zip_crange(Conts&... conts)
#include <mapnik/util/variant.hpp> #include <mapnik/util/variant.hpp>
using mapnik::geometry::geometry; using mapnik::geometry::geometry;
using mapnik::geometry::geometry_empty;
using mapnik::geometry::point;
using mapnik::geometry::line_string;
using mapnik::geometry::polygon;
using mapnik::geometry::multi_point;
using mapnik::geometry::multi_line_string;
using mapnik::geometry::multi_polygon;
using mapnik::geometry::geometry_collection; using mapnik::geometry::geometry_collection;
using mapnik::geometry::geometry_empty;
using mapnik::geometry::line_string;
using mapnik::geometry::multi_line_string;
using mapnik::geometry::multi_point;
using mapnik::geometry::multi_polygon;
using mapnik::geometry::point;
using mapnik::geometry::polygon;
template<typename T> template<typename T>
void assert_g_equal(geometry<T> const& g1, geometry<T> const& g2); void assert_g_equal(geometry<T> const& g1, geometry<T> const& g2);
@ -153,18 +150,15 @@ struct geometry_equal_visitor
template<typename T> template<typename T>
void operator()(line_string<T> const& ls1, line_string<T> const& ls2) const void operator()(line_string<T> const& ls1, line_string<T> const& ls2) const
{ {
(*this)(static_cast<std::vector<point<T>> const&>(ls1), (*this)(static_cast<std::vector<point<T>> const&>(ls1), static_cast<std::vector<point<T>> const&>(ls2));
static_cast<std::vector<point<T>> const&>(ls2));
} }
template<typename T> template<typename T>
void operator()(multi_point<T> const& mp1, multi_point<T> const& mp2) const void operator()(multi_point<T> const& mp1, multi_point<T> const& mp2) const
{ {
(*this)(static_cast<std::vector<point<T>> const&>(mp1), (*this)(static_cast<std::vector<point<T>> const&>(mp1), static_cast<std::vector<point<T>> const&>(mp2));
static_cast<std::vector<point<T>> const&>(mp2));
} }
template<typename T> template<typename T>
void operator()(multi_line_string<T> const& mls1, multi_line_string<T> const& mls2) const void operator()(multi_line_string<T> const& mls1, multi_line_string<T> const& mls2) const
{ {
@ -194,7 +188,8 @@ struct geometry_equal_visitor
} }
template<typename T> template<typename T>
void operator() (mapnik::util::recursive_wrapper<geometry_collection<T> > const& c1_, mapnik::util::recursive_wrapper<geometry_collection<T> > const& c2_) const void operator()(mapnik::util::recursive_wrapper<geometry_collection<T>> const& c1_,
mapnik::util::recursive_wrapper<geometry_collection<T>> const& c2_) const
{ {
geometry_collection<T> const& c1 = static_cast<geometry_collection<T> const&>(c1_); geometry_collection<T> const& c1 = static_cast<geometry_collection<T> const&>(c1_);
geometry_collection<T> const& c2 = static_cast<geometry_collection<T> const&>(c2_); geometry_collection<T> const& c2 = static_cast<geometry_collection<T> const&>(c2_);

View file

@ -4,9 +4,10 @@
#include <mapnik/hit_test_filter.hpp> #include <mapnik/hit_test_filter.hpp>
#include <mapnik/geometry/correct.hpp> #include <mapnik/geometry/correct.hpp>
TEST_CASE("geometry ops") { TEST_CASE("geometry ops")
{
SECTION("hit_test_filter - double") { SECTION("hit_test_filter - double")
{
using namespace mapnik::geometry; using namespace mapnik::geometry;
{ {
geometry<double> geom(point<double>(0, 0)); geometry<double> geom(point<double>(0, 0));
@ -104,5 +105,4 @@ SECTION("hit_test_filter - double") {
REQUIRE(mapnik::hit_test(geometry<double>(poly), -5, 5, 0)); REQUIRE(mapnik::hit_test(geometry<double>(poly), -5, 5, 0));
} }
} }
} }

View file

@ -4,27 +4,31 @@
#include <mapnik/geometry.hpp> #include <mapnik/geometry.hpp>
#include <mapnik/geometry/is_simple.hpp> #include <mapnik/geometry/is_simple.hpp>
TEST_CASE("geometry is_simple") { TEST_CASE("geometry is_simple")
{
// only Boost >= 1.58 has the required is_valid function version // only Boost >= 1.58 has the required is_valid function version
#if BOOST_VERSION >= 105800 #if BOOST_VERSION >= 105800
SECTION("point") { SECTION("point")
{
mapnik::geometry::geometry_empty empty; mapnik::geometry::geometry_empty empty;
CHECK(mapnik::geometry::is_simple(empty)); CHECK(mapnik::geometry::is_simple(empty));
} }
SECTION("point") { SECTION("point")
{
mapnik::geometry::point<double> pt(0, 0); mapnik::geometry::point<double> pt(0, 0);
CHECK(mapnik::geometry::is_simple(pt)); CHECK(mapnik::geometry::is_simple(pt));
} }
SECTION("point uninitialized") { SECTION("point uninitialized")
{
mapnik::geometry::point<double> pt2; mapnik::geometry::point<double> pt2;
CHECK(mapnik::geometry::is_simple(pt2)); CHECK(mapnik::geometry::is_simple(pt2));
} }
SECTION("point -- geometry object") { SECTION("point -- geometry object")
{
mapnik::geometry::point<double> pt(0, 0); mapnik::geometry::point<double> pt(0, 0);
mapnik::geometry::geometry<double> geom(pt); mapnik::geometry::geometry<double> geom(pt);
CHECK(mapnik::geometry::is_simple(geom)); CHECK(mapnik::geometry::is_simple(geom));
@ -33,8 +37,10 @@ SECTION("point -- geometry object") {
// This is funky that boost geometry is_simple does not check for NAN when dealing with a point // This is funky that boost geometry is_simple does not check for NAN when dealing with a point
// this test is here in case the logic ever changes // this test is here in case the logic ever changes
// Bug report on this: https://svn.boost.org/trac/boost/ticket/11711 // Bug report on this: https://svn.boost.org/trac/boost/ticket/11711
SECTION("point NaN") { SECTION("point NaN")
mapnik::geometry::point<double> pt(std::numeric_limits<double>::quiet_NaN(),std::numeric_limits<double>::quiet_NaN()); {
mapnik::geometry::point<double> pt(std::numeric_limits<double>::quiet_NaN(),
std::numeric_limits<double>::quiet_NaN());
CHECK(std::isnan(pt.x)); CHECK(std::isnan(pt.x));
CHECK(std::isnan(pt.y)); CHECK(std::isnan(pt.y));
CHECK(mapnik::geometry::is_simple(pt)); CHECK(mapnik::geometry::is_simple(pt));
@ -43,26 +49,31 @@ SECTION("point NaN") {
// This is funky that boost geometry is_simple does not check for infinity when dealing with a point // This is funky that boost geometry is_simple does not check for infinity when dealing with a point
// this test is here in case the logic ever changes // this test is here in case the logic ever changes
// Bug report on this: https://svn.boost.org/trac/boost/ticket/11711 // Bug report on this: https://svn.boost.org/trac/boost/ticket/11711
SECTION("point Infinity") { SECTION("point Infinity")
mapnik::geometry::point<double> pt(std::numeric_limits<double>::infinity(),std::numeric_limits<double>::infinity()); {
mapnik::geometry::point<double> pt(std::numeric_limits<double>::infinity(),
std::numeric_limits<double>::infinity());
CHECK(std::isinf(pt.x)); CHECK(std::isinf(pt.x));
CHECK(std::isinf(pt.y)); CHECK(std::isinf(pt.y));
CHECK(mapnik::geometry::is_simple(pt)); CHECK(mapnik::geometry::is_simple(pt));
} }
SECTION("multi point") { SECTION("multi point")
{
mapnik::geometry::multi_point<double> mpt; mapnik::geometry::multi_point<double> mpt;
mpt.emplace_back(0, 0); mpt.emplace_back(0, 0);
mpt.emplace_back(1, 1); mpt.emplace_back(1, 1);
CHECK(mapnik::geometry::is_simple(mpt)); CHECK(mapnik::geometry::is_simple(mpt));
} }
SECTION("multi point empty") { SECTION("multi point empty")
{
mapnik::geometry::multi_point<double> mpt; mapnik::geometry::multi_point<double> mpt;
CHECK(mapnik::geometry::is_simple(mpt)); CHECK(mapnik::geometry::is_simple(mpt));
} }
SECTION("line_string") { SECTION("line_string")
{
mapnik::geometry::line_string<double> line; mapnik::geometry::line_string<double> line;
line.emplace_back(0, 0); line.emplace_back(0, 0);
line.emplace_back(1, 1); line.emplace_back(1, 1);
@ -70,7 +81,8 @@ SECTION("line_string") {
} }
// This fails while is_valid will not fail! // This fails while is_valid will not fail!
SECTION("line_string repeated points") { SECTION("line_string repeated points")
{
mapnik::geometry::line_string<double> line; mapnik::geometry::line_string<double> line;
line.emplace_back(0, 0); line.emplace_back(0, 0);
line.emplace_back(1, 1); line.emplace_back(1, 1);
@ -79,12 +91,14 @@ SECTION("line_string repeated points") {
CHECK(!mapnik::geometry::is_simple(line)); CHECK(!mapnik::geometry::is_simple(line));
} }
SECTION("line_string empty") { SECTION("line_string empty")
{
mapnik::geometry::line_string<double> line; mapnik::geometry::line_string<double> line;
CHECK(mapnik::geometry::is_simple(line)); CHECK(mapnik::geometry::is_simple(line));
} }
SECTION("multi_line_string") { SECTION("multi_line_string")
{
mapnik::geometry::line_string<double> line1; mapnik::geometry::line_string<double> line1;
line1.emplace_back(0, 0); line1.emplace_back(0, 0);
line1.emplace_back(1, 1); line1.emplace_back(1, 1);
@ -97,19 +111,22 @@ SECTION("multi_line_string") {
CHECK(mapnik::geometry::is_simple(lines)); CHECK(mapnik::geometry::is_simple(lines));
} }
SECTION("multi_line_string empty") { SECTION("multi_line_string empty")
{
mapnik::geometry::multi_line_string<double> lines; mapnik::geometry::multi_line_string<double> lines;
CHECK(mapnik::geometry::is_simple(lines)); CHECK(mapnik::geometry::is_simple(lines));
} }
SECTION("multi_line_string empty") { SECTION("multi_line_string empty")
{
mapnik::geometry::multi_line_string<double> lines; mapnik::geometry::multi_line_string<double> lines;
mapnik::geometry::line_string<double> line; mapnik::geometry::line_string<double> line;
lines.emplace_back(line); lines.emplace_back(line);
CHECK(mapnik::geometry::is_simple(lines)); CHECK(mapnik::geometry::is_simple(lines));
} }
SECTION("polygon") { SECTION("polygon")
{
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
mapnik::geometry::linear_ring<double> ring; mapnik::geometry::linear_ring<double> ring;
ring.emplace_back(0, 0); ring.emplace_back(0, 0);
@ -121,7 +138,8 @@ SECTION("polygon") {
CHECK(mapnik::geometry::is_simple(poly)); CHECK(mapnik::geometry::is_simple(poly));
} }
SECTION("polygon invalid winding order") { SECTION("polygon invalid winding order")
{
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
mapnik::geometry::linear_ring<double> ring; mapnik::geometry::linear_ring<double> ring;
ring.emplace_back(0, 0); ring.emplace_back(0, 0);
@ -135,7 +153,8 @@ SECTION("polygon invalid winding order") {
// repeated points are not considered invalid in a polygon // repeated points are not considered invalid in a polygon
// but they are considered not simple // but they are considered not simple
SECTION("polygon 2 repeated points") { SECTION("polygon 2 repeated points")
{
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
mapnik::geometry::linear_ring<double> ring; mapnik::geometry::linear_ring<double> ring;
ring.emplace_back(0, 0); ring.emplace_back(0, 0);
@ -149,7 +168,8 @@ SECTION("polygon 2 repeated points") {
} }
// repeated points are not considered invalid in a polygon // repeated points are not considered invalid in a polygon
// but they are considered not simple // but they are considered not simple
SECTION("polygon 3 repeated points") { SECTION("polygon 3 repeated points")
{
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
mapnik::geometry::linear_ring<double> ring; mapnik::geometry::linear_ring<double> ring;
ring.emplace_back(0, 0); ring.emplace_back(0, 0);
@ -165,20 +185,23 @@ SECTION("polygon 3 repeated points") {
#if BOOST_VERSION >= 106000 #if BOOST_VERSION >= 106000
SECTION("polygon that is empty") { SECTION("polygon that is empty")
{
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
poly.emplace_back(); poly.emplace_back();
CHECK(!mapnik::geometry::is_simple(poly)); CHECK(!mapnik::geometry::is_simple(poly));
} }
SECTION("polygon that has empty exterior ring") { SECTION("polygon that has empty exterior ring")
{
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
mapnik::geometry::linear_ring<double> ring; mapnik::geometry::linear_ring<double> ring;
poly.push_back(std::move(ring)); poly.push_back(std::move(ring));
CHECK(!mapnik::geometry::is_simple(poly)); CHECK(!mapnik::geometry::is_simple(poly));
} }
SECTION("polygon that has empty interior ring") { SECTION("polygon that has empty interior ring")
{
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
mapnik::geometry::linear_ring<double> ring; mapnik::geometry::linear_ring<double> ring;
ring.emplace_back(0, 0); ring.emplace_back(0, 0);
@ -194,19 +217,22 @@ SECTION("polygon that has empty interior ring") {
#else // BOOST_VERSION >= 1.60 #else // BOOST_VERSION >= 1.60
SECTION("polygon that is empty") { SECTION("polygon that is empty")
{
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
CHECK(mapnik::geometry::is_simple(poly)); CHECK(mapnik::geometry::is_simple(poly));
} }
SECTION("polygon that has empty exterior ring") { SECTION("polygon that has empty exterior ring")
{
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
mapnik::geometry::linear_ring<double> ring; mapnik::geometry::linear_ring<double> ring;
poly.push_back(std::move(ring)); poly.push_back(std::move(ring));
CHECK(mapnik::geometry::is_simple(poly)); CHECK(mapnik::geometry::is_simple(poly));
} }
SECTION("polygon that has empty interior ring") { SECTION("polygon that has empty interior ring")
{
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
mapnik::geometry::linear_ring<double> ring; mapnik::geometry::linear_ring<double> ring;
ring.emplace_back(0, 0); ring.emplace_back(0, 0);
@ -223,7 +249,8 @@ SECTION("polygon that has empty interior ring") {
#endif // BOOST_VERSION >= 1.60 #endif // BOOST_VERSION >= 1.60
// A polygon with a spike can still be simple // A polygon with a spike can still be simple
SECTION("polygon with spike") { SECTION("polygon with spike")
{
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
mapnik::geometry::linear_ring<double> ring; mapnik::geometry::linear_ring<double> ring;
ring.emplace_back(0, 0); ring.emplace_back(0, 0);
@ -237,7 +264,8 @@ SECTION("polygon with spike") {
CHECK(mapnik::geometry::is_simple(poly)); CHECK(mapnik::geometry::is_simple(poly));
} }
SECTION("polygon with hole") { SECTION("polygon with hole")
{
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
mapnik::geometry::linear_ring<double> ring; mapnik::geometry::linear_ring<double> ring;
ring.emplace_back(0, 0); ring.emplace_back(0, 0);
@ -257,7 +285,8 @@ SECTION("polygon with hole") {
} }
// Polygons with reversed winding order still can be considered simple // Polygons with reversed winding order still can be considered simple
SECTION("polygon with hole with invalid winding order") { SECTION("polygon with hole with invalid winding order")
{
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
mapnik::geometry::linear_ring<double> ring; mapnik::geometry::linear_ring<double> ring;
ring.emplace_back(0, 0); ring.emplace_back(0, 0);
@ -276,7 +305,8 @@ SECTION("polygon with hole with invalid winding order") {
CHECK(mapnik::geometry::is_simple(poly)); CHECK(mapnik::geometry::is_simple(poly));
} }
SECTION("multi polygon") { SECTION("multi polygon")
{
mapnik::geometry::multi_polygon<double> mp; mapnik::geometry::multi_polygon<double> mp;
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
mapnik::geometry::linear_ring<double> ring; mapnik::geometry::linear_ring<double> ring;
@ -300,7 +330,8 @@ SECTION("multi polygon") {
CHECK(mapnik::geometry::is_simple(mp)); CHECK(mapnik::geometry::is_simple(mp));
} }
SECTION("multi polygon with hole") { SECTION("multi polygon with hole")
{
mapnik::geometry::multi_polygon<double> mp; mapnik::geometry::multi_polygon<double> mp;
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
mapnik::geometry::linear_ring<double> ring; mapnik::geometry::linear_ring<double> ring;
@ -337,17 +368,18 @@ SECTION("multi polygon with hole") {
CHECK(mapnik::geometry::is_simple(mp)); CHECK(mapnik::geometry::is_simple(mp));
} }
SECTION("multi polygon empty") { SECTION("multi polygon empty")
{
mapnik::geometry::multi_polygon<double> mp; mapnik::geometry::multi_polygon<double> mp;
CHECK(mapnik::geometry::is_simple(mp)); CHECK(mapnik::geometry::is_simple(mp));
} }
#else // BOOST_VERSION >= 1.58 #else // BOOST_VERSION >= 1.58
SECTION("skipped is_simple tests") { SECTION("skipped is_simple tests")
{
WARN("geometry simple tests disabled due to boost version older that 1.58 used"); WARN("geometry simple tests disabled due to boost version older that 1.58 used");
} }
#endif #endif
} }

View file

@ -3,13 +3,13 @@
#include <mapnik/geometry.hpp> #include <mapnik/geometry.hpp>
#include <mapnik/geometry/is_valid.hpp> #include <mapnik/geometry/is_valid.hpp>
TEST_CASE("geometry is_valid") { TEST_CASE("geometry is_valid")
{
// only Boost >= 1.56 has the is_valid function, but only after 1.58 is there support for returning what is invalid // only Boost >= 1.56 has the is_valid function, but only after 1.58 is there support for returning what is invalid
#if BOOST_VERSION >= 105800 #if BOOST_VERSION >= 105800
SECTION("empty geometry")
SECTION("empty geometry") { {
mapnik::geometry::geometry_empty empty; mapnik::geometry::geometry_empty empty;
CHECK(mapnik::geometry::is_valid(empty)); CHECK(mapnik::geometry::is_valid(empty));
std::string message; std::string message;
@ -20,7 +20,8 @@ SECTION("empty geometry") {
CHECK(failure == boost::geometry::no_failure); CHECK(failure == boost::geometry::no_failure);
} }
SECTION("point") { SECTION("point")
{
mapnik::geometry::point<double> pt(0, 0); mapnik::geometry::point<double> pt(0, 0);
CHECK(mapnik::geometry::is_valid(pt)); CHECK(mapnik::geometry::is_valid(pt));
std::string message; std::string message;
@ -31,7 +32,8 @@ SECTION("point") {
CHECK(failure == boost::geometry::no_failure); CHECK(failure == boost::geometry::no_failure);
} }
SECTION("point -- geometry object") { SECTION("point -- geometry object")
{
mapnik::geometry::point<double> pt(0, 0); mapnik::geometry::point<double> pt(0, 0);
mapnik::geometry::geometry<double> geom(pt); mapnik::geometry::geometry<double> geom(pt);
CHECK(mapnik::geometry::is_valid(geom)); CHECK(mapnik::geometry::is_valid(geom));
@ -45,7 +47,8 @@ SECTION("point -- geometry object") {
#if BOOST_VERSION < 106000 #if BOOST_VERSION < 106000
SECTION("point unitialized") { SECTION("point unitialized")
{
mapnik::geometry::point<double> pt2; mapnik::geometry::point<double> pt2;
CHECK(mapnik::geometry::is_valid(pt2)); CHECK(mapnik::geometry::is_valid(pt2));
std::string message2; std::string message2;
@ -59,8 +62,10 @@ SECTION("point unitialized") {
#if BOOST_VERSION >= 106000 #if BOOST_VERSION >= 106000
SECTION("point NaN") { SECTION("point NaN")
mapnik::geometry::point<double> pt(std::numeric_limits<double>::quiet_NaN(),std::numeric_limits<double>::quiet_NaN()); {
mapnik::geometry::point<double> pt(std::numeric_limits<double>::quiet_NaN(),
std::numeric_limits<double>::quiet_NaN());
CHECK(std::isnan(pt.x)); CHECK(std::isnan(pt.x));
CHECK(std::isnan(pt.y)); CHECK(std::isnan(pt.y));
CHECK(!mapnik::geometry::is_valid(pt)); CHECK(!mapnik::geometry::is_valid(pt));
@ -72,8 +77,10 @@ SECTION("point NaN") {
CHECK(failure == boost::geometry::failure_invalid_coordinate); CHECK(failure == boost::geometry::failure_invalid_coordinate);
} }
SECTION("point Infinity") { SECTION("point Infinity")
mapnik::geometry::point<double> pt(std::numeric_limits<double>::infinity(),std::numeric_limits<double>::infinity()); {
mapnik::geometry::point<double> pt(std::numeric_limits<double>::infinity(),
std::numeric_limits<double>::infinity());
CHECK(std::isinf(pt.x)); CHECK(std::isinf(pt.x));
CHECK(std::isinf(pt.y)); CHECK(std::isinf(pt.y));
CHECK(!mapnik::geometry::is_valid(pt)); CHECK(!mapnik::geometry::is_valid(pt));
@ -90,8 +97,10 @@ SECTION("point Infinity") {
// This is funky that boost geometry is_valid does not check for NAN when dealing with a point // This is funky that boost geometry is_valid does not check for NAN when dealing with a point
// this test is here in case the logic ever changes // this test is here in case the logic ever changes
// Bug report on this: https://svn.boost.org/trac/boost/ticket/11711 // Bug report on this: https://svn.boost.org/trac/boost/ticket/11711
SECTION("point NaN") { SECTION("point NaN")
mapnik::geometry::point<double> pt(std::numeric_limits<double>::quiet_NaN(),std::numeric_limits<double>::quiet_NaN()); {
mapnik::geometry::point<double> pt(std::numeric_limits<double>::quiet_NaN(),
std::numeric_limits<double>::quiet_NaN());
CHECK(std::isnan(pt.x)); CHECK(std::isnan(pt.x));
CHECK(std::isnan(pt.y)); CHECK(std::isnan(pt.y));
CHECK(mapnik::geometry::is_valid(pt)); CHECK(mapnik::geometry::is_valid(pt));
@ -106,8 +115,10 @@ SECTION("point NaN") {
// This is funky that boost geometry is_valid does not check for infinity when dealing with a point // This is funky that boost geometry is_valid does not check for infinity when dealing with a point
// this test is here in case the logic ever changes // this test is here in case the logic ever changes
// Bug report on this: https://svn.boost.org/trac/boost/ticket/11711 // Bug report on this: https://svn.boost.org/trac/boost/ticket/11711
SECTION("point Infinity") { SECTION("point Infinity")
mapnik::geometry::point<double> pt(std::numeric_limits<double>::infinity(),std::numeric_limits<double>::infinity()); {
mapnik::geometry::point<double> pt(std::numeric_limits<double>::infinity(),
std::numeric_limits<double>::infinity());
CHECK(std::isinf(pt.x)); CHECK(std::isinf(pt.x));
CHECK(std::isinf(pt.y)); CHECK(std::isinf(pt.y));
CHECK(mapnik::geometry::is_valid(pt)); CHECK(mapnik::geometry::is_valid(pt));
@ -121,7 +132,8 @@ SECTION("point Infinity") {
#endif // BOOST_VERSION >= 1.60 #endif // BOOST_VERSION >= 1.60
SECTION("multi point") { SECTION("multi point")
{
mapnik::geometry::multi_point<double> mpt; mapnik::geometry::multi_point<double> mpt;
mpt.emplace_back(0, 0); mpt.emplace_back(0, 0);
mpt.emplace_back(1, 1); mpt.emplace_back(1, 1);
@ -134,7 +146,8 @@ SECTION("multi point") {
CHECK(failure == boost::geometry::no_failure); CHECK(failure == boost::geometry::no_failure);
} }
SECTION("multi point empty") { SECTION("multi point empty")
{
mapnik::geometry::multi_point<double> mpt; mapnik::geometry::multi_point<double> mpt;
CHECK(mapnik::geometry::is_valid(mpt)); CHECK(mapnik::geometry::is_valid(mpt));
std::string message; std::string message;
@ -145,8 +158,8 @@ SECTION("multi point empty") {
CHECK(failure == boost::geometry::no_failure); CHECK(failure == boost::geometry::no_failure);
} }
SECTION("line_string")
SECTION("line_string") { {
mapnik::geometry::line_string<double> line; mapnik::geometry::line_string<double> line;
line.emplace_back(0, 0); line.emplace_back(0, 0);
line.emplace_back(1, 1); line.emplace_back(1, 1);
@ -160,7 +173,8 @@ SECTION("line_string") {
} }
// This shouldn't fail -- test added in case logic ever changes // This shouldn't fail -- test added in case logic ever changes
SECTION("line_string repeated points") { SECTION("line_string repeated points")
{
mapnik::geometry::line_string<double> line; mapnik::geometry::line_string<double> line;
line.emplace_back(0, 0); line.emplace_back(0, 0);
line.emplace_back(1, 1); line.emplace_back(1, 1);
@ -175,7 +189,8 @@ SECTION("line_string repeated points") {
CHECK(failure == boost::geometry::no_failure); CHECK(failure == boost::geometry::no_failure);
} }
SECTION("line_string empty") { SECTION("line_string empty")
{
mapnik::geometry::line_string<double> line; mapnik::geometry::line_string<double> line;
CHECK(!mapnik::geometry::is_valid(line)); CHECK(!mapnik::geometry::is_valid(line));
std::string message; std::string message;
@ -186,7 +201,8 @@ SECTION("line_string empty") {
CHECK(failure == boost::geometry::failure_few_points); CHECK(failure == boost::geometry::failure_few_points);
} }
SECTION("multi_line_string") { SECTION("multi_line_string")
{
mapnik::geometry::line_string<double> line1; mapnik::geometry::line_string<double> line1;
line1.emplace_back(0, 0); line1.emplace_back(0, 0);
line1.emplace_back(1, 1); line1.emplace_back(1, 1);
@ -205,7 +221,8 @@ SECTION("multi_line_string") {
CHECK(failure == boost::geometry::no_failure); CHECK(failure == boost::geometry::no_failure);
} }
SECTION("multi_line_string empty") { SECTION("multi_line_string empty")
{
mapnik::geometry::multi_line_string<double> lines; mapnik::geometry::multi_line_string<double> lines;
CHECK(mapnik::geometry::is_valid(lines)); CHECK(mapnik::geometry::is_valid(lines));
std::string message; std::string message;
@ -216,7 +233,8 @@ SECTION("multi_line_string empty") {
CHECK(failure == boost::geometry::no_failure); CHECK(failure == boost::geometry::no_failure);
} }
SECTION("polygon") { SECTION("polygon")
{
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
mapnik::geometry::linear_ring<double> ring; mapnik::geometry::linear_ring<double> ring;
ring.emplace_back(0, 0); ring.emplace_back(0, 0);
@ -234,7 +252,8 @@ SECTION("polygon") {
CHECK(failure == boost::geometry::no_failure); CHECK(failure == boost::geometry::no_failure);
} }
SECTION("polygon invalid winding order") { SECTION("polygon invalid winding order")
{
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
mapnik::geometry::linear_ring<double> ring; mapnik::geometry::linear_ring<double> ring;
ring.emplace_back(0, 0); ring.emplace_back(0, 0);
@ -253,7 +272,8 @@ SECTION("polygon invalid winding order") {
} }
// repeated points are not considered invalid in a polygon // repeated points are not considered invalid in a polygon
SECTION("polygon 2 repeated points") { SECTION("polygon 2 repeated points")
{
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
mapnik::geometry::linear_ring<double> ring; mapnik::geometry::linear_ring<double> ring;
ring.emplace_back(0, 0); ring.emplace_back(0, 0);
@ -272,7 +292,8 @@ SECTION("polygon 2 repeated points") {
CHECK(failure == boost::geometry::no_failure); CHECK(failure == boost::geometry::no_failure);
} }
// repeated points are not considered invalid in a polygon // repeated points are not considered invalid in a polygon
SECTION("polygon 3 repeated points") { SECTION("polygon 3 repeated points")
{
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
mapnik::geometry::linear_ring<double> ring; mapnik::geometry::linear_ring<double> ring;
ring.emplace_back(0, 0); ring.emplace_back(0, 0);
@ -292,7 +313,8 @@ SECTION("polygon 3 repeated points") {
CHECK(failure == boost::geometry::no_failure); CHECK(failure == boost::geometry::no_failure);
} }
SECTION("polygon that is empty") { SECTION("polygon that is empty")
{
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
poly.emplace_back(); poly.emplace_back();
CHECK(!mapnik::geometry::is_valid(poly)); CHECK(!mapnik::geometry::is_valid(poly));
@ -304,7 +326,8 @@ SECTION("polygon that is empty") {
CHECK(failure == boost::geometry::failure_few_points); CHECK(failure == boost::geometry::failure_few_points);
} }
SECTION("polygon with spike") { SECTION("polygon with spike")
{
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
mapnik::geometry::linear_ring<double> ring; mapnik::geometry::linear_ring<double> ring;
ring.emplace_back(0, 0); ring.emplace_back(0, 0);
@ -324,7 +347,8 @@ SECTION("polygon with spike") {
CHECK(failure == boost::geometry::failure_spikes); CHECK(failure == boost::geometry::failure_spikes);
} }
SECTION("polygon with hole") { SECTION("polygon with hole")
{
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
mapnik::geometry::linear_ring<double> ring; mapnik::geometry::linear_ring<double> ring;
ring.emplace_back(0, 0); ring.emplace_back(0, 0);
@ -349,7 +373,8 @@ SECTION("polygon with hole") {
CHECK(failure == boost::geometry::no_failure); CHECK(failure == boost::geometry::no_failure);
} }
SECTION("polygon with empty hole") { SECTION("polygon with empty hole")
{
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
mapnik::geometry::linear_ring<double> ring; mapnik::geometry::linear_ring<double> ring;
ring.emplace_back(0, 0); ring.emplace_back(0, 0);
@ -369,8 +394,8 @@ SECTION("polygon with empty hole") {
CHECK(failure == boost::geometry::failure_few_points); CHECK(failure == boost::geometry::failure_few_points);
} }
SECTION("polygon with hole with invalid winding order")
SECTION("polygon with hole with invalid winding order") { {
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
mapnik::geometry::linear_ring<double> ring; mapnik::geometry::linear_ring<double> ring;
ring.emplace_back(0, 0); ring.emplace_back(0, 0);
@ -395,7 +420,8 @@ SECTION("polygon with hole with invalid winding order") {
CHECK(failure == boost::geometry::failure_wrong_orientation); CHECK(failure == boost::geometry::failure_wrong_orientation);
} }
SECTION("multi polygon") { SECTION("multi polygon")
{
mapnik::geometry::multi_polygon<double> mp; mapnik::geometry::multi_polygon<double> mp;
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
mapnik::geometry::linear_ring<double> ring; mapnik::geometry::linear_ring<double> ring;
@ -424,7 +450,8 @@ SECTION("multi polygon") {
CHECK(failure == boost::geometry::no_failure); CHECK(failure == boost::geometry::no_failure);
} }
SECTION("multi polygon with hole") { SECTION("multi polygon with hole")
{
mapnik::geometry::multi_polygon<double> mp; mapnik::geometry::multi_polygon<double> mp;
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
mapnik::geometry::linear_ring<double> ring; mapnik::geometry::linear_ring<double> ring;
@ -467,7 +494,8 @@ SECTION("multi polygon with hole") {
CHECK(failure == boost::geometry::no_failure); CHECK(failure == boost::geometry::no_failure);
} }
SECTION("multi polygon empty") { SECTION("multi polygon empty")
{
mapnik::geometry::multi_polygon<double> mp; mapnik::geometry::multi_polygon<double> mp;
CHECK(mapnik::geometry::is_valid(mp)); CHECK(mapnik::geometry::is_valid(mp));
std::string message; std::string message;
@ -479,5 +507,4 @@ SECTION("multi polygon empty") {
} }
#endif // BOOST_VERSION >= 1.58 #endif // BOOST_VERSION >= 1.58
} }

View file

@ -7,9 +7,10 @@
#include <mapnik/proj_transform.hpp> #include <mapnik/proj_transform.hpp>
#include <mapnik/geometry/reprojection.hpp> #include <mapnik/geometry/reprojection.hpp>
TEST_CASE("geometry reprojection") { TEST_CASE("geometry reprojection")
{
SECTION("test_projection_4326_3857 - Empty Geometry Object") { SECTION("test_projection_4326_3857 - Empty Geometry Object")
{
using namespace mapnik::geometry; using namespace mapnik::geometry;
mapnik::projection source("epsg:4326"); mapnik::projection source("epsg:4326");
mapnik::projection dest("epsg:3857"); mapnik::projection dest("epsg:3857");
@ -35,7 +36,8 @@ SECTION("test_projection_4326_3857 - Empty Geometry Object") {
} }
} // End Section } // End Section
SECTION("test_projection_4326_3857 - Empty Geometry in Geometry Variant") { SECTION("test_projection_4326_3857 - Empty Geometry in Geometry Variant")
{
using namespace mapnik::geometry; using namespace mapnik::geometry;
mapnik::projection source("epsg:4326"); mapnik::projection source("epsg:4326");
mapnik::projection dest("epsg:3857"); mapnik::projection dest("epsg:3857");
@ -64,7 +66,8 @@ SECTION("test_projection_4326_3857 - Empty Geometry in Geometry Variant") {
} }
} // End Section } // End Section
SECTION("test_projection_4326_3857 - Point Geometry Object") { SECTION("test_projection_4326_3857 - Point Geometry Object")
{
using namespace mapnik::geometry; using namespace mapnik::geometry;
mapnik::projection source("epsg:4326"); mapnik::projection source("epsg:4326");
mapnik::projection dest("epsg:3857"); mapnik::projection dest("epsg:3857");
@ -117,7 +120,8 @@ SECTION("test_projection_4326_3857 - Point Geometry Object") {
} }
} // End Section } // End Section
SECTION("test_projection_4326_3857 - Point Geometry Variant Object") { SECTION("test_projection_4326_3857 - Point Geometry Variant Object")
{
using namespace mapnik::geometry; using namespace mapnik::geometry;
mapnik::projection source("epsg:4326"); mapnik::projection source("epsg:4326");
mapnik::projection dest("epsg:3857"); mapnik::projection dest("epsg:3857");
@ -174,7 +178,8 @@ SECTION("test_projection_4326_3857 - Point Geometry Variant Object") {
} }
} // End Section */ } // End Section */
SECTION("test_projection_4326_3857 - Line_String Geometry Object") { SECTION("test_projection_4326_3857 - Line_String Geometry Object")
{
using namespace mapnik::geometry; using namespace mapnik::geometry;
mapnik::projection source("epsg:4326"); mapnik::projection source("epsg:4326");
mapnik::projection dest("epsg:3857"); mapnik::projection dest("epsg:3857");
@ -239,7 +244,8 @@ SECTION("test_projection_4326_3857 - Line_String Geometry Object") {
} }
} // End Section } // End Section
SECTION("test_projection_4326_3857 - Line_String Geometry Variant Object") { SECTION("test_projection_4326_3857 - Line_String Geometry Variant Object")
{
using namespace mapnik::geometry; using namespace mapnik::geometry;
mapnik::projection source("epsg:4326"); mapnik::projection source("epsg:4326");
mapnik::projection dest("epsg:3857"); mapnik::projection dest("epsg:3857");
@ -314,7 +320,8 @@ SECTION("test_projection_4326_3857 - Line_String Geometry Variant Object") {
} }
} // End Section } // End Section
SECTION("test_projection_4326_3857 - Polygon Geometry Object") { SECTION("test_projection_4326_3857 - Polygon Geometry Object")
{
using namespace mapnik::geometry; using namespace mapnik::geometry;
mapnik::projection source("epsg:4326"); mapnik::projection source("epsg:4326");
mapnik::projection dest("epsg:3857"); mapnik::projection dest("epsg:3857");
@ -409,7 +416,8 @@ SECTION("test_projection_4326_3857 - Polygon Geometry Object") {
} }
} // End Section } // End Section
SECTION("test_projection_4326_3857 - Polygon Geometry Variant Object") { SECTION("test_projection_4326_3857 - Polygon Geometry Variant Object")
{
using namespace mapnik::geometry; using namespace mapnik::geometry;
mapnik::projection source("epsg:4326"); mapnik::projection source("epsg:4326");
mapnik::projection dest("epsg:3857"); mapnik::projection dest("epsg:3857");
@ -501,7 +509,8 @@ SECTION("test_projection_4326_3857 - Polygon Geometry Variant Object") {
} }
} // END SECTION } // END SECTION
SECTION("test_projection_4326_3857 - Multi_Point Geometry Object") { SECTION("test_projection_4326_3857 - Multi_Point Geometry Object")
{
using namespace mapnik::geometry; using namespace mapnik::geometry;
mapnik::projection source("epsg:4326"); mapnik::projection source("epsg:4326");
mapnik::projection dest("epsg:3857"); mapnik::projection dest("epsg:3857");
@ -566,7 +575,8 @@ SECTION("test_projection_4326_3857 - Multi_Point Geometry Object") {
} }
} // End Section } // End Section
SECTION("test_projection_4326_3857 - Multi_Point Geometry Variant Object") { SECTION("test_projection_4326_3857 - Multi_Point Geometry Variant Object")
{
using namespace mapnik::geometry; using namespace mapnik::geometry;
mapnik::projection source("epsg:4326"); mapnik::projection source("epsg:4326");
mapnik::projection dest("epsg:3857"); mapnik::projection dest("epsg:3857");
@ -641,7 +651,8 @@ SECTION("test_projection_4326_3857 - Multi_Point Geometry Variant Object") {
} }
} // End Section } // End Section
SECTION("test_projection_4326_3857 - Multi_Line_String Geometry Object") { SECTION("test_projection_4326_3857 - Multi_Line_String Geometry Object")
{
using namespace mapnik::geometry; using namespace mapnik::geometry;
mapnik::projection source("epsg:4326"); mapnik::projection source("epsg:4326");
mapnik::projection dest("epsg:3857"); mapnik::projection dest("epsg:3857");
@ -718,7 +729,8 @@ SECTION("test_projection_4326_3857 - Multi_Line_String Geometry Object") {
} }
} // End Section } // End Section
SECTION("test_projection_4326_3857 - Multi_Line_String Geometry Variant Object") { SECTION("test_projection_4326_3857 - Multi_Line_String Geometry Variant Object")
{
using namespace mapnik::geometry; using namespace mapnik::geometry;
mapnik::projection source("epsg:4326"); mapnik::projection source("epsg:4326");
mapnik::projection dest("epsg:3857"); mapnik::projection dest("epsg:3857");
@ -797,7 +809,8 @@ SECTION("test_projection_4326_3857 - Multi_Line_String Geometry Variant Object")
} }
} // End Section } // End Section
SECTION("test_projection_4326_3857 - Multi_Polygon Geometry Object") { SECTION("test_projection_4326_3857 - Multi_Polygon Geometry Object")
{
using namespace mapnik::geometry; using namespace mapnik::geometry;
mapnik::projection source("epsg:4326"); mapnik::projection source("epsg:4326");
mapnik::projection dest("epsg:3857"); mapnik::projection dest("epsg:3857");
@ -896,7 +909,8 @@ SECTION("test_projection_4326_3857 - Multi_Polygon Geometry Object") {
} }
} // End Section } // End Section
SECTION("test_projection_4326_3857 - Multi_Polygon Geometry Variant Object") { SECTION("test_projection_4326_3857 - Multi_Polygon Geometry Variant Object")
{
using namespace mapnik::geometry; using namespace mapnik::geometry;
mapnik::projection source("epsg:4326"); mapnik::projection source("epsg:4326");
mapnik::projection dest("epsg:3857"); mapnik::projection dest("epsg:3857");
@ -991,7 +1005,8 @@ SECTION("test_projection_4326_3857 - Multi_Polygon Geometry Variant Object") {
} }
} // END SECTION } // END SECTION
SECTION("test_projection_4326_3857 - Geometry Collection Object") { SECTION("test_projection_4326_3857 - Geometry Collection Object")
{
using namespace mapnik::geometry; using namespace mapnik::geometry;
mapnik::projection source("epsg:4326"); mapnik::projection source("epsg:4326");
mapnik::projection dest("epsg:3857"); mapnik::projection dest("epsg:3857");
@ -1090,7 +1105,8 @@ SECTION("test_projection_4326_3857 - Geometry Collection Object") {
} }
} // End Section } // End Section
SECTION("test_projection_4326_3857 - Geometry Collection Variant Object") { SECTION("test_projection_4326_3857 - Geometry Collection Variant Object")
{
using namespace mapnik::geometry; using namespace mapnik::geometry;
mapnik::projection source("epsg:4326"); mapnik::projection source("epsg:4326");
mapnik::projection dest("epsg:3857"); mapnik::projection dest("epsg:3857");
@ -1186,7 +1202,8 @@ SECTION("test_projection_4326_3857 - Geometry Collection Variant Object") {
} // END SECTION } // END SECTION
#ifdef MAPNIK_USE_PROJ #ifdef MAPNIK_USE_PROJ
SECTION("test_projection_4269_3857 - Line_String Geometry Object") { SECTION("test_projection_4269_3857 - Line_String Geometry Object")
{
using namespace mapnik::geometry; using namespace mapnik::geometry;
mapnik::projection source("epsg:4269"); mapnik::projection source("epsg:4269");
mapnik::projection dest("epsg:3857"); mapnik::projection dest("epsg:3857");
@ -1251,8 +1268,8 @@ SECTION("test_projection_4269_3857 - Line_String Geometry Object") {
} }
} // End Section } // End Section
SECTION("test_projection_4269_3857 - Point Geometry Object")
SECTION("test_projection_4269_3857 - Point Geometry Object") { {
using namespace mapnik::geometry; using namespace mapnik::geometry;
mapnik::projection source("epsg:4269"); mapnik::projection source("epsg:4269");
mapnik::projection dest("epsg:3857"); mapnik::projection dest("epsg:3857");

View file

@ -10,9 +10,10 @@
#include <mapnik/proj_strategy.hpp> #include <mapnik/proj_strategy.hpp>
#include <mapnik/view_strategy.hpp> #include <mapnik/view_strategy.hpp>
TEST_CASE("geometry strategy tests")
TEST_CASE("geometry strategy tests") { {
SECTION("proj and view strategy") { SECTION("proj and view strategy")
{
using namespace mapnik::geometry; using namespace mapnik::geometry;
mapnik::box2d<double> e(-20037508.342789, -20037508.342789, 20037508.342789, 20037508.342789); mapnik::box2d<double> e(-20037508.342789, -20037508.342789, 20037508.342789, 20037508.342789);
mapnik::view_transform vt(256, 256, e); mapnik::view_transform vt(256, 256, e);
@ -37,7 +38,6 @@ SECTION("proj and view strategy") {
point<double> r1(58.6287, 100.945); point<double> r1(58.6287, 100.945);
point<double> p3 = transform<double>(p1, vs); point<double> p3 = transform<double>(p1, vs);
assert_g_equal(r1, p3); assert_g_equal(r1, p3);
} }
{ {
// Test next that view_strategy works as single process in strategy group // Test next that view_strategy works as single process in strategy group
@ -47,7 +47,6 @@ SECTION("proj and view strategy") {
sg_type sg(vs); sg_type sg(vs);
point<double> p3 = transform<double>(p1, sg); point<double> p3 = transform<double>(p1, sg);
assert_g_equal(r1, p3); assert_g_equal(r1, p3);
} }
{ {
// Test that both work grouped together in strategy group // Test that both work grouped together in strategy group
@ -83,7 +82,8 @@ SECTION("proj and view strategy") {
{ {
// Test with scaling as well. This would be like projection from 4326 to a vector tile. // Test with scaling as well. This would be like projection from 4326 to a vector tile.
mapnik::geometry::scale_rounding_strategy ss(16); mapnik::geometry::scale_rounding_strategy ss(16);
using sg_type = strategy_group<mapnik::proj_strategy, mapnik::view_strategy, mapnik::geometry::scale_rounding_strategy >; using sg_type =
strategy_group<mapnik::proj_strategy, mapnik::view_strategy, mapnik::geometry::scale_rounding_strategy>;
sg_type sg(ps, vs, ss); sg_type sg(ps, vs, ss);
geometry<double> p1(point<double>(-97.553098, 35.523105)); geometry<double> p1(point<double>(-97.553098, 35.523105));
point<std::int64_t> r1(938, 1615); point<std::int64_t> r1(938, 1615);
@ -95,7 +95,8 @@ SECTION("proj and view strategy") {
{ {
// Test the entire process in reverse! This would be like converting a vector tile coordinate to 4326. // Test the entire process in reverse! This would be like converting a vector tile coordinate to 4326.
mapnik::geometry::scale_strategy ss(1.0 / 16.0); mapnik::geometry::scale_strategy ss(1.0 / 16.0);
using sg_type = strategy_group_first<mapnik::geometry::scale_strategy, mapnik::unview_strategy, mapnik::proj_strategy >; using sg_type =
strategy_group_first<mapnik::geometry::scale_strategy, mapnik::unview_strategy, mapnik::proj_strategy>;
sg_type sg(ss, uvs, ps_rev); sg_type sg(ss, uvs, ps_rev);
geometry<std::int64_t> p1(point<std::int64_t>(938, 1615)); geometry<std::int64_t> p1(point<std::int64_t>(938, 1615));
point<double> r1(-97.5586, 35.5322); point<double> r1(-97.5586, 35.5322);
@ -107,7 +108,8 @@ SECTION("proj and view strategy") {
{ {
// Test with scaling + offset as well. This would be like projection from 4326 to a vector tile. // Test with scaling + offset as well. This would be like projection from 4326 to a vector tile.
mapnik::geometry::scale_rounding_strategy ss(16, 20); mapnik::geometry::scale_rounding_strategy ss(16, 20);
using sg_type = strategy_group<mapnik::proj_strategy, mapnik::view_strategy, mapnik::geometry::scale_rounding_strategy >; using sg_type =
strategy_group<mapnik::proj_strategy, mapnik::view_strategy, mapnik::geometry::scale_rounding_strategy>;
sg_type sg(ps, vs, ss); sg_type sg(ps, vs, ss);
geometry<double> p1(point<double>(-97.553098, 35.523105)); geometry<double> p1(point<double>(-97.553098, 35.523105));
point<std::int64_t> r1(958, 1635); point<std::int64_t> r1(958, 1635);
@ -117,9 +119,11 @@ SECTION("proj and view strategy") {
assert_g_equal(r1, p3); assert_g_equal(r1, p3);
} }
{ {
// Test the entire scaling plus offset in reverse process in reverse! This would be like converting a vector tile coordinate to 4326. // Test the entire scaling plus offset in reverse process in reverse! This would be like converting a vector
// tile coordinate to 4326.
mapnik::geometry::scale_strategy ss(1.0 / 16.0, -20.0 / 16.0); mapnik::geometry::scale_strategy ss(1.0 / 16.0, -20.0 / 16.0);
using sg_type = strategy_group_first<mapnik::geometry::scale_strategy, mapnik::unview_strategy, mapnik::proj_strategy >; using sg_type =
strategy_group_first<mapnik::geometry::scale_strategy, mapnik::unview_strategy, mapnik::proj_strategy>;
sg_type sg(ss, uvs, ps_rev); sg_type sg(ss, uvs, ps_rev);
geometry<std::int64_t> p1(point<std::int64_t>(958, 1635)); geometry<std::int64_t> p1(point<std::int64_t>(958, 1635));
point<double> r1(-97.5586, 35.5322); point<double> r1(-97.5586, 35.5322);
@ -131,7 +135,8 @@ SECTION("proj and view strategy") {
} // END SECTION } // END SECTION
SECTION("scaling strategies - double to double") { SECTION("scaling strategies - double to double")
{
using namespace mapnik::geometry; using namespace mapnik::geometry;
{ {
@ -158,7 +163,8 @@ SECTION("scaling strategies - double to double") {
} // END SECTION } // END SECTION
SECTION("scaling strategies - double to int64") { SECTION("scaling strategies - double to int64")
{
using namespace mapnik::geometry; using namespace mapnik::geometry;
{ {

View file

@ -2,8 +2,8 @@
#include <mapnik/geometry/envelope.hpp> #include <mapnik/geometry/envelope.hpp>
#include <mapnik/geometry/envelope_impl.hpp> #include <mapnik/geometry/envelope_impl.hpp>
namespace mapnik {
namespace mapnik { namespace geometry { namespace geometry {
// instantiate types required by geometry_envelope_test // instantiate types required by geometry_envelope_test
template mapnik::box2d<int> envelope(geometry<int> const& geom); template mapnik::box2d<int> envelope(geometry<int> const& geom);
template mapnik::box2d<float> envelope(geometry<float> const& geom); template mapnik::box2d<float> envelope(geometry<float> const& geom);
@ -12,4 +12,5 @@ template mapnik::box2d<float> envelope(polygon<float> const& geom);
template mapnik::box2d<int> envelope(geometry_collection<int> const& geom); template mapnik::box2d<int> envelope(geometry_collection<int> const& geom);
template mapnik::box2d<float> envelope(geometry_collection<float> const& geom); template mapnik::box2d<float> envelope(geometry_collection<float> const& geom);
}} } // namespace geometry
} // namespace mapnik

View file

@ -2,15 +2,13 @@
#include <mapnik/grid_vertex_converter.hpp> #include <mapnik/grid_vertex_converter.hpp>
TEST_CASE("spiral_iterator") { TEST_CASE("spiral_iterator")
{
SECTION("sprial 3x3") { SECTION("sprial 3x3")
{
mapnik::geometry::spiral_iterator si(3); mapnik::geometry::spiral_iterator si(3);
const mapnik::geometry::point<int> points[] = { const mapnik::geometry::point<int> points[] =
{ 0, 0 }, { 1, 0 }, { 1, -1 }, {{0, 0}, {1, 0}, {1, -1}, {0, -1}, {-1, -1}, {-1, 0}, {-1, 1}, {0, 1}, {1, 1}};
{ 0, -1 }, { -1, -1 }, { -1, 0 },
{ -1, 1 }, { 0, 1 }, { 1, 1 } };
const std::size_t points_size = std::extent<decltype(points)>::value; const std::size_t points_size = std::extent<decltype(points)>::value;
@ -29,13 +27,12 @@ SECTION("sprial 3x3") {
CHECK(index == points_size); CHECK(index == points_size);
} }
} }
TEST_CASE("grid_vertex_converter") { TEST_CASE("grid_vertex_converter")
{
SECTION("empty polygon") { SECTION("empty polygon")
{
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
using path_type = mapnik::geometry::polygon_vertex_adapter<double>; using path_type = mapnik::geometry::polygon_vertex_adapter<double>;
path_type path(poly); path_type path(poly);
@ -46,11 +43,10 @@ SECTION("empty polygon") {
unsigned cmd = gvc.vertex(&x, &y); unsigned cmd = gvc.vertex(&x, &y);
CHECK(cmd == mapnik::SEG_END); CHECK(cmd == mapnik::SEG_END);
} }
SECTION("empty polygon exterior ring") { SECTION("empty polygon exterior ring")
{
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
poly.emplace_back(); poly.emplace_back();
@ -63,11 +59,10 @@ SECTION("empty polygon exterior ring") {
unsigned cmd = gvc.vertex(&x, &y); unsigned cmd = gvc.vertex(&x, &y);
CHECK(cmd == mapnik::SEG_END); CHECK(cmd == mapnik::SEG_END);
} }
SECTION("grid of a square") { SECTION("grid of a square")
{
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
poly.emplace_back(); poly.emplace_back();
auto& exterior_ring = poly.front(); auto& exterior_ring = poly.front();
@ -83,19 +78,11 @@ SECTION("grid of a square") {
converter_type gvc(path, 3.0, 3.0, 1.0); converter_type gvc(path, 3.0, 3.0, 1.0);
const mapnik::geometry::point<double> points[] = { const mapnik::geometry::point<double> points[] = {
{ 0, 0 }, { 3, 0 }, { 3, 3 }, { 0, 3 }, {0, 0}, {3, 0}, {3, 3}, {0, 3}, {-3, 3}, {-3, 0}, {-3, -3}, {0, -3}, {3, -3}, {6, -3},
{ -3, 3 }, { -3, 0 }, { -3, -3 }, { 0, -3 }, {6, 0}, {6, 3}, {6, 6}, {3, 6}, {0, 6}, {-3, 6}, {-6, 6}, {-6, 3}, {-6, 0}, {-6, -3},
{ 3, -3 }, { 6, -3 }, { 6, 0 }, { 6, 3 }, {-6, -6}, {-3, -6}, {0, -6}, {3, -6}, {6, -6}, {9, -6}, {9, -3}, {9, 0}, {9, 3}, {9, 6},
{ 6, 6 }, { 3, 6 }, { 0, 6 }, { -3, 6 }, {9, 9}, {6, 9}, {3, 9}, {0, 9}, {-3, 9}, {-6, 9}, {-9, 9}, {-9, 6}, {-9, 3}, {-9, 0},
{ -6, 6 }, { -6, 3 }, { -6, 0 }, { -6, -3 }, {-9, -3}, {-9, -6}, {-9, -9}, {-6, -9}, {-3, -9}, {0, -9}, {3, -9}, {6, -9}, {9, -9}};
{ -6, -6 }, { -3, -6 }, { 0, -6 }, { 3, -6 },
{ 6, -6 }, { 9, -6 }, { 9, -3 }, { 9, 0 },
{ 9, 3 }, { 9, 6 }, { 9, 9 }, { 6, 9 },
{ 3, 9 }, { 0, 9 }, { -3, 9 }, { -6, 9 },
{ -9, 9 }, { -9, 6 }, { -9, 3 }, { -9, 0 },
{ -9, -3 }, { -9, -6 }, { -9, -9 }, { -6, -9 },
{ -3, -9 }, { 0, -9 }, { 3, -9 }, { 6, -9 },
{ 9, -9 } };
const std::size_t points_size = std::extent<decltype(points)>::value; const std::size_t points_size = std::extent<decltype(points)>::value;
double x, y; double x, y;
@ -116,6 +103,4 @@ SECTION("grid of a square") {
CHECK(index == points_size); CHECK(index == points_size);
CHECK(cmd == mapnik::SEG_END); CHECK(cmd == mapnik::SEG_END);
} }
} }

View file

@ -2,18 +2,18 @@
#include <mapnik/geometry/interior.hpp> #include <mapnik/geometry/interior.hpp>
TEST_CASE("polygon interior") { TEST_CASE("polygon interior")
{
SECTION("empty polygon") { SECTION("empty polygon")
{
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
mapnik::geometry::point<double> pt; mapnik::geometry::point<double> pt;
CHECK(!mapnik::geometry::interior(poly, 1.0, pt)); CHECK(!mapnik::geometry::interior(poly, 1.0, pt));
} }
SECTION("empty exterior ring") { SECTION("empty exterior ring")
{
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
poly.emplace_back(); poly.emplace_back();
@ -22,8 +22,8 @@ SECTION("empty exterior ring") {
CHECK(!mapnik::geometry::interior(poly, 1.0, pt)); CHECK(!mapnik::geometry::interior(poly, 1.0, pt));
} }
SECTION("interior of a square") { SECTION("interior of a square")
{
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
poly.emplace_back(); poly.emplace_back();
auto& exterior_ring = poly.front(); auto& exterior_ring = poly.front();
@ -39,5 +39,4 @@ SECTION("interior of a square") {
CHECK(pt.x == Approx(0)); CHECK(pt.x == Approx(0));
CHECK(pt.y == Approx(0)); CHECK(pt.y == Approx(0));
} }
} }

View file

@ -3,8 +3,8 @@
#include <mapnik/geometry.hpp> #include <mapnik/geometry.hpp>
#include <mapnik/util/is_clockwise.hpp> #include <mapnik/util/is_clockwise.hpp>
TEST_CASE("Ring is_clockwise") { TEST_CASE("Ring is_clockwise")
{
// Input is rather thin triangle to test precision issues aren't getting in the way. // Input is rather thin triangle to test precision issues aren't getting in the way.
SECTION("Clockwise") SECTION("Clockwise")
{ {

View file

@ -2,16 +2,16 @@
#include <mapnik/geometry/is_empty.hpp> #include <mapnik/geometry/is_empty.hpp>
TEST_CASE("geometry is_empty") { TEST_CASE("geometry is_empty")
{
SECTION("empty geometry") { SECTION("empty geometry")
{
mapnik::geometry::geometry_empty geom; mapnik::geometry::geometry_empty geom;
REQUIRE(mapnik::geometry::is_empty(geom)); REQUIRE(mapnik::geometry::is_empty(geom));
} }
SECTION("geometry collection") { SECTION("geometry collection")
{
{ {
mapnik::geometry::geometry_collection<double> geom; mapnik::geometry::geometry_collection<double> geom;
REQUIRE(mapnik::geometry::is_empty(geom)); REQUIRE(mapnik::geometry::is_empty(geom));
@ -24,14 +24,14 @@ SECTION("geometry collection") {
} }
} }
SECTION("point") { SECTION("point")
{
mapnik::geometry::point<double> pt(10, 10); mapnik::geometry::point<double> pt(10, 10);
REQUIRE(!mapnik::geometry::is_empty(pt)); REQUIRE(!mapnik::geometry::is_empty(pt));
} }
SECTION("linestring") { SECTION("linestring")
{
{ {
mapnik::geometry::line_string<double> line; mapnik::geometry::line_string<double> line;
REQUIRE(mapnik::geometry::is_empty(line)); REQUIRE(mapnik::geometry::is_empty(line));
@ -45,8 +45,8 @@ SECTION("linestring") {
} }
} }
SECTION("polygon") { SECTION("polygon")
{
{ {
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
REQUIRE(mapnik::geometry::is_empty(poly)); REQUIRE(mapnik::geometry::is_empty(poly));
@ -70,8 +70,8 @@ SECTION("polygon") {
} }
} }
SECTION("multi-point") { SECTION("multi-point")
{
{ {
mapnik::geometry::multi_point<double> geom; mapnik::geometry::multi_point<double> geom;
REQUIRE(mapnik::geometry::is_empty(geom)); REQUIRE(mapnik::geometry::is_empty(geom));
@ -85,8 +85,8 @@ SECTION("multi-point") {
} }
} }
SECTION("multi-linestring") { SECTION("multi-linestring")
{
{ {
mapnik::geometry::multi_line_string<double> geom; mapnik::geometry::multi_line_string<double> geom;
REQUIRE(mapnik::geometry::is_empty(geom)); REQUIRE(mapnik::geometry::is_empty(geom));
@ -99,8 +99,8 @@ SECTION("multi-linestring") {
} }
} }
SECTION("multi-polygon") { SECTION("multi-polygon")
{
{ {
mapnik::geometry::multi_polygon<double> geom; mapnik::geometry::multi_polygon<double> geom;
REQUIRE(mapnik::geometry::is_empty(geom)); REQUIRE(mapnik::geometry::is_empty(geom));

View file

@ -3,18 +3,18 @@
#include <mapnik/geometry/polygon_vertex_processor.hpp> #include <mapnik/geometry/polygon_vertex_processor.hpp>
TEST_CASE("polygon_vertex_processor") { TEST_CASE("polygon_vertex_processor")
{
SECTION("empty polygon") { SECTION("empty polygon")
{
fake_path path = {}; fake_path path = {};
mapnik::geometry::polygon_vertex_processor<double> proc; mapnik::geometry::polygon_vertex_processor<double> proc;
proc.add_path(path); proc.add_path(path);
CHECK(proc.polygon_.size() == 0); CHECK(proc.polygon_.size() == 0);
} }
SECTION("empty outer ring") { SECTION("empty outer ring")
{
fake_path path = {}; fake_path path = {};
path.vertices_.emplace_back(0, 0, mapnik::SEG_CLOSE); path.vertices_.emplace_back(0, 0, mapnik::SEG_CLOSE);
path.rewind(0); path.rewind(0);
@ -25,8 +25,8 @@ SECTION("empty outer ring") {
REQUIRE(proc.polygon_.front().size() == 0); REQUIRE(proc.polygon_.front().size() == 0);
} }
SECTION("empty inner ring") { SECTION("empty inner ring")
{
fake_path path = {}; fake_path path = {};
path.vertices_.emplace_back(-1, -1, mapnik::SEG_MOVETO); path.vertices_.emplace_back(-1, -1, mapnik::SEG_MOVETO);
path.vertices_.emplace_back(1, -1, mapnik::SEG_LINETO); path.vertices_.emplace_back(1, -1, mapnik::SEG_LINETO);
@ -58,5 +58,4 @@ SECTION("empty inner ring") {
CHECK(outer_ring[4].x == Approx(-1)); CHECK(outer_ring[4].x == Approx(-1));
CHECK(outer_ring[4].y == Approx(-1)); CHECK(outer_ring[4].y == Approx(-1));
} }
} }

View file

@ -2,18 +2,18 @@
#include <mapnik/geometry/polylabel.hpp> #include <mapnik/geometry/polylabel.hpp>
TEST_CASE("polylabel") { TEST_CASE("polylabel")
{
SECTION("empty polygon") { SECTION("empty polygon")
{
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
mapnik::geometry::point<double> pt; mapnik::geometry::point<double> pt;
CHECK(!mapnik::geometry::polylabel(poly, 1.0, pt)); CHECK(!mapnik::geometry::polylabel(poly, 1.0, pt));
} }
SECTION("empty exterior ring") { SECTION("empty exterior ring")
{
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
poly.emplace_back(); poly.emplace_back();
@ -22,8 +22,8 @@ SECTION("empty exterior ring") {
CHECK(!mapnik::geometry::polylabel(poly, 1.0, pt)); CHECK(!mapnik::geometry::polylabel(poly, 1.0, pt));
} }
SECTION("polylabel with a square") { SECTION("polylabel with a square")
{
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
poly.emplace_back(); poly.emplace_back();
auto& exterior_ring = poly.front(); auto& exterior_ring = poly.front();
@ -39,5 +39,4 @@ SECTION("polylabel with a square") {
CHECK(pt.x == Approx(0)); CHECK(pt.x == Approx(0));
CHECK(pt.y == Approx(0)); CHECK(pt.y == Approx(0));
} }
} }

View file

@ -2,10 +2,10 @@
#include <mapnik/geometry/remove_empty.hpp> #include <mapnik/geometry/remove_empty.hpp>
TEST_CASE("geometry remove_empty") { TEST_CASE("geometry remove_empty")
{
SECTION("point") { SECTION("point")
{
using geom_type = mapnik::geometry::point<double>; using geom_type = mapnik::geometry::point<double>;
geom_type pt(10, 10); geom_type pt(10, 10);
geom_type pt2 = mapnik::geometry::remove_empty(pt); geom_type pt2 = mapnik::geometry::remove_empty(pt);
@ -13,8 +13,8 @@ SECTION("point") {
REQUIRE(pt.y == pt2.y); REQUIRE(pt.y == pt2.y);
} }
SECTION("multi-linestring") { SECTION("multi-linestring")
{
using geom_type = mapnik::geometry::multi_line_string<double>; using geom_type = mapnik::geometry::multi_line_string<double>;
geom_type geom; geom_type geom;
mapnik::geometry::line_string<double> line; mapnik::geometry::line_string<double> line;
@ -30,8 +30,8 @@ SECTION("multi-linestring") {
REQUIRE(geom2[0].size() == 3); REQUIRE(geom2[0].size() == 3);
} }
SECTION("multi-polygon") { SECTION("multi-polygon")
{
using geom_type = mapnik::geometry::multi_polygon<double>; using geom_type = mapnik::geometry::multi_polygon<double>;
geom_type geom; geom_type geom;
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;

View file

@ -8,10 +8,10 @@
#include <mapnik/color.hpp> #include <mapnik/color.hpp>
#include <mapnik/image_util.hpp> #include <mapnik/image_util.hpp>
TEST_CASE("image class") { TEST_CASE("image class")
{
SECTION("test gray16") { SECTION("test gray16")
{
const mapnik::image_gray16 im(4, 4); const mapnik::image_gray16 im(4, 4);
mapnik::image_gray16 im2(im); mapnik::image_gray16 im2(im);
mapnik::image_gray16 im3(5, 5); mapnik::image_gray16 im3(5, 5);
@ -219,7 +219,6 @@ SECTION("image any")
} // END SECTION } // END SECTION
SECTION("test image_any initialization") SECTION("test image_any initialization")
{ {
{ {
@ -290,7 +289,6 @@ SECTION("Image Buffer")
} // END SECTION } // END SECTION
SECTION("Image copy/move") SECTION("Image copy/move")
{ {
mapnik::detail::buffer buf(16 * 16 * 4); // large enough to hold 16*16 RGBA image mapnik::detail::buffer buf(16 * 16 * 4); // large enough to hold 16*16 RGBA image
@ -383,10 +381,7 @@ SECTION("image::swap")
// swap empty <-> non-empty // swap empty <-> non-empty
CHECK_NOTHROW(im.swap(im3)); CHECK_NOTHROW(im.swap(im3));
CHECK(im3.data() == nullptr); CHECK(im3.data() == nullptr);
CHECKED_IF(im.data() != nullptr) CHECKED_IF(im.data() != nullptr) { CHECK(im(0, 0) == blue); }
{
CHECK(im(0, 0) == blue);
}
} }
} // END TEST CASE } // END TEST CASE

View file

@ -6,10 +6,10 @@
#include <mapnik/color.hpp> #include <mapnik/color.hpp>
#include <mapnik/image_util.hpp> #include <mapnik/image_util.hpp>
TEST_CASE("image apply_opacity") { TEST_CASE("image apply_opacity")
{
SECTION("test rgba8") { SECTION("test rgba8")
{
mapnik::image_rgba8 im(4, 4); mapnik::image_rgba8 im(4, 4);
mapnik::image_rgba8 im2(4, 4, true, true); // Initialize as already premultiplied mapnik::image_rgba8 im2(4, 4, true, true); // Initialize as already premultiplied
mapnik::image_any im_any(mapnik::image_rgba8(4, 4)); mapnik::image_any im_any(mapnik::image_rgba8(4, 4));
@ -54,8 +54,8 @@ SECTION("test rgba8") {
} // END SECTION } // END SECTION
SECTION("test rgba8 overflow") { SECTION("test rgba8 overflow")
{
mapnik::image_rgba8 im(4, 4); mapnik::image_rgba8 im(4, 4);
mapnik::color c(128, 128, 128, 128); // This color is premultiplied mapnik::color c(128, 128, 128, 128); // This color is premultiplied
mapnik::fill(im, c); // Because c1 is not premultiplied it will make the image not premultiplied mapnik::fill(im, c); // Because c1 is not premultiplied it will make the image not premultiplied
@ -76,8 +76,8 @@ SECTION("test rgba8 overflow") {
} // END SECTION } // END SECTION
SECTION("test rgba8 underflow") { SECTION("test rgba8 underflow")
{
mapnik::image_rgba8 im(4, 4); mapnik::image_rgba8 im(4, 4);
mapnik::color c(128, 128, 128, 128); // This color is premultiplied mapnik::color c(128, 128, 128, 128); // This color is premultiplied
mapnik::fill(im, c); // Because c1 is not premultiplied it will make the image not premultiplied mapnik::fill(im, c); // Because c1 is not premultiplied it will make the image not premultiplied
@ -93,8 +93,8 @@ SECTION("test rgba8 underflow") {
} // END SECTION } // END SECTION
SECTION("test gray8") { SECTION("test gray8")
{
mapnik::image_gray8 im(4, 4); mapnik::image_gray8 im(4, 4);
mapnik::image_any im_any(mapnik::image_gray8(4, 4)); mapnik::image_any im_any(mapnik::image_gray8(4, 4));

View file

@ -11,10 +11,10 @@
#include <sstream> #include <sstream>
#include <array> #include <array>
TEST_CASE("image filter") { TEST_CASE("image filter")
{
SECTION("test bad filter input") { SECTION("test bad filter input")
{
mapnik::image_rgba8 im(3, 3); mapnik::image_rgba8 im(3, 3);
mapnik::fill(im, mapnik::color("blue")); mapnik::fill(im, mapnik::color("blue"));
mapnik::set_pixel(im, 1, 1, mapnik::color("red")); mapnik::set_pixel(im, 1, 1, mapnik::color("red"));
@ -40,8 +40,8 @@ SECTION("test bad filter input") {
} // END SECTION } // END SECTION
SECTION("test blur") { SECTION("test blur")
{
mapnik::image_rgba8 im(3, 3); mapnik::image_rgba8 im(3, 3);
mapnik::fill(im, mapnik::color("blue")); mapnik::fill(im, mapnik::color("blue"));
mapnik::set_pixel(im, 1, 1, mapnik::color("red")); mapnik::set_pixel(im, 1, 1, mapnik::color("red"));
@ -60,8 +60,8 @@ SECTION("test blur") {
} // END SECTION } // END SECTION
SECTION("test blur constant") { SECTION("test blur constant")
{
mapnik::image_rgba8 im_orig(3, 3); mapnik::image_rgba8 im_orig(3, 3);
mapnik::fill(im_orig, mapnik::color("blue")); mapnik::fill(im_orig, mapnik::color("blue"));
mapnik::set_pixel(im_orig, 1, 1, mapnik::color("red")); mapnik::set_pixel(im_orig, 1, 1, mapnik::color("red"));
@ -81,8 +81,8 @@ SECTION("test blur constant") {
} // END SECTION } // END SECTION
SECTION("test gray") { SECTION("test gray")
{
mapnik::image_rgba8 im(3, 3); mapnik::image_rgba8 im(3, 3);
mapnik::fill(im, mapnik::color("blue")); mapnik::fill(im, mapnik::color("blue"));
mapnik::set_pixel(im, 1, 1, mapnik::color("red")); mapnik::set_pixel(im, 1, 1, mapnik::color("red"));
@ -101,8 +101,8 @@ SECTION("test gray") {
} // END SECTION } // END SECTION
SECTION("test agg stack blur") { SECTION("test agg stack blur")
{
mapnik::image_rgba8 im(3, 3); mapnik::image_rgba8 im(3, 3);
mapnik::fill(im, mapnik::color("blue")); mapnik::fill(im, mapnik::color("blue"));
mapnik::set_pixel(im, 1, 1, mapnik::color("red")); mapnik::set_pixel(im, 1, 1, mapnik::color("red"));
@ -121,8 +121,8 @@ SECTION("test agg stack blur") {
} // END SECTION } // END SECTION
SECTION("test scale-hsla 1") { SECTION("test scale-hsla 1")
{
mapnik::image_rgba8 im(3, 3); mapnik::image_rgba8 im(3, 3);
mapnik::fill(im, mapnik::color("blue")); mapnik::fill(im, mapnik::color("blue"));
mapnik::set_pixel(im, 1, 1, mapnik::color("red")); mapnik::set_pixel(im, 1, 1, mapnik::color("red"));
@ -141,8 +141,8 @@ SECTION("test scale-hsla 1") {
} // END SECTION } // END SECTION
SECTION("test scale-hsla 2") { SECTION("test scale-hsla 2")
{
mapnik::image_rgba8 im(3, 3); mapnik::image_rgba8 im(3, 3);
mapnik::set_pixel(im, 0, 0, mapnik::color(255, 0, 0)); mapnik::set_pixel(im, 0, 0, mapnik::color(255, 0, 0));
mapnik::set_pixel(im, 0, 1, mapnik::color(147, 112, 219)); mapnik::set_pixel(im, 0, 1, mapnik::color(147, 112, 219));
@ -170,8 +170,8 @@ SECTION("test scale-hsla 2") {
} // END SECTION } // END SECTION
SECTION("test emboss") { SECTION("test emboss")
{
mapnik::image_rgba8 im(3, 3); mapnik::image_rgba8 im(3, 3);
mapnik::fill(im, mapnik::color("white")); mapnik::fill(im, mapnik::color("white"));
mapnik::set_pixel(im, 1, 1, mapnik::color("orange")); mapnik::set_pixel(im, 1, 1, mapnik::color("orange"));
@ -190,8 +190,8 @@ SECTION("test emboss") {
} // END SECTION } // END SECTION
SECTION("test sharpen") { SECTION("test sharpen")
{
mapnik::image_rgba8 im(3, 3); mapnik::image_rgba8 im(3, 3);
mapnik::fill(im, mapnik::color("blue")); mapnik::fill(im, mapnik::color("blue"));
mapnik::set_pixel(im, 1, 1, mapnik::color("gray")); mapnik::set_pixel(im, 1, 1, mapnik::color("gray"));
@ -210,8 +210,8 @@ SECTION("test sharpen") {
} // END SECTION } // END SECTION
SECTION("test edge detect") { SECTION("test edge detect")
{
mapnik::image_rgba8 im(3, 3); mapnik::image_rgba8 im(3, 3);
mapnik::fill(im, mapnik::color("blue")); mapnik::fill(im, mapnik::color("blue"));
mapnik::set_pixel(im, 1, 1, mapnik::color("gray")); mapnik::set_pixel(im, 1, 1, mapnik::color("gray"));
@ -230,8 +230,8 @@ SECTION("test edge detect") {
} // END SECTION } // END SECTION
SECTION("test sobel") { SECTION("test sobel")
{
mapnik::image_rgba8 im(3, 3); mapnik::image_rgba8 im(3, 3);
mapnik::fill(im, mapnik::color("blue")); mapnik::fill(im, mapnik::color("blue"));
mapnik::set_pixel(im, 1, 1, mapnik::color("gray")); mapnik::set_pixel(im, 1, 1, mapnik::color("gray"));
@ -250,8 +250,8 @@ SECTION("test sobel") {
} // END SECTION } // END SECTION
SECTION("test x-gradient") { SECTION("test x-gradient")
{
mapnik::image_rgba8 im(3, 3); mapnik::image_rgba8 im(3, 3);
mapnik::fill(im, mapnik::color("blue")); mapnik::fill(im, mapnik::color("blue"));
mapnik::set_pixel(im, 1, 1, mapnik::color("gray")); mapnik::set_pixel(im, 1, 1, mapnik::color("gray"));
@ -270,8 +270,8 @@ SECTION("test x-gradient") {
} // END SECTION } // END SECTION
SECTION("test y-gradient") { SECTION("test y-gradient")
{
mapnik::image_rgba8 im(3, 3); mapnik::image_rgba8 im(3, 3);
mapnik::fill(im, mapnik::color("blue")); mapnik::fill(im, mapnik::color("blue"));
mapnik::set_pixel(im, 1, 1, mapnik::color("gray")); mapnik::set_pixel(im, 1, 1, mapnik::color("gray"));
@ -290,8 +290,8 @@ SECTION("test y-gradient") {
} // END SECTION } // END SECTION
SECTION("test invert") { SECTION("test invert")
{
mapnik::image_rgba8 im(3, 3); mapnik::image_rgba8 im(3, 3);
mapnik::fill(im, mapnik::color("blue")); mapnik::fill(im, mapnik::color("blue"));
mapnik::set_pixel(im, 1, 1, mapnik::color("gray")); mapnik::set_pixel(im, 1, 1, mapnik::color("gray"));
@ -310,8 +310,8 @@ SECTION("test invert") {
} // END SECTION } // END SECTION
SECTION("test colorize-alpha - one color") { SECTION("test colorize-alpha - one color")
{
mapnik::image_rgba8 im(3, 3); mapnik::image_rgba8 im(3, 3);
mapnik::fill(im, mapnik::color("blue")); mapnik::fill(im, mapnik::color("blue"));
mapnik::set_pixel(im, 1, 1, mapnik::color("gray")); mapnik::set_pixel(im, 1, 1, mapnik::color("gray"));
@ -330,8 +330,8 @@ SECTION("test colorize-alpha - one color") {
} // END SECTION } // END SECTION
SECTION("test colorize-alpha - two color") { SECTION("test colorize-alpha - two color")
{
mapnik::image_rgba8 im(3, 3); mapnik::image_rgba8 im(3, 3);
mapnik::fill(im, mapnik::color("blue")); mapnik::fill(im, mapnik::color("blue"));
mapnik::set_pixel(im, 1, 1, mapnik::color("gray")); mapnik::set_pixel(im, 1, 1, mapnik::color("gray"));
@ -350,8 +350,8 @@ SECTION("test colorize-alpha - two color") {
} // END SECTION } // END SECTION
SECTION("test colorize-alpha - one color with transparency") { SECTION("test colorize-alpha - one color with transparency")
{
mapnik::image_rgba8 im(3, 3); mapnik::image_rgba8 im(3, 3);
mapnik::fill(im, mapnik::color("#0000ffaa")); mapnik::fill(im, mapnik::color("#0000ffaa"));
mapnik::set_pixel(im, 1, 1, mapnik::color("#aaaaaaaa")); mapnik::set_pixel(im, 1, 1, mapnik::color("#aaaaaaaa"));
@ -370,8 +370,8 @@ SECTION("test colorize-alpha - one color with transparency") {
} // END SECTION } // END SECTION
SECTION("test colorize-alpha - two color with transparency") { SECTION("test colorize-alpha - two color with transparency")
{
mapnik::image_rgba8 im(3, 3); mapnik::image_rgba8 im(3, 3);
mapnik::fill(im, mapnik::color("#0000ffaa")); mapnik::fill(im, mapnik::color("#0000ffaa"));
mapnik::set_pixel(im, 1, 1, mapnik::color("#aaaaaaaa")); mapnik::set_pixel(im, 1, 1, mapnik::color("#aaaaaaaa"));
@ -390,8 +390,8 @@ SECTION("test colorize-alpha - two color with transparency") {
} // END SECTION } // END SECTION
SECTION("test parsing image-filters") { SECTION("test parsing image-filters")
{
std::string str = ""; // empty string std::string str = ""; // empty string
std::vector<mapnik::filter::filter_type> filters; std::vector<mapnik::filter::filter_type> filters;
CHECK(parse_image_filters(str, filters)); CHECK(parse_image_filters(str, filters));
@ -416,7 +416,8 @@ SECTION("test parsing image-filters") {
"agg-stack-blur(2,3)"}}; "agg-stack-blur(2,3)"}};
str += "emboss emboss() blur,gray ,edge-detect, sobel , , sharpen,,,x-gradient y-gradientinvert"; str += "emboss emboss() blur,gray ,edge-detect, sobel , , sharpen,,,x-gradient y-gradientinvert";
str += "color-blind-protanope color-blind-deuteranope color-blind-tritanope agg-stack-blur,agg-stack-blur(),agg-stack-blur(2),agg-stack-blur(2,3)" ; str += "color-blind-protanope color-blind-deuteranope color-blind-tritanope "
"agg-stack-blur,agg-stack-blur(),agg-stack-blur(2),agg-stack-blur(2,3)";
CHECK(parse_image_filters(str, filters)); CHECK(parse_image_filters(str, filters));
CHECK(filters.size() == expected.size()); CHECK(filters.size() == expected.size());
std::size_t count = 0; std::size_t count = 0;
@ -428,8 +429,8 @@ SECTION("test parsing image-filters") {
} }
} }
SECTION("test colorize-alpha - parsing correct input") { SECTION("test colorize-alpha - parsing correct input")
{
std::string s("colorize-alpha(#0000ff 0%, #00ff00 100%)"); std::string s("colorize-alpha(#0000ff 0%, #00ff00 100%)");
std::vector<mapnik::filter::filter_type> f; std::vector<mapnik::filter::filter_type> f;
REQUIRE(parse_image_filters(s, f)); REQUIRE(parse_image_filters(s, f));
@ -458,8 +459,8 @@ SECTION("test colorize-alpha - parsing correct input") {
} // END SECTION } // END SECTION
SECTION("test colorize-alpha - parsing incorrect input") { SECTION("test colorize-alpha - parsing incorrect input")
{
std::string s("colorize-alpha(#0000ff 0%, #00ff00 00 100%)"); std::string s("colorize-alpha(#0000ff 0%, #00ff00 00 100%)");
std::vector<mapnik::filter::filter_type> f; std::vector<mapnik::filter::filter_type> f;
CHECK(!parse_image_filters(s, f)); CHECK(!parse_image_filters(s, f));
@ -467,8 +468,8 @@ SECTION("test colorize-alpha - parsing incorrect input") {
} // END SECTION } // END SECTION
SECTION("test color-blind-protanope") { SECTION("test color-blind-protanope")
{
mapnik::image_rgba8 im(2, 2); mapnik::image_rgba8 im(2, 2);
mapnik::fill(im, mapnik::color("blue")); mapnik::fill(im, mapnik::color("blue"));
mapnik::set_pixel(im, 0, 1, mapnik::color("green")); mapnik::set_pixel(im, 0, 1, mapnik::color("green"));
@ -484,8 +485,8 @@ SECTION("test color-blind-protanope") {
} // END SECTION } // END SECTION
SECTION("test color-blind-deuteranope") { SECTION("test color-blind-deuteranope")
{
mapnik::image_rgba8 im(2, 2); mapnik::image_rgba8 im(2, 2);
mapnik::fill(im, mapnik::color("blue")); mapnik::fill(im, mapnik::color("blue"));
mapnik::set_pixel(im, 0, 1, mapnik::color("green")); mapnik::set_pixel(im, 0, 1, mapnik::color("green"));
@ -501,8 +502,8 @@ SECTION("test color-blind-deuteranope") {
} // END SECTION } // END SECTION
SECTION("test color-blind-tritanope") { SECTION("test color-blind-tritanope")
{
mapnik::image_rgba8 im(2, 2); mapnik::image_rgba8 im(2, 2);
mapnik::fill(im, mapnik::color("blue")); mapnik::fill(im, mapnik::color("blue"));
mapnik::set_pixel(im, 0, 1, mapnik::color("green")); mapnik::set_pixel(im, 0, 1, mapnik::color("green"));

View file

@ -21,7 +21,8 @@ MAPNIK_DISABLE_WARNING_PUSH
MAPNIK_DISABLE_WARNING_POP MAPNIK_DISABLE_WARNING_POP
#include <mapnik/util/mapped_memory_file.hpp> #include <mapnik/util/mapped_memory_file.hpp>
inline void make_directory(std::string const& dir) { inline void make_directory(std::string const& dir)
{
boost::filesystem::create_directories(dir); boost::filesystem::create_directories(dir);
} }
@ -48,12 +49,12 @@ void check_tiny_png_image_quantising(T const& im)
} }
} }
} } // namespace
TEST_CASE("image io") {
SECTION("readers") {
TEST_CASE("image io")
{
SECTION("readers")
{
std::string should_throw; std::string should_throw;
boost::optional<std::string> type; boost::optional<std::string> type;
try try
@ -79,10 +80,11 @@ SECTION("readers") {
{ {
std::unique_ptr<mapnik::image_reader> reader(mapnik::get_image_reader(should_throw, *type)); std::unique_ptr<mapnik::image_reader> reader(mapnik::get_image_reader(should_throw, *type));
REQUIRE(false); REQUIRE(false);
} } catch (std::exception const& ex)
catch (std::exception const& ex)
{ {
REQUIRE( std::string(ex.what()) == std::string("JPEG Reader: libjpeg could not read image: Not a JPEG file: starts with 0x89 0x50") ); REQUIRE(
std::string(ex.what()) ==
std::string("JPEG Reader: libjpeg could not read image: Not a JPEG file: starts with 0x89 0x50"));
} }
#endif #endif
@ -90,10 +92,10 @@ SECTION("readers") {
REQUIRE_THROWS(mapnik::image_rgba8(-10, -10)); // should throw rather than overflow REQUIRE_THROWS(mapnik::image_rgba8(-10, -10)); // should throw rather than overflow
#if defined(HAVE_CAIRO) #if defined(HAVE_CAIRO)
mapnik::cairo_surface_ptr image_surface( mapnik::cairo_surface_ptr image_surface(cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 256, 257),
cairo_image_surface_create(CAIRO_FORMAT_ARGB32,256,257),
mapnik::cairo_surface_closer()); mapnik::cairo_surface_closer());
mapnik::image_rgba8 im_data(cairo_image_surface_get_width(&*image_surface), cairo_image_surface_get_height(&*image_surface)); mapnik::image_rgba8 im_data(cairo_image_surface_get_width(&*image_surface),
cairo_image_surface_get_height(&*image_surface));
im_data.set(1); im_data.set(1);
REQUIRE((unsigned)im_data(0, 0) == unsigned(1)); REQUIRE((unsigned)im_data(0, 0) == unsigned(1));
// Should set back to fully transparent // Should set back to fully transparent
@ -130,8 +132,7 @@ SECTION("readers") {
REQUIRE(type); REQUIRE(type);
REQUIRE_THROWS(mapnik::get_image_reader(should_throw, *type)); REQUIRE_THROWS(mapnik::get_image_reader(should_throw, *type));
#endif #endif
} } catch (std::exception const& ex)
catch (std::exception const & ex)
{ {
std::clog << ex.what() << "\n"; std::clog << ex.what() << "\n";
REQUIRE(false); REQUIRE(false);
@ -151,7 +152,6 @@ SECTION("writers options")
#endif #endif
} // END SECTION } // END SECTION
SECTION("image_util : save_to_file/save_to_stream/save_to_string") SECTION("image_util : save_to_file/save_to_stream/save_to_string")
{ {
mapnik::image_rgba8 im(256, 256); mapnik::image_rgba8 im(256, 256);

View file

@ -7,11 +7,10 @@
#include <mapnik/color.hpp> #include <mapnik/color.hpp>
#include <mapnik/image_util.hpp> #include <mapnik/image_util.hpp>
TEST_CASE("image is_solid")
TEST_CASE("image is_solid") { {
SECTION("test rgba8")
SECTION("test rgba8") { {
mapnik::image_rgba8 im(4, 4); mapnik::image_rgba8 im(4, 4);
mapnik::image_any im_any(mapnik::image_rgba8(4, 4)); mapnik::image_any im_any(mapnik::image_rgba8(4, 4));
@ -44,8 +43,8 @@ SECTION("test rgba8") {
} // END SECTION } // END SECTION
SECTION("test gray8") { SECTION("test gray8")
{
mapnik::image_gray8 im(4, 4); mapnik::image_gray8 im(4, 4);
mapnik::image_any im_any(mapnik::image_gray8(4, 4)); mapnik::image_any im_any(mapnik::image_gray8(4, 4));
@ -76,8 +75,8 @@ SECTION("test gray8") {
} // END SECTION } // END SECTION
SECTION("test image null") { SECTION("test image null")
{
mapnik::image_null im; mapnik::image_null im;
mapnik::image_any im_any; mapnik::image_any im_any;

View file

@ -11,10 +11,10 @@
#include <mapnik/expression.hpp> #include <mapnik/expression.hpp>
#include <mapnik/util/fs.hpp> #include <mapnik/util/fs.hpp>
TEST_CASE("image") { TEST_CASE("image")
{
SECTION("painting") { SECTION("painting")
{
using namespace mapnik; using namespace mapnik;
try try
@ -62,12 +62,10 @@ SECTION("painting") {
REQUIRE(image.painted() == true); REQUIRE(image.painted() == true);
} }
} } catch (std::exception const& ex)
catch (std::exception const & ex)
{ {
std::clog << ex.what() << std::endl; std::clog << ex.what() << std::endl;
REQUIRE(false); REQUIRE(false);
} }
} }
} }

View file

@ -6,10 +6,10 @@
#include <mapnik/color.hpp> #include <mapnik/color.hpp>
#include <mapnik/image_util.hpp> #include <mapnik/image_util.hpp>
TEST_CASE("image premultiply") { TEST_CASE("image premultiply")
{
SECTION("test rgba8") { SECTION("test rgba8")
{
mapnik::image_rgba8 im(4, 4); mapnik::image_rgba8 im(4, 4);
mapnik::image_rgba8 im2(4, 4, true, true); // Initialize as already premultiplied mapnik::image_rgba8 im2(4, 4, true, true); // Initialize as already premultiplied
mapnik::image_any im_any(mapnik::image_rgba8(4, 4)); mapnik::image_any im_any(mapnik::image_rgba8(4, 4));
@ -106,8 +106,8 @@ SECTION("test rgba8") {
} // END SECTION } // END SECTION
SECTION("test gray8") { SECTION("test gray8")
{
mapnik::image_gray8 im(4, 4); mapnik::image_gray8 im(4, 4);
mapnik::image_gray8 im2(4, 4, true, true); // Initialize as already premultiplied mapnik::image_gray8 im2(4, 4, true, true); // Initialize as already premultiplied
mapnik::image_any im_any(mapnik::image_gray8(4, 4)); mapnik::image_any im_any(mapnik::image_gray8(4, 4));

View file

@ -5,10 +5,10 @@
#include <mapnik/image.hpp> #include <mapnik/image.hpp>
#include <mapnik/image_util.hpp> #include <mapnik/image_util.hpp>
TEST_CASE("image set_pixel")
TEST_CASE("image set_pixel") { {
SECTION("test gray32")
SECTION("test gray32") { {
mapnik::image_gray32 im(256, 256); mapnik::image_gray32 im(256, 256);
mapnik::set_pixel(im, 0, 0, -1); mapnik::set_pixel(im, 0, 0, -1);
auto pixel = mapnik::get_pixel<mapnik::image_gray32::pixel_type>(im, 0, 0); auto pixel = mapnik::get_pixel<mapnik::image_gray32::pixel_type>(im, 0, 0);
@ -16,12 +16,12 @@ SECTION("test gray32") {
CHECK(pixel == 0); CHECK(pixel == 0);
} }
SECTION("test gray8s") { SECTION("test gray8s")
{
mapnik::image_gray8s im(256, 256); mapnik::image_gray8s im(256, 256);
mapnik::set_pixel(im, 0, 0, std::numeric_limits<mapnik::image_gray8s::pixel_type>::max() + 1); mapnik::set_pixel(im, 0, 0, std::numeric_limits<mapnik::image_gray8s::pixel_type>::max() + 1);
auto pixel = mapnik::get_pixel<mapnik::image_gray8s::pixel_type>(im, 0, 0); auto pixel = mapnik::get_pixel<mapnik::image_gray8s::pixel_type>(im, 0, 0);
INFO(pixel); INFO(pixel);
CHECK((int)pixel == (int)std::numeric_limits<mapnik::image_gray8s::pixel_type>::max()); CHECK((int)pixel == (int)std::numeric_limits<mapnik::image_gray8s::pixel_type>::max());
} }
} }

View file

@ -7,10 +7,10 @@
#include <mapnik/image_view_any.hpp> #include <mapnik/image_view_any.hpp>
#include <mapnik/image_util.hpp> #include <mapnik/image_util.hpp>
TEST_CASE("image view") { TEST_CASE("image view")
{
SECTION("test rgba8") { SECTION("test rgba8")
{
mapnik::image_rgba8 im(4, 4); mapnik::image_rgba8 im(4, 4);
mapnik::color c_red("red"); mapnik::color c_red("red");
mapnik::color c_blue("blue"); mapnik::color c_blue("blue");

View file

@ -34,38 +34,37 @@ using source_type = std::filebuf;
REQUIRE(tiff_reader2.height() == 256); \ REQUIRE(tiff_reader2.height() == 256); \
std::unique_ptr<mapnik::image_reader> reader2(mapnik::get_image_reader(file.data().get(), file.size())); \ std::unique_ptr<mapnik::image_reader> reader2(mapnik::get_image_reader(file.data().get(), file.size())); \
REQUIRE(reader2->width() == 256); \ REQUIRE(reader2->width() == 256); \
REQUIRE( reader2->height() == 256 ); \ REQUIRE(reader2->height() == 256);
#define TIFF_ASSERT_ALPHA(data) \ #define TIFF_ASSERT_ALPHA(data) \
REQUIRE(tiff_reader.has_alpha() == true); \ REQUIRE(tiff_reader.has_alpha() == true); \
REQUIRE(reader->has_alpha() == true); \ REQUIRE(reader->has_alpha() == true); \
REQUIRE(tiff_reader2.has_alpha() == true); \ REQUIRE(tiff_reader2.has_alpha() == true); \
REQUIRE(reader2->has_alpha() == true); \ REQUIRE(reader2->has_alpha() == true); \
REQUIRE( data.get_premultiplied() == true ); \ REQUIRE(data.get_premultiplied() == true);
#define TIFF_ASSERT_NO_ALPHA_RGB(data) \ #define TIFF_ASSERT_NO_ALPHA_RGB(data) \
REQUIRE(tiff_reader.has_alpha() == false); \ REQUIRE(tiff_reader.has_alpha() == false); \
REQUIRE(reader->has_alpha() == false); \ REQUIRE(reader->has_alpha() == false); \
REQUIRE(tiff_reader2.has_alpha() == false); \ REQUIRE(tiff_reader2.has_alpha() == false); \
REQUIRE(reader2->has_alpha() == false); \ REQUIRE(reader2->has_alpha() == false); \
REQUIRE( data.get_premultiplied() == true ); \ REQUIRE(data.get_premultiplied() == true);
#define TIFF_ASSERT_NO_ALPHA_GRAY(data) \ #define TIFF_ASSERT_NO_ALPHA_GRAY(data) \
REQUIRE(tiff_reader.has_alpha() == false); \ REQUIRE(tiff_reader.has_alpha() == false); \
REQUIRE(reader->has_alpha() == false); \ REQUIRE(reader->has_alpha() == false); \
REQUIRE(tiff_reader2.has_alpha() == false); \ REQUIRE(tiff_reader2.has_alpha() == false); \
REQUIRE(reader2->has_alpha() == false); \ REQUIRE(reader2->has_alpha() == false); \
REQUIRE( data.get_premultiplied() == false ); \ REQUIRE(data.get_premultiplied() == false);
#define TIFF_ASSERT_SIZE(data, reader) \ #define TIFF_ASSERT_SIZE(data, reader) \
REQUIRE(data.width() == reader->width()); \ REQUIRE(data.width() == reader->width()); \
REQUIRE( data.height() == reader->height() ); \ REQUIRE(data.height() == reader->height());
#define TIFF_READ_ONE_PIXEL \ #define TIFF_READ_ONE_PIXEL \
mapnik::image_any subimage = reader->read(1, 1, 1, 1); \ mapnik::image_any subimage = reader->read(1, 1, 1, 1); \
REQUIRE(subimage.width() == 1); \ REQUIRE(subimage.width() == 1); \
REQUIRE( subimage.height() == 1 ); \ REQUIRE(subimage.height() == 1);
namespace { namespace {
@ -73,10 +72,7 @@ template <typename Image>
struct test_image_traits struct test_image_traits
{ {
using value_type = mapnik::color; using value_type = mapnik::color;
static value_type const& get_value(mapnik::color const& c) static value_type const& get_value(mapnik::color const& c) { return c; }
{
return c;
}
}; };
template<> template<>
@ -89,11 +85,9 @@ struct test_image_traits<mapnik::image_gray8>
} }
}; };
template<typename Image> template<typename Image>
Image generate_test_image() Image generate_test_image()
{ {
std::size_t tile_size = 16; std::size_t tile_size = 16;
Image im(64, 64); Image im(64, 64);
mapnik::color colors[] = {{mapnik::color("red")}, mapnik::color colors[] = {{mapnik::color("red")},
@ -130,7 +124,8 @@ bool identical(Image1 const& im1, Image2 const& im2)
{ {
for (std::size_t j = 0; j < im1.height(); ++j) for (std::size_t j = 0; j < im1.height(); ++j)
{ {
if (im1(i,j) != im2(i,j)) return false; if (im1(i, j) != im2(i, j))
return false;
} }
} }
return true; return true;
@ -144,8 +139,7 @@ void test_tiff_reader(std::string const& pattern)
for (auto const& path : mapnik::util::list_directory("test/data/tiff/")) for (auto const& path : mapnik::util::list_directory("test/data/tiff/"))
{ {
if (boost::iends_with(path,".tif") if (boost::iends_with(path, ".tif") && boost::istarts_with(mapnik::util::basename(path), pattern))
&& boost::istarts_with(mapnik::util::basename(path), pattern))
{ {
mapnik::tiff_reader<source_type> tiff_reader(path); mapnik::tiff_reader<source_type> tiff_reader(path);
auto width = tiff_reader.width(); auto width = tiff_reader.width();
@ -169,19 +163,13 @@ void test_tiff_reader(std::string const& pattern)
} }
} }
} } // namespace
TEST_CASE("tiff io") TEST_CASE("tiff io")
{ {
SECTION("tiff-reader rgb8+rgba8") SECTION("tiff-reader rgb8+rgba8") { test_tiff_reader<mapnik::image_rgba8>("tiff_rgb"); }
{
test_tiff_reader<mapnik::image_rgba8>("tiff_rgb");
}
SECTION("tiff-reader gray8") SECTION("tiff-reader gray8") { test_tiff_reader<mapnik::image_gray8>("tiff_gray"); }
{
test_tiff_reader<mapnik::image_gray8>("tiff_gray");
}
SECTION("scan rgb8 striped") SECTION("scan rgb8 striped")
{ {
@ -214,7 +202,8 @@ TEST_CASE("tiff io")
TIFF_READ_ONE_PIXEL TIFF_READ_ONE_PIXEL
} }
SECTION("scan rgb8 tiled") { SECTION("scan rgb8 tiled")
{
std::string filename("./test/data/tiff/scan_512x512_rgb8_tiled.tif"); std::string filename("./test/data/tiff/scan_512x512_rgb8_tiled.tif");
mapnik::tiff_reader<source_type> tiff_reader(filename); mapnik::tiff_reader<source_type> tiff_reader(filename);
REQUIRE(tiff_reader.width() == 512); REQUIRE(tiff_reader.width() == 512);
@ -244,7 +233,8 @@ TEST_CASE("tiff io")
TIFF_READ_ONE_PIXEL TIFF_READ_ONE_PIXEL
} }
SECTION("rgba8 striped") { SECTION("rgba8 striped")
{
TIFF_ASSERT("./test/data/tiff/ndvi_256x256_rgba8_striped.tif") TIFF_ASSERT("./test/data/tiff/ndvi_256x256_rgba8_striped.tif")
REQUIRE(tiff_reader.rows_per_strip() == 1); REQUIRE(tiff_reader.rows_per_strip() == 1);
REQUIRE(tiff_reader.bits_per_sample() == 8); REQUIRE(tiff_reader.bits_per_sample() == 8);
@ -260,7 +250,8 @@ TEST_CASE("tiff io")
TIFF_READ_ONE_PIXEL TIFF_READ_ONE_PIXEL
} }
SECTION("rgba8 tiled") { SECTION("rgba8 tiled")
{
TIFF_ASSERT("./test/data/tiff/ndvi_256x256_rgba8_tiled.tif") TIFF_ASSERT("./test/data/tiff/ndvi_256x256_rgba8_tiled.tif")
REQUIRE(tiff_reader.rows_per_strip() == 0); REQUIRE(tiff_reader.rows_per_strip() == 0);
REQUIRE(tiff_reader.bits_per_sample() == 8); REQUIRE(tiff_reader.bits_per_sample() == 8);
@ -276,7 +267,8 @@ TEST_CASE("tiff io")
TIFF_READ_ONE_PIXEL TIFF_READ_ONE_PIXEL
} }
SECTION("rgb8 striped") { SECTION("rgb8 striped")
{
TIFF_ASSERT("./test/data/tiff/ndvi_256x256_rgb8_striped.tif") TIFF_ASSERT("./test/data/tiff/ndvi_256x256_rgb8_striped.tif")
REQUIRE(tiff_reader.rows_per_strip() == 10); REQUIRE(tiff_reader.rows_per_strip() == 10);
REQUIRE(tiff_reader.bits_per_sample() == 8); REQUIRE(tiff_reader.bits_per_sample() == 8);
@ -292,7 +284,8 @@ TEST_CASE("tiff io")
TIFF_READ_ONE_PIXEL TIFF_READ_ONE_PIXEL
} }
SECTION("rgb8 tiled") { SECTION("rgb8 tiled")
{
TIFF_ASSERT("./test/data/tiff/ndvi_256x256_rgb8_tiled.tif") TIFF_ASSERT("./test/data/tiff/ndvi_256x256_rgb8_tiled.tif")
REQUIRE(tiff_reader.rows_per_strip() == 0); REQUIRE(tiff_reader.rows_per_strip() == 0);
REQUIRE(tiff_reader.bits_per_sample() == 8); REQUIRE(tiff_reader.bits_per_sample() == 8);
@ -308,7 +301,8 @@ TEST_CASE("tiff io")
TIFF_READ_ONE_PIXEL TIFF_READ_ONE_PIXEL
} }
SECTION("gray8 striped") { SECTION("gray8 striped")
{
TIFF_ASSERT("./test/data/tiff/ndvi_256x256_gray8_striped.tif") TIFF_ASSERT("./test/data/tiff/ndvi_256x256_gray8_striped.tif")
REQUIRE(tiff_reader.rows_per_strip() == 32); REQUIRE(tiff_reader.rows_per_strip() == 32);
REQUIRE(tiff_reader.bits_per_sample() == 8); REQUIRE(tiff_reader.bits_per_sample() == 8);
@ -324,7 +318,8 @@ TEST_CASE("tiff io")
TIFF_READ_ONE_PIXEL TIFF_READ_ONE_PIXEL
} }
SECTION("gray8 tiled") { SECTION("gray8 tiled")
{
TIFF_ASSERT("./test/data/tiff/ndvi_256x256_gray8_tiled.tif") TIFF_ASSERT("./test/data/tiff/ndvi_256x256_gray8_tiled.tif")
REQUIRE(tiff_reader.rows_per_strip() == 0); REQUIRE(tiff_reader.rows_per_strip() == 0);
REQUIRE(tiff_reader.bits_per_sample() == 8); REQUIRE(tiff_reader.bits_per_sample() == 8);
@ -340,7 +335,8 @@ TEST_CASE("tiff io")
TIFF_READ_ONE_PIXEL TIFF_READ_ONE_PIXEL
} }
SECTION("gray16 striped") { SECTION("gray16 striped")
{
TIFF_ASSERT("./test/data/tiff/ndvi_256x256_gray16_striped.tif") TIFF_ASSERT("./test/data/tiff/ndvi_256x256_gray16_striped.tif")
REQUIRE(tiff_reader.rows_per_strip() == 16); REQUIRE(tiff_reader.rows_per_strip() == 16);
REQUIRE(tiff_reader.bits_per_sample() == 16); REQUIRE(tiff_reader.bits_per_sample() == 16);
@ -356,7 +352,8 @@ TEST_CASE("tiff io")
TIFF_READ_ONE_PIXEL TIFF_READ_ONE_PIXEL
} }
SECTION("gray16 tiled") { SECTION("gray16 tiled")
{
TIFF_ASSERT("./test/data/tiff/ndvi_256x256_gray16_tiled.tif") TIFF_ASSERT("./test/data/tiff/ndvi_256x256_gray16_tiled.tif")
REQUIRE(tiff_reader.rows_per_strip() == 0); REQUIRE(tiff_reader.rows_per_strip() == 0);
REQUIRE(tiff_reader.bits_per_sample() == 16); REQUIRE(tiff_reader.bits_per_sample() == 16);
@ -372,7 +369,8 @@ TEST_CASE("tiff io")
TIFF_READ_ONE_PIXEL TIFF_READ_ONE_PIXEL
} }
SECTION("gray32f striped") { SECTION("gray32f striped")
{
TIFF_ASSERT("./test/data/tiff/ndvi_256x256_gray32f_striped.tif") TIFF_ASSERT("./test/data/tiff/ndvi_256x256_gray32f_striped.tif")
REQUIRE(tiff_reader.rows_per_strip() == 8); REQUIRE(tiff_reader.rows_per_strip() == 8);
REQUIRE(tiff_reader.bits_per_sample() == 32); REQUIRE(tiff_reader.bits_per_sample() == 32);
@ -388,7 +386,8 @@ TEST_CASE("tiff io")
TIFF_READ_ONE_PIXEL TIFF_READ_ONE_PIXEL
} }
SECTION("gray32f tiled") { SECTION("gray32f tiled")
{
TIFF_ASSERT("./test/data/tiff/ndvi_256x256_gray32f_tiled.tif") TIFF_ASSERT("./test/data/tiff/ndvi_256x256_gray32f_tiled.tif")
REQUIRE(tiff_reader.rows_per_strip() == 0); REQUIRE(tiff_reader.rows_per_strip() == 0);
REQUIRE(tiff_reader.bits_per_sample() == 32); REQUIRE(tiff_reader.bits_per_sample() == 32);
@ -403,7 +402,6 @@ TEST_CASE("tiff io")
TIFF_ASSERT_NO_ALPHA_GRAY(data); TIFF_ASSERT_NO_ALPHA_GRAY(data);
TIFF_READ_ONE_PIXEL TIFF_READ_ONE_PIXEL
} }
} }
#endif #endif

View file

@ -8,9 +8,10 @@
#include <mapnik/image_view.hpp> #include <mapnik/image_view.hpp>
#include <mapnik/webp_io.hpp> #include <mapnik/webp_io.hpp>
TEST_CASE("webp io") { TEST_CASE("webp io")
{
SECTION("does not crash accessing view") { SECTION("does not crash accessing view")
{
std::stringstream s; std::stringstream s;
mapnik::image_rgba8 im(1024, 1024); mapnik::image_rgba8 im(1024, 1024);
mapnik::image_view_rgba8 view(512, 512, 1024, 1024, im); mapnik::image_view_rgba8 view(512, 512, 1024, 1024, im);
@ -21,7 +22,6 @@ SECTION("does not crash accessing view") {
} }
save_as_webp(s, view, config, true); save_as_webp(s, view, config, true);
} }
} }
#endif #endif

View file

@ -30,10 +30,10 @@
#include <mapnik/cairo/cairo_image_util.hpp> #include <mapnik/cairo/cairo_image_util.hpp>
#endif #endif
TEST_CASE("map") { TEST_CASE("map")
{
SECTION("set background - agg") { SECTION("set background - agg")
{
mapnik::Map map(256, 256); mapnik::Map map(256, 256);
mapnik::image_rgba8 image(map.width(), map.height()); mapnik::image_rgba8 image(map.width(), map.height());
const mapnik::color c1(255, 0, 0); const mapnik::color c1(255, 0, 0);
@ -51,8 +51,8 @@ SECTION("set background - agg") {
} }
#if defined(HAVE_CAIRO) #if defined(HAVE_CAIRO)
SECTION("set background - cairo") { SECTION("set background - cairo")
{
mapnik::Map map(256, 256); mapnik::Map map(256, 256);
mapnik::cairo_surface_ptr image_surface( mapnik::cairo_surface_ptr image_surface(
cairo_image_surface_create(CAIRO_FORMAT_ARGB32, map.width(), map.height()), cairo_image_surface_create(CAIRO_FORMAT_ARGB32, map.width(), map.height()),
@ -82,5 +82,4 @@ SECTION("set background - cairo") {
} }
} }
#endif #endif
} }

View file

@ -27,12 +27,13 @@
#include <mapnik/featureset.hpp> #include <mapnik/featureset.hpp>
#include <mapnik/load_map.hpp> #include <mapnik/load_map.hpp>
namespace { namespace {
bool test_query_point(mapnik::Map const& map, bool test_query_point(mapnik::Map const& map,
double x, double y, double x,
std::string const& name, std::string const& expected_val) double y,
std::string const& name,
std::string const& expected_val)
{ {
auto featureset = map.query_map_point(0u, x, y); auto featureset = map.query_map_point(0u, x, y);
while (auto feature = featureset->next()) while (auto feature = featureset->next())
@ -42,12 +43,12 @@ bool test_query_point(mapnik::Map const& map,
} }
return false; return false;
} }
} } // namespace
TEST_CASE("Query map point") {
SECTION("Polygons") {
TEST_CASE("Query map point")
{
SECTION("Polygons")
{
mapnik::Map map(882, 780); mapnik::Map map(882, 780);
mapnik::load_map(map, "./test/data/good_maps/wgs842merc_reprojection.xml"); mapnik::load_map(map, "./test/data/good_maps/wgs842merc_reprojection.xml");
map.zoom_all(); map.zoom_all();

View file

@ -4,8 +4,8 @@
#include <mapnik/symbolizer_enumerations.hpp> #include <mapnik/symbolizer_enumerations.hpp>
#include <sstream> #include <sstream>
TEST_CASE("enumeration") { TEST_CASE("enumeration")
{
mapnik::line_cap_e e(mapnik::ROUND_CAP); mapnik::line_cap_e e(mapnik::ROUND_CAP);
CHECK(e.as_string() == "round"); CHECK(e.as_string() == "round");
// note: test the << operator, which calls `as_string` internally // note: test the << operator, which calls `as_string` internally
@ -13,5 +13,4 @@ TEST_CASE("enumeration") {
std::stringstream s; std::stringstream s;
s << e; s << e;
CHECK(s.str() == "round"); CHECK(s.str() == "round");
} }

View file

@ -7,31 +7,31 @@
auto min_value = static_cast<std::intmax_t>(limit::min()) - 1; \ auto min_value = static_cast<std::intmax_t>(limit::min()) - 1; \
auto max_value = static_cast<std::intmax_t>(limit::max()) + 1; \ auto max_value = static_cast<std::intmax_t>(limit::max()) + 1; \
CHECK(limit::min() == mapnik::safe_cast<numeric_type>(min_value)); \ CHECK(limit::min() == mapnik::safe_cast<numeric_type>(min_value)); \
CHECK( limit::max() == mapnik::safe_cast<numeric_type>(max_value) ); \ CHECK(limit::max() == mapnik::safe_cast<numeric_type>(max_value));
#define CAST_ASSERT2(numeric_type) \ #define CAST_ASSERT2(numeric_type) \
using limit = std::numeric_limits<numeric_type>; \ using limit = std::numeric_limits<numeric_type>; \
auto min_value = static_cast<std::intmax_t>(limit::min()); \ auto min_value = static_cast<std::intmax_t>(limit::min()); \
auto max_value = static_cast<std::intmax_t>(limit::max()); \ auto max_value = static_cast<std::intmax_t>(limit::max()); \
CHECK(limit::min() == mapnik::safe_cast<numeric_type>(min_value)); \ CHECK(limit::min() == mapnik::safe_cast<numeric_type>(min_value)); \
CHECK( limit::max() == mapnik::safe_cast<numeric_type>(max_value) ); \ CHECK(limit::max() == mapnik::safe_cast<numeric_type>(max_value));
#define CAST_ASSERT3(numeric_type) \ #define CAST_ASSERT3(numeric_type) \
using limit = std::numeric_limits<numeric_type>; \ using limit = std::numeric_limits<numeric_type>; \
auto min_value = static_cast<std::intmax_t>(limit::min()) - 1; \ auto min_value = static_cast<std::intmax_t>(limit::min()) - 1; \
auto max_value = static_cast<std::uintmax_t>(limit::max()); \ auto max_value = static_cast<std::uintmax_t>(limit::max()); \
CHECK(limit::min() == mapnik::safe_cast<numeric_type>(min_value)); \ CHECK(limit::min() == mapnik::safe_cast<numeric_type>(min_value)); \
CHECK( limit::max() == mapnik::safe_cast<numeric_type>(max_value) ); \ CHECK(limit::max() == mapnik::safe_cast<numeric_type>(max_value));
#define CAST_ASSERT4(numeric_type) \ #define CAST_ASSERT4(numeric_type) \
using limit = std::numeric_limits<numeric_type>; \ using limit = std::numeric_limits<numeric_type>; \
auto min_value = static_cast<double>(-limit::max()) - 1; \ auto min_value = static_cast<double>(-limit::max()) - 1; \
auto max_value = static_cast<double>(limit::max()); \ auto max_value = static_cast<double>(limit::max()); \
CHECK(-limit::max() == mapnik::safe_cast<numeric_type>(min_value)); \ CHECK(-limit::max() == mapnik::safe_cast<numeric_type>(min_value)); \
CHECK( limit::max() == mapnik::safe_cast<numeric_type>(max_value) ); \ CHECK(limit::max() == mapnik::safe_cast<numeric_type>(max_value));
TEST_CASE("saturated cast") {
TEST_CASE("saturated cast")
{
SECTION("int8") { CAST_ASSERT(std::int8_t); } SECTION("int8") { CAST_ASSERT(std::int8_t); }
SECTION("int16") { CAST_ASSERT(std::int16_t); } SECTION("int16") { CAST_ASSERT(std::int16_t); }
SECTION("int32") { CAST_ASSERT(std::int32_t); } SECTION("int32") { CAST_ASSERT(std::int32_t); }
@ -50,11 +50,10 @@ TEST_CASE("saturated cast") {
SECTION("float") { CAST_ASSERT4(float); } SECTION("float") { CAST_ASSERT4(float); }
SECTION("freeform") { SECTION("freeform")
{
CHECK(static_cast<std::size_t>(0) == mapnik::safe_cast<std::size_t>(-1)); CHECK(static_cast<std::size_t>(0) == mapnik::safe_cast<std::size_t>(-1));
CHECK(static_cast<std::uint64_t>(0) == mapnik::safe_cast<std::uint64_t>(-1)); CHECK(static_cast<std::uint64_t>(0) == mapnik::safe_cast<std::uint64_t>(-1));
CHECK(static_cast<unsigned long long>(0) == mapnik::safe_cast<unsigned long long>(-1)); CHECK(static_cast<unsigned long long>(0) == mapnik::safe_cast<unsigned long long>(-1));
} }
} }

View file

@ -38,10 +38,7 @@ color blend(color const& source, color const& dest, unsigned cover=255)
buffer[2] = dest_pre.b; buffer[2] = dest_pre.b;
buffer[3] = dest_pre.a; buffer[3] = dest_pre.a;
// http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html // http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html
agg::rendering_buffer rbuf(buffer, agg::rendering_buffer rbuf(buffer, size, size, size * stride);
size,
size,
size * stride);
color::value_type* psource = (color::value_type*)rbuf.row_ptr(0, 0, 1); color::value_type* psource = (color::value_type*)rbuf.row_ptr(0, 0, 1);
blender::blend_pix(psource, source_pre.r, source_pre.g, source_pre.b, source_pre.a, cover); blender::blend_pix(psource, source_pre.r, source_pre.g, source_pre.b, source_pre.a, cover);
color color_result(psource[0], psource[1], psource[2], psource[3]); color color_result(psource[0], psource[1], psource[2], psource[3]);
@ -90,29 +87,22 @@ color normal_blend(color const& source, color const& dest, unsigned cover=255)
return color_result; return color_result;
} }
namespace agg { namespace agg {
// the original agg template code for src_over // the original agg template code for src_over
// before we changed A as per https://github.com/mapnik/mapnik/issues/1452 // before we changed A as per https://github.com/mapnik/mapnik/issues/1452
template<class ColorT, class Order> struct comp_op_rgba_src_over2 template<class ColorT, class Order>
struct comp_op_rgba_src_over2
{ {
using color_type = ColorT; using color_type = ColorT;
using order_type = Order; using order_type = Order;
using value_type = typename color_type::value_type; using value_type = typename color_type::value_type;
using calc_type = typename color_type::calc_type; using calc_type = typename color_type::calc_type;
enum base_scale_e enum base_scale_e { base_shift = color_type::base_shift, base_mask = color_type::base_mask };
{
base_shift = color_type::base_shift,
base_mask = color_type::base_mask
};
// Dca' = Sca + Dca.(1 - Sa) // Dca' = Sca + Dca.(1 - Sa)
// Da' = Sa + Da - Sa.Da // Da' = Sa + Da - Sa.Da
static void blend_pix(value_type* p, static void blend_pix(value_type* p, unsigned sr, unsigned sg, unsigned sb, unsigned sa, unsigned cover)
unsigned sr, unsigned sg, unsigned sb,
unsigned sa, unsigned cover)
{ {
if (cover < 255) if (cover < 255)
{ {
@ -129,12 +119,12 @@ template<class ColorT, class Order> struct comp_op_rgba_src_over2
} }
}; };
} } // namespace agg
TEST_CASE("blending") {
SECTION("src over") {
TEST_CASE("blending")
{
SECTION("src over")
{
using source_over_old_agg = agg::comp_op_rgba_src_over2<color, agg::order_rgba>; using source_over_old_agg = agg::comp_op_rgba_src_over2<color, agg::order_rgba>;
using source_over = agg::comp_op_rgba_src_over<color, agg::order_rgba>; using source_over = agg::comp_op_rgba_src_over<color, agg::order_rgba>;
@ -150,7 +140,8 @@ SECTION("src over") {
color near_white(254, 254, 254, 254); // Source color near_white(254, 254, 254, 254); // Source
color near_trans(1, 1, 1, 1); // Dest color near_trans(1, 1, 1, 1); // Dest
color expected_color(253, 253, 253, 255); // expected result color expected_color(253, 253, 253, 255); // expected result
REQUIRE( to_string(blend<source_over_old_agg>(near_white,near_trans)) == to_string(color(253,253,253,254)) ); REQUIRE(to_string(blend<source_over_old_agg>(near_white, near_trans)) ==
to_string(color(253, 253, 253, 254)));
REQUIRE(to_string(blend<source_over>(near_white, near_trans)) == to_string(expected_color)); REQUIRE(to_string(blend<source_over>(near_white, near_trans)) == to_string(expected_color));
REQUIRE(to_string(normal_blend(near_white, near_trans)) == to_string(expected_color)); REQUIRE(to_string(normal_blend(near_white, near_trans)) == to_string(expected_color));
@ -196,12 +187,10 @@ SECTION("src over") {
REQUIRE( to_string(blend<source_over_old_agg>(source,dest,cover)) == expected_str ); REQUIRE( to_string(blend<source_over_old_agg>(source,dest,cover)) == expected_str );
} }
*/ */
} } catch (std::exception const& ex)
catch (std::exception const & ex)
{ {
std::clog << ex.what() << "\n"; std::clog << ex.what() << "\n";
REQUIRE(false); REQUIRE(false);
} }
} }
} }

View file

@ -22,7 +22,6 @@ std::string get_file_contents(std::string const& filename)
TEST_CASE("palette") TEST_CASE("palette")
{ {
SECTION("rgb") SECTION("rgb")
{ {
mapnik::rgb a(1, 2, 3); mapnik::rgb a(1, 2, 3);
@ -34,7 +33,6 @@ SECTION("rgb")
} // END SECTION } // END SECTION
SECTION("rgba") SECTION("rgba")
{ {
mapnik::rgba a(1, 2, 3, 4); mapnik::rgba a(1, 2, 3, 4);
@ -75,7 +73,13 @@ SECTION("rgba palette - act pal_64")
{ {
std::string pal_64 = get_file_contents("./test/data/palettes/palette64.act"); std::string pal_64 = get_file_contents("./test/data/palettes/palette64.act");
mapnik::rgba_palette rgba_pal(pal_64, mapnik::rgba_palette::PALETTE_ACT); mapnik::rgba_palette rgba_pal(pal_64, mapnik::rgba_palette::PALETTE_ACT);
CHECK(rgba_pal.to_string() == "[Palette 64 colors #494746 #c37631 #89827c #d1955c #7397b9 #fc9237 #a09f9c #fbc147 #9bb3ce #b7c9a1 #b5d29c #c4b9aa #cdc4a5 #d5c8a3 #c1d7aa #ccc4b6 #dbd19c #b2c4d5 #eae487 #c9c8c6 #e4db99 #c9dcb5 #dfd3ac #cbd2c2 #d6cdbc #dbd2b6 #c0ceda #ece597 #f7ef86 #d7d3c3 #dfcbc3 #d1d0cd #d1e2bf #d3dec1 #dbd3c4 #e6d8b6 #f4ef91 #d3d3cf #cad5de #ded7c9 #dfdbce #fcf993 #ffff8a #dbd9d7 #dbe7cd #d4dce2 #e4ded3 #ebe3c9 #e0e2e2 #f4edc3 #fdfcae #e9e5dc #f4edda #eeebe4 #fefdc5 #e7edf2 #edf4e5 #f2efe9 #f6ede7 #fefedd #f6f4f0 #f1f5f8 #fbfaf8 #ffffff]"); CHECK(rgba_pal.to_string() ==
"[Palette 64 colors #494746 #c37631 #89827c #d1955c #7397b9 #fc9237 #a09f9c #fbc147 #9bb3ce #b7c9a1 "
"#b5d29c #c4b9aa #cdc4a5 #d5c8a3 #c1d7aa #ccc4b6 #dbd19c #b2c4d5 #eae487 #c9c8c6 #e4db99 #c9dcb5 #dfd3ac "
"#cbd2c2 #d6cdbc #dbd2b6 #c0ceda #ece597 #f7ef86 #d7d3c3 #dfcbc3 #d1d0cd #d1e2bf #d3dec1 #dbd3c4 #e6d8b6 "
"#f4ef91 #d3d3cf #cad5de #ded7c9 #dfdbce #fcf993 #ffff8a #dbd9d7 #dbe7cd #d4dce2 #e4ded3 #ebe3c9 #e0e2e2 "
"#f4edc3 #fdfcae #e9e5dc #f4edda #eeebe4 #fefdc5 #e7edf2 #edf4e5 #f2efe9 #f6ede7 #fefedd #f6f4f0 #f1f5f8 "
"#fbfaf8 #ffffff]");
} // END SECTION } // END SECTION
@ -83,7 +87,27 @@ SECTION("rgba palette - act pal_256")
{ {
std::string pal_ = get_file_contents("./test/data/palettes/palette256.act"); std::string pal_ = get_file_contents("./test/data/palettes/palette256.act");
mapnik::rgba_palette rgba_pal(pal_, mapnik::rgba_palette::PALETTE_ACT); mapnik::rgba_palette rgba_pal(pal_, mapnik::rgba_palette::PALETTE_ACT);
CHECK(rgba_pal.to_string() == "[Palette 256 colors #272727 #3c3c3c #484847 #564b41 #605243 #6a523e #555555 #785941 #5d5d5d #746856 #676767 #956740 #ba712e #787777 #cb752a #c27c3d #b68049 #dc8030 #df9e10 #878685 #e1a214 #928b82 #a88a70 #ea8834 #e7a81d #cb8d55 #909090 #94938c #e18f48 #f68d36 #6f94b7 #e1ab2e #8e959b #c79666 #999897 #ff9238 #ef9447 #a99a88 #f1b32c #919ca6 #a1a09f #f0b04b #8aa4bf #f8bc39 #b3ac8f #d1a67a #e3b857 #a8a8a7 #ffc345 #a2adb9 #afaeab #f9ab69 #afbba4 #c4c48a #b4b2af #dec177 #9ab2cf #a3bebb #d7b491 #b6cd9e #b5d29c #b9c8a2 #f1c969 #c5c79e #bbbab9 #cabdaa #a6bcd1 #cec4a7 #e7cc89 #dad98a #d5c9a3 #fabd8a #c1d7aa #cec5b4 #d1d1a5 #d9cf9f #c5c4c3 #d3c7b5 #ddd59d #b4c6d6 #d1cbb4 #d1c7ba #d7d1aa #e1c6ab #cbc7c2 #dbd0a9 #e8e58a #fee178 #d3cbba #dfd7a3 #d2cfb9 #c9ddb5 #d2cbbe #c3cbce #d7cbba #dcceb2 #dfd3aa #e5dd9a #dbd3b1 #ceccc6 #d7cbbe #d7cfba #dfc3be #dfd3ae #cbcbcb #cbd3c3 #d3cfc0 #e0d8aa #d7cfbe #dbd3b8 #ebe596 #dfd8b0 #c0ceda #f1ee89 #decfbc #d7cfc4 #d7d3c3 #d1d0cd #d2dfc0 #dbd3c3 #e7c7c3 #e7d7b3 #f2ed92 #d1e2bf #dad7c3 #fef383 #d3d3cf #dbd3c7 #e0d3c2 #dfd7c0 #ebe4a8 #dbd7c7 #dfd3c7 #f7f38f #c9d4de #dcdcc5 #dfd7c7 #e7d5c2 #d6d5d4 #faf78e #d7dfca #fbfb8a #fffb86 #dfd7cb #e5ddc0 #dad7d2 #ecd6c1 #cfd7de #e8d0cc #fbfb8e #fffb8a #eae3b8 #e3d7cd #dfdbce #fffb8e #ffff8a #f5efa6 #dae6cc #e3dbcf #edddc3 #dddbd6 #d5dbdf #ffff91 #e3dbd3 #fefc99 #e7dbd2 #eaddcd #e3dfd3 #ebd7d3 #dddddd #d4dee6 #e2dfd7 #fcdcc0 #e7dbd7 #e7dfd3 #ebe4cb #f4eeb8 #e3dfdb #e7dfd7 #ebded5 #e7e3d7 #fefea6 #e1ecd6 #ece5d3 #e7e3db #dee3e5 #ebe3db #efdfdb #efe3d8 #f4efc9 #e6ecdb #ebe3df #ebe7db #f0ecd3 #e5e6e5 #efe7da #ebe7df #efe3df #fefeb8 #dfe7ef #ebe7e3 #edebde #efe7e0 #e8efe0 #e7f3df #ebebe3 #e7ebe8 #f5edd9 #efebe3 #e3ebf1 #e9efe7 #ebebea #efebe7 #f0efe2 #ecf3e5 #fefdc9 #efefe7 #f3efe7 #f5f3e1 #f2efe9 #e9eef4 #ffeddf #efefef #f3efeb #f3f3eb #f0f7eb #fbf7e1 #fefed8 #f3f3ef #f7f3eb #eef3f7 #f7f7ea #f3f3f3 #f3f7ef #f7f3ef #f3f3f7 #f7f3f3 #f7f7ef #fffee3 #f3f7f7 #f7f7f3 #fcf7ee #f7f7f7 #f7fbf4 #f5f7fb #fbf7f6 #fffeef #f7fbfb #fbfbf7 #fbfbfb #fbfbff #fbfffb #fffbfb #fbffff #fffffb #ffffff]"); CHECK(rgba_pal.to_string() ==
"[Palette 256 colors #272727 #3c3c3c #484847 #564b41 #605243 #6a523e #555555 #785941 #5d5d5d #746856 "
"#676767 #956740 #ba712e #787777 #cb752a #c27c3d #b68049 #dc8030 #df9e10 #878685 #e1a214 #928b82 #a88a70 "
"#ea8834 #e7a81d #cb8d55 #909090 #94938c #e18f48 #f68d36 #6f94b7 #e1ab2e #8e959b #c79666 #999897 #ff9238 "
"#ef9447 #a99a88 #f1b32c #919ca6 #a1a09f #f0b04b #8aa4bf #f8bc39 #b3ac8f #d1a67a #e3b857 #a8a8a7 #ffc345 "
"#a2adb9 #afaeab #f9ab69 #afbba4 #c4c48a #b4b2af #dec177 #9ab2cf #a3bebb #d7b491 #b6cd9e #b5d29c #b9c8a2 "
"#f1c969 #c5c79e #bbbab9 #cabdaa #a6bcd1 #cec4a7 #e7cc89 #dad98a #d5c9a3 #fabd8a #c1d7aa #cec5b4 #d1d1a5 "
"#d9cf9f #c5c4c3 #d3c7b5 #ddd59d #b4c6d6 #d1cbb4 #d1c7ba #d7d1aa #e1c6ab #cbc7c2 #dbd0a9 #e8e58a #fee178 "
"#d3cbba #dfd7a3 #d2cfb9 #c9ddb5 #d2cbbe #c3cbce #d7cbba #dcceb2 #dfd3aa #e5dd9a #dbd3b1 #ceccc6 #d7cbbe "
"#d7cfba #dfc3be #dfd3ae #cbcbcb #cbd3c3 #d3cfc0 #e0d8aa #d7cfbe #dbd3b8 #ebe596 #dfd8b0 #c0ceda #f1ee89 "
"#decfbc #d7cfc4 #d7d3c3 #d1d0cd #d2dfc0 #dbd3c3 #e7c7c3 #e7d7b3 #f2ed92 #d1e2bf #dad7c3 #fef383 #d3d3cf "
"#dbd3c7 #e0d3c2 #dfd7c0 #ebe4a8 #dbd7c7 #dfd3c7 #f7f38f #c9d4de #dcdcc5 #dfd7c7 #e7d5c2 #d6d5d4 #faf78e "
"#d7dfca #fbfb8a #fffb86 #dfd7cb #e5ddc0 #dad7d2 #ecd6c1 #cfd7de #e8d0cc #fbfb8e #fffb8a #eae3b8 #e3d7cd "
"#dfdbce #fffb8e #ffff8a #f5efa6 #dae6cc #e3dbcf #edddc3 #dddbd6 #d5dbdf #ffff91 #e3dbd3 #fefc99 #e7dbd2 "
"#eaddcd #e3dfd3 #ebd7d3 #dddddd #d4dee6 #e2dfd7 #fcdcc0 #e7dbd7 #e7dfd3 #ebe4cb #f4eeb8 #e3dfdb #e7dfd7 "
"#ebded5 #e7e3d7 #fefea6 #e1ecd6 #ece5d3 #e7e3db #dee3e5 #ebe3db #efdfdb #efe3d8 #f4efc9 #e6ecdb #ebe3df "
"#ebe7db #f0ecd3 #e5e6e5 #efe7da #ebe7df #efe3df #fefeb8 #dfe7ef #ebe7e3 #edebde #efe7e0 #e8efe0 #e7f3df "
"#ebebe3 #e7ebe8 #f5edd9 #efebe3 #e3ebf1 #e9efe7 #ebebea #efebe7 #f0efe2 #ecf3e5 #fefdc9 #efefe7 #f3efe7 "
"#f5f3e1 #f2efe9 #e9eef4 #ffeddf #efefef #f3efeb #f3f3eb #f0f7eb #fbf7e1 #fefed8 #f3f3ef #f7f3eb #eef3f7 "
"#f7f7ea #f3f3f3 #f3f7ef #f7f3ef #f3f3f7 #f7f3f3 #f7f7ef #fffee3 #f3f7f7 #f7f7f3 #fcf7ee #f7f7f7 #f7fbf4 "
"#f5f7fb #fbf7f6 #fffeef #f7fbfb #fbfbf7 #fbfbfb #fbfbff #fbfffb #fffbfb #fbffff #fffffb #ffffff]");
} // END SECTION } // END SECTION

View file

@ -8,7 +8,6 @@
TEST_CASE("projection transform") TEST_CASE("projection transform")
{ {
SECTION("Test bounding box transforms - 4326 to 3857") SECTION("Test bounding box transforms - 4326 to 3857")
{ {
mapnik::projection proj_4326("epsg:4326"); mapnik::projection proj_4326("epsg:4326");
@ -44,7 +43,6 @@ SECTION("Test bounding box transforms - 4326 to 3857")
} }
} }
#if defined(MAPNIK_USE_PROJ) #if defined(MAPNIK_USE_PROJ)
SECTION("test proj_transform failure behavior") SECTION("test proj_transform failure behavior")
{ {
@ -96,9 +94,7 @@ SECTION("test forward/backward transformations")
mapnik::proj_transform tr3(proj_4236, proj_4236); mapnik::proj_transform tr3(proj_4236, proj_4236);
mapnik::proj_transform tr4(proj_4236, proj_4937); mapnik::proj_transform tr4(proj_4236, proj_4937);
mapnik::proj_transform tr5(proj_4236, proj_3857); mapnik::proj_transform tr5(proj_4236, proj_3857);
std::initializer_list<std::reference_wrapper<mapnik::proj_transform>> transforms = { std::initializer_list<std::reference_wrapper<mapnik::proj_transform>> transforms = {tr1, tr2, tr3, tr4, tr5};
tr1, tr2, tr3, tr4, tr5
};
std::initializer_list<std::tuple<double, double>> coords = { std::initializer_list<std::tuple<double, double>> coords = {
{-4.0278869, 57.8796955}, // Dórnach, Highland {-4.0278869, 57.8796955}, // Dórnach, Highland
@ -144,8 +140,7 @@ SECTION("Test proj antimeridian bbox")
// //
// wrong = mapnik.Box2d(-177.3145325044, -62.3337481525, // wrong = mapnik.Box2d(-177.3145325044, -62.3337481525,
// 178.0277836332, -24.5845974912) // 178.0277836332, -24.5845974912)
const mapnik::box2d<double> better(-180.0, -62.3337481525, const mapnik::box2d<double> better(-180.0, -62.3337481525, 180.0, -24.5845974912);
180.0, -24.5845974912);
{ {
mapnik::box2d<double> ext(274000, 3087000, 3327000, 7173000); mapnik::box2d<double> ext(274000, 3087000, 3327000, 7173000);
@ -179,8 +174,7 @@ SECTION("Test proj antimeridian bbox")
// 274000 7173000 # top-most // 274000 7173000 # top-most
// END // END
// //
const mapnik::box2d<double> normal(148.7639922894, -60.1222810241, const mapnik::box2d<double> normal(148.7639922894, -60.1222810241, 159.9548489296, -24.9771195155);
159.9548489296, -24.9771195155);
{ {
// checks for not being snapped (ie. not antimeridian) // checks for not being snapped (ie. not antimeridian)
@ -210,7 +204,6 @@ SECTION("Test proj antimeridian bbox")
SECTION("proj_transform of coordinate arrays with stride > 1") SECTION("proj_transform of coordinate arrays with stride > 1")
{ {
mapnik::projection const proj_4326("epsg:4326"); mapnik::projection const proj_4326("epsg:4326");
mapnik::projection const proj_3857("epsg:3857"); mapnik::projection const proj_3857("epsg:3857");
mapnik::projection const proj_2193("epsg:2193"); mapnik::projection const proj_2193("epsg:2193");
@ -225,8 +218,7 @@ SECTION("proj_transform of coordinate arrays with stride > 1")
// 170.142139 -43.595056 18940136.2759583741 -5402988.5324898539 // 170.142139 -43.595056 18940136.2759583741 -5402988.5324898539
// 175.566667 -39.283333 19543991.9707122259 -4762338.2380718365 // 175.566667 -39.283333 19543991.9707122259 -4762338.2380718365
// //
mapnik::geometry::point<double> points[] = {{ 170.142139, -43.595056 }, mapnik::geometry::point<double> points[] = {{170.142139, -43.595056}, {175.566667, -39.283333}};
{ 175.566667, -39.283333 }};
// this transform is calculated by Mapnik (well_known_srs.cpp) // this transform is calculated by Mapnik (well_known_srs.cpp)
mapnik::proj_transform lonlat_to_webmerc(proj_4326, proj_3857); mapnik::proj_transform lonlat_to_webmerc(proj_4326, proj_3857);
CHECKED_IF(lonlat_to_webmerc.forward(&points[0].x, &points[0].y, nullptr, 2, 2)) CHECKED_IF(lonlat_to_webmerc.forward(&points[0].x, &points[0].y, nullptr, 2, 2))
@ -248,7 +240,6 @@ SECTION("proj_transform of coordinate arrays with stride > 1")
#ifdef MAPNIK_USE_PROJ #ifdef MAPNIK_USE_PROJ
SECTION("lonlat <-> New Zealand Transverse Mercator 2000") SECTION("lonlat <-> New Zealand Transverse Mercator 2000")
{ {
mapnik::projection const proj_2193("epsg:2193"); mapnik::projection const proj_2193("epsg:2193");
// cs2cs -Ef %.10f epsg:4326 +to epsg:2193 <<END // cs2cs -Ef %.10f epsg:4326 +to epsg:2193 <<END
// 170.142139 -43.595056 // 170.142139 -43.595056
@ -258,8 +249,7 @@ SECTION("proj_transform of coordinate arrays with stride > 1")
// 170.142139 -43.595056 1369316.0970041484 5169132.9750701785 // 170.142139 -43.595056 1369316.0970041484 5169132.9750701785
// 175.566667 -39.283333 1821377.9170061364 5648640.2106032455 // 175.566667 -39.283333 1821377.9170061364 5648640.2106032455
// //
mapnik::geometry::point<double> points[] = {{ 170.142139, -43.595056 }, mapnik::geometry::point<double> points[] = {{170.142139, -43.595056}, {175.566667, -39.283333}};
{ 175.566667, -39.283333 }};
// this transform is not calculated by Mapnik (needs Proj4) // this transform is not calculated by Mapnik (needs Proj4)
mapnik::proj_transform lonlat_to_nztm(proj_4326, proj_2193); mapnik::proj_transform lonlat_to_nztm(proj_4326, proj_2193);
CHECKED_IF(lonlat_to_nztm.forward(&points[0].x, &points[0].y, nullptr, 2, 2)) CHECKED_IF(lonlat_to_nztm.forward(&points[0].x, &points[0].y, nullptr, 2, 2))
@ -279,5 +269,4 @@ SECTION("proj_transform of coordinate arrays with stride > 1")
} }
#endif // MAPNIK_USE_PROJ #endif // MAPNIK_USE_PROJ
} }
} }

View file

@ -16,10 +16,9 @@ class test_datasource : public mapnik::memory_datasource
{ {
public: public:
test_datasource(mapnik::box2d<double> const& expected_query_bbox) test_datasource(mapnik::box2d<double> const& expected_query_bbox)
: mapnik::memory_datasource(prepare_params()), : mapnik::memory_datasource(prepare_params())
expected_query_bbox_(expected_query_bbox) , expected_query_bbox_(expected_query_bbox)
{ {}
}
virtual mapnik::featureset_ptr features(mapnik::query const& q) const virtual mapnik::featureset_ptr features(mapnik::query const& q) const
{ {
@ -42,16 +41,14 @@ private:
mapnik::box2d<double> expected_query_bbox_; mapnik::box2d<double> expected_query_bbox_;
}; };
TEST_CASE("feature_style_processor: buffer-size with scale-factor")
TEST_CASE("feature_style_processor: buffer-size with scale-factor") { {
SECTION("query extent with buffer-size should not be affected by scale-factor")
SECTION("query extent with buffer-size should not be affected by scale-factor") { {
const mapnik::box2d<double> expected_query_bbox(-0.5, -0.5, 1.5, 1.5); const mapnik::box2d<double> expected_query_bbox(-0.5, -0.5, 1.5, 1.5);
using datasource_ptr = std::shared_ptr<test_datasource>; using datasource_ptr = std::shared_ptr<test_datasource>;
datasource_ptr datasource = std::make_shared<test_datasource>( datasource_ptr datasource = std::make_shared<test_datasource>(expected_query_bbox);
expected_query_bbox);
mapnik::context_ptr ctx = std::make_shared<mapnik::context_type>(); mapnik::context_ptr ctx = std::make_shared<mapnik::context_type>();
{ {
mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx, 2)); mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx, 2));
@ -95,5 +92,4 @@ SECTION("query extent with buffer-size should not be affected by scale-factor")
ren.apply(); ren.apply();
} }
} }
} }

View file

@ -12,9 +12,10 @@ MAPNIK_DISABLE_WARNING_POP
#include <fstream> #include <fstream>
#if defined(HAVE_CAIRO) #if defined(HAVE_CAIRO)
TEST_CASE("cairo_io") { TEST_CASE("cairo_io")
{
SECTION("save_to_cairo_file - SVG") { SECTION("save_to_cairo_file - SVG")
{
std::string directory_name("/tmp/mapnik-tests/"); std::string directory_name("/tmp/mapnik-tests/");
boost::filesystem::create_directories(directory_name); boost::filesystem::create_directories(directory_name);
REQUIRE(mapnik::util::exists(directory_name)); REQUIRE(mapnik::util::exists(directory_name));
@ -30,6 +31,5 @@ SECTION("save_to_cairo_file - SVG") {
// Check the Cairo SVG surface is using SVG 1.2 // Check the Cairo SVG surface is using SVG 1.2
CHECK(actual_output.find("version=\"1.2\"") != std::string::npos); CHECK(actual_output.find("version=\"1.2\"") != std::string::npos);
} }
} }
#endif #endif

View file

@ -33,42 +33,26 @@ public:
using processor_impl_type = test_renderer; using processor_impl_type = test_renderer;
test_renderer(mapnik::Map const& map, rendering_result& result) test_renderer(mapnik::Map const& map, rendering_result& result)
: mapnik::feature_style_processor<test_renderer>(map), : mapnik::feature_style_processor<test_renderer>(map)
result_(result), , result_(result)
painted_(false), , painted_(false)
vars_() , vars_()
{ {}
}
void start_map_processing(mapnik::Map const& map) void start_map_processing(mapnik::Map const& map) { result_.start_map_processing++; }
{
result_.start_map_processing++;
}
void end_map_processing(mapnik::Map const& map) void end_map_processing(mapnik::Map const& map) { result_.end_map_processing++; }
{
result_.end_map_processing++;
}
void start_layer_processing(mapnik::layer const& lay, mapnik::box2d<double> const& query_extent) void start_layer_processing(mapnik::layer const& lay, mapnik::box2d<double> const& query_extent)
{ {
result_.layer_query_extents.push_back(query_extent); result_.layer_query_extents.push_back(query_extent);
} }
void end_layer_processing(mapnik::layer const& lay) void end_layer_processing(mapnik::layer const& lay) { result_.end_layer_processing++; }
{
result_.end_layer_processing++;
}
void start_style_processing(mapnik::feature_type_style const& st) void start_style_processing(mapnik::feature_type_style const& st) { result_.start_style_processing++; }
{
result_.start_style_processing++;
}
void end_style_processing(mapnik::feature_type_style const& st) void end_style_processing(mapnik::feature_type_style const& st) { result_.end_style_processing++; }
{
result_.end_style_processing++;
}
template<typename Symbolizer> template<typename Symbolizer>
void process(Symbolizer const& sym, mapnik::feature_impl& feature, mapnik::proj_transform const& prj_trans) void process(Symbolizer const& sym, mapnik::feature_impl& feature, mapnik::proj_transform const& prj_trans)
@ -81,30 +65,18 @@ public:
return false; return false;
} }
double scale_factor() const double scale_factor() const { return 1; }
{
return 1;
}
mapnik::attributes const& variables() const mapnik::attributes const& variables() const { return vars_; }
{
return vars_;
}
mapnik::eAttributeCollectionPolicy attribute_collection_policy() const mapnik::eAttributeCollectionPolicy attribute_collection_policy() const
{ {
return mapnik::eAttributeCollectionPolicy::DEFAULT; return mapnik::eAttributeCollectionPolicy::DEFAULT;
} }
bool painted() const bool painted() const { return painted_; }
{
return painted_;
}
void painted(bool painted) void painted(bool painted) { painted_ = painted; }
{
painted_ = painted;
}
private: private:
rendering_result& result_; rendering_result& result_;
@ -162,10 +134,10 @@ mapnik::Map prepare_map()
return map; return map;
} }
TEST_CASE("feature_style_processor") { TEST_CASE("feature_style_processor")
{
SECTION("test_renderer") { SECTION("test_renderer")
{
mapnik::Map map(prepare_map()); mapnik::Map map(prepare_map());
rendering_result result; rendering_result result;
test_renderer renderer(map, result); test_renderer renderer(map, result);
@ -188,8 +160,8 @@ SECTION("test_renderer") {
REQUIRE(mapnik::geometry::geometry_type(result.geometries[1]) == mapnik::geometry::geometry_types::LineString); REQUIRE(mapnik::geometry::geometry_type(result.geometries[1]) == mapnik::geometry::geometry_types::LineString);
} }
SECTION("test_renderer - apply() with single layer") { SECTION("test_renderer - apply() with single layer")
{
mapnik::Map map(prepare_map()); mapnik::Map map(prepare_map());
rendering_result result; rendering_result result;
test_renderer renderer(map, result); test_renderer renderer(map, result);
@ -214,8 +186,8 @@ SECTION("test_renderer - apply() with single layer") {
REQUIRE(mapnik::geometry::geometry_type(result.geometries[1]) == mapnik::geometry::geometry_types::LineString); REQUIRE(mapnik::geometry::geometry_type(result.geometries[1]) == mapnik::geometry::geometry_types::LineString);
} }
SECTION("test_renderer - apply_to_layer") { SECTION("test_renderer - apply_to_layer")
{
mapnik::Map map(prepare_map()); mapnik::Map map(prepare_map());
rendering_result result; rendering_result result;
test_renderer renderer(map, result); test_renderer renderer(map, result);
@ -249,5 +221,4 @@ SECTION("test_renderer - apply_to_layer") {
REQUIRE(mapnik::geometry::geometry_type(result.geometries[0]) == mapnik::geometry::geometry_types::Point); REQUIRE(mapnik::geometry::geometry_type(result.geometries[0]) == mapnik::geometry::geometry_types::Point);
REQUIRE(mapnik::geometry::geometry_type(result.geometries[1]) == mapnik::geometry::geometry_types::LineString); REQUIRE(mapnik::geometry::geometry_type(result.geometries[1]) == mapnik::geometry::geometry_types::LineString);
} }
} }

View file

@ -8,20 +8,14 @@
#include "cleanup.hpp" // run_cleanup() #include "cleanup.hpp" // run_cleanup()
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
Catch::Session session; Catch::Session session;
std::string plugin_path; std::string plugin_path;
std::string working_dir; std::string working_dir;
auto cli = session.cli() auto cli =
| session.cli() | Catch::clara::Opt(plugin_path, "plugins")["-p"]["--plugins"]("path to mapnik plugins") |
Catch::clara::Opt(plugin_path, "plugins") Catch::clara::Opt(working_dir, "working directory")["-C"]["--working-directory"]("change working directory");
["-p"]["--plugins"] ("path to mapnik plugins")
|
Catch::clara::Opt(working_dir, "working directory")
["-C"]["--working-directory"] ("change working directory")
;
session.cli(cli); session.cli(cli);
int result = session.applyCommandLine(argc, argv); int result = session.applyCommandLine(argc, argv);
@ -58,5 +52,4 @@ int main (int argc, char** argv)
testing::run_cleanup(); testing::run_cleanup();
return result; return result;
} }

View file

@ -29,7 +29,8 @@ MAPNIK_DISABLE_WARNING_PUSH
#include <boost/spirit/home/x3.hpp> #include <boost/spirit/home/x3.hpp>
MAPNIK_DISABLE_WARNING_POP MAPNIK_DISABLE_WARNING_POP
namespace mapnik { namespace util { namespace mapnik {
namespace util {
template<typename Out> template<typename Out>
bool parse_hex(std::string const& input, Out& output) bool parse_hex(std::string const& input, Out& output)
@ -41,7 +42,7 @@ bool parse_hex(std::string const& input, Out & output)
return boost::spirit::x3::parse(itr, end, -(lit("\\x") | lit("0x")) > *hex2(), output); return boost::spirit::x3::parse(itr, end, -(lit("\\x") | lit("0x")) > *hex2(), output);
} }
}} } // namespace util
} // namespace mapnik
#endif // MAPNIK_PARSE_HEX_HPP #endif // MAPNIK_PARSE_HEX_HPP

View file

@ -7,57 +7,66 @@
#include <mapnik/geometry/correct.hpp> #include <mapnik/geometry/correct.hpp>
#include <boost/version.hpp> #include <boost/version.hpp>
TEST_CASE("geometry formats") { TEST_CASE("geometry formats")
{
SECTION("wkb") { SECTION("wkb")
{
unsigned char sp_valid_blob[] = { unsigned char sp_valid_blob[] = {
0x0, 0x1, 0xBC, 0xB, 0x0, 0x0, 0x1F, 0x12, 0xDB, 0xCF, 0xC3, 0xA2, 0x41, 0x41, 0x9D, 0x74, 0xB0, 0x31, 0xE6, 0x34, 0x53, 0x41, 0xDB, 0x0, 0x1, 0xBC, 0xB, 0x0, 0x0, 0x1F, 0x12, 0xDB, 0xCF, 0xC3, 0xA2, 0x41, 0x41, 0x9D, 0x74, 0xB0, 0x31,
0x1B, 0xB6, 0x7C, 0xD9, 0xA2, 0x41, 0x41, 0x67, 0xA7, 0xB6, 0xF, 0xF6, 0x34, 0x53, 0x41, 0x7C, 0x6, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0xE6, 0x34, 0x53, 0x41, 0xDB, 0x1B, 0xB6, 0x7C, 0xD9, 0xA2, 0x41, 0x41, 0x67, 0xA7, 0xB6, 0xF, 0xF6, 0x34,
0x0, 0x69, 0x3, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x12, 0x0, 0x0, 0x0, 0xBB, 0x4B, 0x9C, 0x59, 0xD2, 0xA2, 0x41, 0x41, 0x3A, 0xAA, 0x53, 0x41, 0x7C, 0x6, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x69, 0x3, 0x0, 0x0, 0x0, 0x1, 0x0,
0x3F, 0xAE, 0xEB, 0x34, 0x53, 0x41, 0xA2, 0xC2, 0xE4, 0xC6, 0xD1, 0xA2, 0x41, 0x41, 0x4C, 0xFE, 0x6, 0x2B, 0xEC, 0x34, 0x53, 0x41, 0x0, 0x0, 0x12, 0x0, 0x0, 0x0, 0xBB, 0x4B, 0x9C, 0x59, 0xD2, 0xA2, 0x41, 0x41, 0x3A, 0xAA, 0x3F, 0xAE,
0xEC, 0x65, 0x5F, 0x6, 0xCE, 0xA2, 0x41, 0x41, 0xDD, 0x33, 0x7F, 0x24, 0xEF, 0x34, 0x53, 0x41, 0x2D, 0x35, 0x2D, 0x30, 0xCB, 0xA2, 0xEB, 0x34, 0x53, 0x41, 0xA2, 0xC2, 0xE4, 0xC6, 0xD1, 0xA2, 0x41, 0x41, 0x4C, 0xFE, 0x6, 0x2B, 0xEC, 0x34,
0x41, 0x41, 0x4E, 0xA7, 0x88, 0x9, 0xF1, 0x34, 0x53, 0x41, 0x58, 0x2F, 0x12, 0x96, 0xCA, 0xA2, 0x41, 0x41, 0x52, 0xD1, 0xBD, 0xDC, 0x53, 0x41, 0xEC, 0x65, 0x5F, 0x6, 0xCE, 0xA2, 0x41, 0x41, 0xDD, 0x33, 0x7F, 0x24, 0xEF, 0x34, 0x53, 0x41,
0xF0, 0x34, 0x53, 0x41, 0x1F, 0x12, 0xDB, 0xCF, 0xC3, 0xA2, 0x41, 0x41, 0xB9, 0x31, 0xA4, 0xE1, 0xF5, 0x34, 0x53, 0x41, 0x21, 0xBB, 0x2D, 0x35, 0x2D, 0x30, 0xCB, 0xA2, 0x41, 0x41, 0x4E, 0xA7, 0x88, 0x9, 0xF1, 0x34, 0x53, 0x41, 0x58, 0x2F,
0x20, 0x6D, 0xC4, 0xA2, 0x41, 0x41, 0x67, 0xA7, 0xB6, 0xF, 0xF6, 0x34, 0x53, 0x41, 0x5A, 0x82, 0x4A, 0xD3, 0xCA, 0xA2, 0x41, 0x41, 0x12, 0x96, 0xCA, 0xA2, 0x41, 0x41, 0x52, 0xD1, 0xBD, 0xDC, 0xF0, 0x34, 0x53, 0x41, 0x1F, 0x12, 0xDB, 0xCF,
0xA7, 0x85, 0x3D, 0x58, 0xF1, 0x34, 0x53, 0x41, 0x22, 0xB8, 0x3A, 0x7D, 0xCB, 0xA2, 0x41, 0x41, 0x7D, 0x89, 0xA1, 0x8E, 0xF1, 0x34, 0xC3, 0xA2, 0x41, 0x41, 0xB9, 0x31, 0xA4, 0xE1, 0xF5, 0x34, 0x53, 0x41, 0x21, 0xBB, 0x20, 0x6D, 0xC4, 0xA2,
0x53, 0x41, 0xD0, 0x77, 0x3F, 0x80, 0xCF, 0xA2, 0x41, 0x41, 0x57, 0x69, 0x83, 0xC4, 0xEE, 0x34, 0x53, 0x41, 0xA7, 0xF5, 0x8E, 0xF9, 0x41, 0x41, 0x67, 0xA7, 0xB6, 0xF, 0xF6, 0x34, 0x53, 0x41, 0x5A, 0x82, 0x4A, 0xD3, 0xCA, 0xA2, 0x41, 0x41,
0xD1, 0xA2, 0x41, 0x41, 0x9A, 0xA2, 0x31, 0xEE, 0xEC, 0x34, 0x53, 0x41, 0x2A, 0xCD, 0xDE, 0x4C, 0xD4, 0xA2, 0x41, 0x41, 0x11, 0x43, 0xA7, 0x85, 0x3D, 0x58, 0xF1, 0x34, 0x53, 0x41, 0x22, 0xB8, 0x3A, 0x7D, 0xCB, 0xA2, 0x41, 0x41, 0x7D, 0x89,
0xE1, 0xF7, 0xEA, 0x34, 0x53, 0x41, 0xF, 0x89, 0xB1, 0x66, 0xD5, 0xA2, 0x41, 0x41, 0xC8, 0x5D, 0x86, 0xF1, 0xE9, 0x34, 0x53, 0x41, 0xA1, 0x8E, 0xF1, 0x34, 0x53, 0x41, 0xD0, 0x77, 0x3F, 0x80, 0xCF, 0xA2, 0x41, 0x41, 0x57, 0x69, 0x83, 0xC4,
0x19, 0xF4, 0x73, 0x63, 0xD7, 0xA2, 0x41, 0x41, 0x7, 0xB1, 0x14, 0x36, 0xE8, 0x34, 0x53, 0x41, 0xDB, 0x1B, 0xB6, 0x7C, 0xD9, 0xA2, 0xEE, 0x34, 0x53, 0x41, 0xA7, 0xF5, 0x8E, 0xF9, 0xD1, 0xA2, 0x41, 0x41, 0x9A, 0xA2, 0x31, 0xEE, 0xEC, 0x34,
0x41, 0x41, 0x98, 0xB5, 0xE0, 0x74, 0xE6, 0x34, 0x53, 0x41, 0xC0, 0x3F, 0xC6, 0xAC, 0xD8, 0xA2, 0x41, 0x41, 0x9D, 0x74, 0xB0, 0x31, 0x53, 0x41, 0x2A, 0xCD, 0xDE, 0x4C, 0xD4, 0xA2, 0x41, 0x41, 0x11, 0x43, 0xE1, 0xF7, 0xEA, 0x34, 0x53, 0x41,
0xE6, 0x34, 0x53, 0x41, 0xF0, 0xB5, 0xB1, 0x53, 0xD5, 0xA2, 0x41, 0x41, 0x97, 0x47, 0xAD, 0x36, 0xE9, 0x34, 0x53, 0x41, 0xBB, 0x4B, 0xF, 0x89, 0xB1, 0x66, 0xD5, 0xA2, 0x41, 0x41, 0xC8, 0x5D, 0x86, 0xF1, 0xE9, 0x34, 0x53, 0x41, 0x19, 0xF4,
0x9C, 0x59, 0xD2, 0xA2, 0x41, 0x41, 0x3A, 0xAA, 0x3F, 0xAE, 0xEB, 0x34, 0x53, 0x41, 0xFE }; 0x73, 0x63, 0xD7, 0xA2, 0x41, 0x41, 0x7, 0xB1, 0x14, 0x36, 0xE8, 0x34, 0x53, 0x41, 0xDB, 0x1B, 0xB6, 0x7C,
0xD9, 0xA2, 0x41, 0x41, 0x98, 0xB5, 0xE0, 0x74, 0xE6, 0x34, 0x53, 0x41, 0xC0, 0x3F, 0xC6, 0xAC, 0xD8, 0xA2,
0x41, 0x41, 0x9D, 0x74, 0xB0, 0x31, 0xE6, 0x34, 0x53, 0x41, 0xF0, 0xB5, 0xB1, 0x53, 0xD5, 0xA2, 0x41, 0x41,
0x97, 0x47, 0xAD, 0x36, 0xE9, 0x34, 0x53, 0x41, 0xBB, 0x4B, 0x9C, 0x59, 0xD2, 0xA2, 0x41, 0x41, 0x3A, 0xAA,
0x3F, 0xAE, 0xEB, 0x34, 0x53, 0x41, 0xFE};
unsigned char sp_invalid_blob[] = { unsigned char sp_invalid_blob[] = {
0x0, 0x1, 0xBC, 0xB, 0x0, 0x0, 0x1F, 0x12, 0xDB, 0xCF, 0xC3, 0xA2, 0x41, 0x41, 0x9D, 0x74, 0xB0, 0x31, 0xE6, 0x34, 0x53, 0x41, 0xDB, 0x0, 0x1, 0xBC, 0xB, 0x0, 0x0, 0x1F, 0x12, 0xDB, 0xCF, 0xC3, 0xA2, 0x41, 0x41, 0x9D, 0x74, 0xB0, 0x31,
0x1B, 0xB6, 0x7C, 0xD9, 0xA2, 0x41, 0x41, 0x67, 0xA7, 0xB6, 0xF, 0xF6, 0x34, 0x53, 0x41, 0x7C, 0x6, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0xE6, 0x34, 0x53, 0x41, 0xDB, 0x1B, 0xB6, 0x7C, 0xD9, 0xA2, 0x41, 0x41, 0x67, 0xA7, 0xB6, 0xF, 0xF6, 0x34,
0x0, 0x69, 0x3, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x12, 0x0, 0x0, 0x0, 0xBB, 0x4B, 0x9C, 0x59, 0xD2, 0xA2, 0x41, 0x41, 0x3A, 0xAA, 0x53, 0x41, 0x7C, 0x6, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x69, 0x3, 0x0, 0x0, 0x0, 0x1, 0x0,
0x3F, 0xAE, 0xEB, 0x34, 0x53, 0x41, 0xA2, 0xC2, 0xE4, 0xC6, 0xD1, 0xA2, 0x41, 0x41, 0x4C, 0xFE, 0x6, 0x2B, 0xEC, 0x34, 0x53, 0x41, 0x0, 0x0, 0x12, 0x0, 0x0, 0x0, 0xBB, 0x4B, 0x9C, 0x59, 0xD2, 0xA2, 0x41, 0x41, 0x3A, 0xAA, 0x3F, 0xAE,
0xEC, 0x65, 0x5F, 0x6, 0xCE, 0xA2, 0x41, 0x41, 0xDD, 0x33, 0x7F, 0x24, 0xEF, 0x34, 0x53, 0x41, 0x2D, 0x35, 0x2D, 0x30, 0xCB, 0xA2, 0xEB, 0x34, 0x53, 0x41, 0xA2, 0xC2, 0xE4, 0xC6, 0xD1, 0xA2, 0x41, 0x41, 0x4C, 0xFE, 0x6, 0x2B, 0xEC, 0x34,
0x41, 0x41, 0x4E, 0xA7, 0x88, 0x9, 0xF1, 0x34, 0x53, 0x41, 0x58, 0x2F, 0x12, 0x96, 0xCA, 0xA2, 0x41, 0x41, 0x52, 0xD1, 0xBD, 0xDC, 0x53, 0x41, 0xEC, 0x65, 0x5F, 0x6, 0xCE, 0xA2, 0x41, 0x41, 0xDD, 0x33, 0x7F, 0x24, 0xEF, 0x34, 0x53, 0x41,
0xF0, 0x34, 0x53, 0x41, 0x1F, 0x12, 0xDB, 0xCF, 0xC3, 0xA2, 0x41, 0x41, 0xB9, 0x31, 0xA4, 0xE1, 0xF5, 0x34, 0x53, 0x41, 0x21, 0xBB, 0x2D, 0x35, 0x2D, 0x30, 0xCB, 0xA2, 0x41, 0x41, 0x4E, 0xA7, 0x88, 0x9, 0xF1, 0x34, 0x53, 0x41, 0x58, 0x2F,
0x20, 0x6D, 0xC4, 0xA2, 0x41, 0x41, 0x67, 0xA7, 0xB6, 0xF, 0xF6, 0x34, 0x53, 0x41, 0x5A, 0x82, 0x4A, 0xD3, 0xCA, 0xA2, 0x41, 0x41, 0x12, 0x96, 0xCA, 0xA2, 0x41, 0x41, 0x52, 0xD1, 0xBD, 0xDC, 0xF0, 0x34, 0x53, 0x41, 0x1F, 0x12, 0xDB, 0xCF,
0xA7, 0x85, 0x3D, 0x58, 0xF1, 0x34, 0x53, 0x41, 0x22, 0xB8, 0x3A, 0x7D, 0xCB, 0xA2, 0x41, 0x41, 0x7D, 0x89, 0xA1, 0x8E, 0xF1, 0x34, 0xC3, 0xA2, 0x41, 0x41, 0xB9, 0x31, 0xA4, 0xE1, 0xF5, 0x34, 0x53, 0x41, 0x21, 0xBB, 0x20, 0x6D, 0xC4, 0xA2,
0x53, 0x41, 0xD0, 0x77, 0x3F, 0x80, 0xCF, 0xA2, 0x41, 0x41, 0x57, 0x69, 0x83, 0xC4, 0xEE, 0x34, 0x53, 0x41, 0xA7, 0xF5, 0x8E, 0xF9, 0x41, 0x41, 0x67, 0xA7, 0xB6, 0xF, 0xF6, 0x34, 0x53, 0x41, 0x5A, 0x82, 0x4A, 0xD3, 0xCA, 0xA2, 0x41, 0x41,
0xD1, 0xA2, 0x41, 0x41, 0x9A, 0xA2, 0x31, 0xEE, 0xEC, 0x34, 0x53, 0x41, 0x2A, 0xCD, 0xDE, 0x4C, 0xD4, 0xA2, 0x41, 0x41, 0x11, 0x43, 0xA7, 0x85, 0x3D, 0x58, 0xF1, 0x34, 0x53, 0x41, 0x22, 0xB8, 0x3A, 0x7D, 0xCB, 0xA2, 0x41, 0x41, 0x7D, 0x89,
0xE1, 0xF7, 0xEA, 0x34, 0x53, 0x41, 0xF, 0x89, 0xB1, 0x66, 0xD5, 0xA2, 0x41, 0x41, 0xC8, 0x5D, 0x86, 0xF1, 0xE9, 0x34, 0x53, 0x41, 0xA1, 0x8E, 0xF1, 0x34, 0x53, 0x41, 0xD0, 0x77, 0x3F, 0x80, 0xCF, 0xA2, 0x41, 0x41, 0x57, 0x69, 0x83, 0xC4,
0x19, 0xF4, 0x73, 0x63, 0xD7, 0xA2, 0x41, 0x41, 0x7, 0xB1, 0x14, 0x36, 0xE8, 0x34, 0x53, 0x41, 0xDB, 0x1B, 0xB6, 0x7C, 0xD9, 0xA2, 0xEE, 0x34, 0x53, 0x41, 0xA7, 0xF5, 0x8E, 0xF9, 0xD1, 0xA2, 0x41, 0x41, 0x9A, 0xA2, 0x31, 0xEE, 0xEC, 0x34,
0x41, 0x41, 0x98, 0xB5, 0xE0, 0x74, 0xE6, 0x34, 0x53, 0x41, 0xC0, 0x3F, 0xC6, 0xAC, 0xD8, 0xA2, 0x41, 0x41, 0x9D, 0x74, 0xB0, 0x31, 0x53, 0x41, 0x2A, 0xCD, 0xDE, 0x4C, 0xD4, 0xA2, 0x41, 0x41, 0x11, 0x43, 0xE1, 0xF7, 0xEA, 0x34, 0x53, 0x41,
0xE6, 0x34, 0x53, 0x41, 0xF0, 0xB5, 0xB1, 0x53, 0xD5, 0xA2, 0x41, 0x41, 0x97, 0x47, 0xAD, 0x36, 0xE9, 0x34, 0x53, 0x41, 0xBB, 0x4B, 0xF, 0x89, 0xB1, 0x66, 0xD5, 0xA2, 0x41, 0x41, 0xC8, 0x5D, 0x86, 0xF1, 0xE9, 0x34, 0x53, 0x41, 0x19, 0xF4,
0x9C, 0x59, 0xD2, 0xA2, 0x41, 0x41, 0x3A, 0xAA, 0x3F, 0xAE, 0xEB, 0x34, 0x53, 0x41 }; 0x73, 0x63, 0xD7, 0xA2, 0x41, 0x41, 0x7, 0xB1, 0x14, 0x36, 0xE8, 0x34, 0x53, 0x41, 0xDB, 0x1B, 0xB6, 0x7C,
0xD9, 0xA2, 0x41, 0x41, 0x98, 0xB5, 0xE0, 0x74, 0xE6, 0x34, 0x53, 0x41, 0xC0, 0x3F, 0xC6, 0xAC, 0xD8, 0xA2,
0x41, 0x41, 0x9D, 0x74, 0xB0, 0x31, 0xE6, 0x34, 0x53, 0x41, 0xF0, 0xB5, 0xB1, 0x53, 0xD5, 0xA2, 0x41, 0x41,
0x97, 0x47, 0xAD, 0x36, 0xE9, 0x34, 0x53, 0x41, 0xBB, 0x4B, 0x9C, 0x59, 0xD2, 0xA2, 0x41, 0x41, 0x3A, 0xAA,
0x3F, 0xAE, 0xEB, 0x34, 0x53, 0x41};
unsigned char sq_valid_blob[] = { unsigned char sq_valid_blob[] = {0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x40 }; 0x24, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x40};
unsigned char sq_invalid_blob[] = { unsigned char sq_invalid_blob[] = {0x23, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x23, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x40, 0x23 }; 0x24, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x40, 0x23};
// test of parsing wkb geometries // test of parsing wkb geometries
try { try
{
// spatialite blob // spatialite blob
mapnik::geometry::geometry<double> geom = mapnik::geometry_utils::from_wkb((const char*)sp_valid_blob, mapnik::geometry::geometry<double> geom =
mapnik::geometry_utils::from_wkb((const char*)sp_valid_blob,
sizeof(sp_valid_blob) / sizeof(sp_valid_blob[0]), sizeof(sp_valid_blob) / sizeof(sp_valid_blob[0]),
mapnik::wkbSpatiaLite); mapnik::wkbSpatiaLite);
// winding order is not correct per OGC so we'll fix it // winding order is not correct per OGC so we'll fix it
@ -105,8 +114,7 @@ SECTION("wkb") {
mapnik::wkbGeneric); mapnik::wkbGeneric);
REQUIRE(geom.is<mapnik::geometry::geometry_empty>()); // returns geometry_empty REQUIRE(geom.is<mapnik::geometry::geometry_empty>()); // returns geometry_empty
} } catch (std::exception const& ex)
catch (std::exception const& ex)
{ {
REQUIRE(false); REQUIRE(false);
std::clog << "threw: " << ex.what() << "\n"; std::clog << "threw: " << ex.what() << "\n";

View file

@ -16,7 +16,6 @@
#include <vector> #include <vector>
#include <fstream> #include <fstream>
#if BOOST_VERSION >= 105800 #if BOOST_VERSION >= 105800
namespace { namespace {
@ -24,16 +23,15 @@ struct spatially_equal_visitor
{ {
using result_type = bool; using result_type = bool;
result_type operator() (mapnik::geometry::geometry_empty, mapnik::geometry::geometry_empty) const result_type operator()(mapnik::geometry::geometry_empty, mapnik::geometry::geometry_empty) const { return true; }
{
return true;
}
result_type operator() (mapnik::geometry::geometry_collection<double> const& lhs, mapnik::geometry::geometry_collection<double> const& rhs) const result_type operator()(mapnik::geometry::geometry_collection<double> const& lhs,
mapnik::geometry::geometry_collection<double> const& rhs) const
{ {
std::size_t size0 = lhs.size(); std::size_t size0 = lhs.size();
std::size_t size1 = rhs.size(); std::size_t size1 = rhs.size();
if (size0 != size1) return false; if (size0 != size1)
return false;
for (std::size_t index = 0; index < size0; ++index) for (std::size_t index = 0; index < size0; ++index)
{ {
if (!mapnik::util::apply_visitor(*this, lhs[index], rhs[index])) if (!mapnik::util::apply_visitor(*this, lhs[index], rhs[index]))
@ -42,18 +40,21 @@ struct spatially_equal_visitor
return true; return true;
} }
result_type operator() (mapnik::geometry::multi_point<double> const& lhs, mapnik::geometry::multi_point<double> const& rhs) const result_type operator()(mapnik::geometry::multi_point<double> const& lhs,
mapnik::geometry::multi_point<double> const& rhs) const
{ {
std::size_t size0 = lhs.size(); std::size_t size0 = lhs.size();
std::size_t size1 = rhs.size(); std::size_t size1 = rhs.size();
if (size0 != size1) return false; if (size0 != size1)
return false;
auto tmp0 = lhs; auto tmp0 = lhs;
auto tmp1 = rhs; auto tmp1 = rhs;
std::sort(tmp0.begin(), tmp0.end(), boost::geometry::less<mapnik::geometry::point<double>>()); std::sort(tmp0.begin(), tmp0.end(), boost::geometry::less<mapnik::geometry::point<double>>());
std::sort(tmp1.begin(), tmp1.end(), boost::geometry::less<mapnik::geometry::point<double>>()); std::sort(tmp1.begin(), tmp1.end(), boost::geometry::less<mapnik::geometry::point<double>>());
for (std::size_t index = 0; index < size0; ++index) for (std::size_t index = 0; index < size0; ++index)
{ {
if (!boost::geometry::equals(tmp0[index], tmp1[index])) return false; if (!boost::geometry::equals(tmp0[index], tmp1[index]))
return false;
} }
return true; return true;
} }
@ -71,7 +72,6 @@ struct spatially_equal_visitor
{ {
return false; return false;
} }
}; };
template<typename T> template<typename T>
@ -80,7 +80,7 @@ bool spatially_equal(mapnik::geometry::geometry<T> const& g0, mapnik::geometry::
return mapnik::util::apply_visitor(spatially_equal_visitor(), g0, g1); return mapnik::util::apply_visitor(spatially_equal_visitor(), g0, g1);
} }
} } // namespace
#endif #endif
TEST_CASE("Well-known-geometries") TEST_CASE("Well-known-geometries")
@ -89,7 +89,8 @@ TEST_CASE("Well-known-geometries")
{ {
std::string filename("test/unit/data/well-known-geometries.test"); std::string filename("test/unit/data/well-known-geometries.test");
std::ifstream is(filename.c_str(), std::ios_base::in | std::ios_base::binary); std::ifstream is(filename.c_str(), std::ios_base::in | std::ios_base::binary);
if (!is) throw std::runtime_error("could not open: '" + filename + "'"); if (!is)
throw std::runtime_error("could not open: '" + filename + "'");
for (std::string line; std::getline(is, line, '\n');) for (std::string line; std::getline(is, line, '\n');)
{ {
@ -99,7 +100,8 @@ TEST_CASE("Well-known-geometries")
std::vector<char> wkb, twkb; std::vector<char> wkb, twkb;
REQUIRE(mapnik::util::parse_hex(columns[1], wkb)); REQUIRE(mapnik::util::parse_hex(columns[1], wkb));
REQUIRE(mapnik::util::parse_hex(columns[2], twkb)); REQUIRE(mapnik::util::parse_hex(columns[2], twkb));
mapnik::geometry::geometry<double> geom_0 = mapnik::geometry_utils::from_wkb(wkb.data(), wkb.size(), mapnik::wkbAuto); mapnik::geometry::geometry<double> geom_0 =
mapnik::geometry_utils::from_wkb(wkb.data(), wkb.size(), mapnik::wkbAuto);
mapnik::geometry::geometry<double> geom_1 = mapnik::geometry_utils::from_twkb(twkb.data(), twkb.size()); mapnik::geometry::geometry<double> geom_1 = mapnik::geometry_utils::from_twkb(twkb.data(), twkb.size());
// compare WKTs as doubles // compare WKTs as doubles
std::string wkt, wkt0, wkt1; std::string wkt, wkt0, wkt1;

View file

@ -5,10 +5,10 @@
#include <mapnik/xml_loader.hpp> #include <mapnik/xml_loader.hpp>
#include <mapnik/attribute.hpp> // needed due to fwd declare in value_types.hpp #include <mapnik/attribute.hpp> // needed due to fwd declare in value_types.hpp
TEST_CASE("xml parser") { TEST_CASE("xml parser")
{
SECTION("trims whitespace") { SECTION("trims whitespace")
{
// simple and non-valid mapnik XML reduced from the empty_parameter2.xml // simple and non-valid mapnik XML reduced from the empty_parameter2.xml
// test case. this is to check that the xml parsing routine is trimming // test case. this is to check that the xml parsing routine is trimming
// whitespace from text nodes as part of the parsing operation. // whitespace from text nodes as part of the parsing operation.
@ -41,4 +41,3 @@ TEST_CASE("xml parser") {
REQUIRE(parameter.get_text() == ""); REQUIRE(parameter.get_text() == "");
} }
} }

View file

@ -3,31 +3,35 @@
#include <mapnik/sql_utils.hpp> #include <mapnik/sql_utils.hpp>
TEST_CASE("sql parse") { TEST_CASE("sql parse")
{
SECTION("table") { SECTION("table")
{
std::string subquery("table"); std::string subquery("table");
REQUIRE(subquery == mapnik::sql_utils::table_from_sql(subquery)); REQUIRE(subquery == mapnik::sql_utils::table_from_sql(subquery));
} }
SECTION("complex sql 1") { SECTION("complex sql 1")
{
std::string subquery("(select * FROM table1, table2) AS data"); std::string subquery("(select * FROM table1, table2) AS data");
REQUIRE("table1" == mapnik::sql_utils::table_from_sql(subquery)); REQUIRE("table1" == mapnik::sql_utils::table_from_sql(subquery));
} }
SECTION("complex sql 2") { SECTION("complex sql 2")
{
std::string subquery("(select * FROM table1 , table2) AS data"); std::string subquery("(select * FROM table1 , table2) AS data");
REQUIRE("table1" == mapnik::sql_utils::table_from_sql(subquery)); REQUIRE("table1" == mapnik::sql_utils::table_from_sql(subquery));
} }
SECTION("complex sql 3") { SECTION("complex sql 3")
{
std::string subquery("(select * FROM table1,table2) AS data"); std::string subquery("(select * FROM table1,table2) AS data");
REQUIRE("table1" == mapnik::sql_utils::table_from_sql(subquery)); REQUIRE("table1" == mapnik::sql_utils::table_from_sql(subquery));
} }
SECTION("complex sql 4") { SECTION("complex sql 4")
{
std::string subquery("(select * FROM table1) AS data"); std::string subquery("(select * FROM table1) AS data");
REQUIRE("table1" == mapnik::sql_utils::table_from_sql(subquery)); REQUIRE("table1" == mapnik::sql_utils::table_from_sql(subquery));
} }
} }

View file

@ -51,10 +51,7 @@ namespace // internal
, p(svg, strict) , p(svg, strict)
{} {}
mapnik::svg::svg_parser* operator->() mapnik::svg::svg_parser* operator->() { return &p; }
{
return &p;
}
}; };
template<typename C> template<typename C>
@ -63,15 +60,16 @@ namespace // internal
std::string result; std::string result;
for (auto const& str : container) for (auto const& str : container)
{ {
if (!result.empty()) result += "\n "; if (!result.empty())
result += "\n ";
result += str; result += str;
} }
return result; return result;
} }
} } // namespace
TEST_CASE("SVG parser") {
TEST_CASE("SVG parser")
{
SECTION("SVG i/o") SECTION("SVG i/o")
{ {
mapnik::logger::instance().set_severity(mapnik::logger::none); mapnik::logger::instance().set_severity(mapnik::logger::none);
@ -85,17 +83,13 @@ TEST_CASE("SVG parser") {
SECTION("SVG::parse i/o") SECTION("SVG::parse i/o")
{ {
std::string svg_name("FAIL"); std::string svg_name("FAIL");
char const* expected_errors[] = char const* expected_errors[] = {"SVG error: unable to open \"FAIL\""};
{
"SVG error: unable to open \"FAIL\""
};
test_parser p; test_parser p;
try try
{ {
p->parse(svg_name); p->parse(svg_name);
} } catch (std::exception const& ex)
catch (std::exception const& ex)
{ {
REQUIRE(ex.what() == join(expected_errors)); REQUIRE(ex.what() == join(expected_errors));
} }
@ -104,21 +98,18 @@ TEST_CASE("SVG parser") {
SECTION("SVG::parse_from_string syntax error") SECTION("SVG::parse_from_string syntax error")
{ {
std::string svg_name("./test/data/svg/invalid.svg"); std::string svg_name("./test/data/svg/invalid.svg");
char const* expected_errors[] = char const* expected_errors[] = {
{ "SVG error: unable to parse \"<?xml version=\"1.0\"?>\n<svg width=\"12cm\" height=\"4cm\" viewBox=\"0 0 1200 "
"SVG error: unable to parse \"<?xml version=\"1.0\"?>\n<svg width=\"12cm\" height=\"4cm\" viewBox=\"0 0 1200 400\"\nxmlns=\"http://www.w3.org/2000/svg\" version=\"1.2\" baseProfile=\"tiny\">\n\"" "400\"\nxmlns=\"http://www.w3.org/2000/svg\" version=\"1.2\" baseProfile=\"tiny\">\n\""};
};
std::ifstream in(svg_name.c_str()); std::ifstream in(svg_name.c_str());
std::string svg_str((std::istreambuf_iterator<char>(in)), std::string svg_str((std::istreambuf_iterator<char>(in)), std::istreambuf_iterator<char>());
std::istreambuf_iterator<char>());
test_parser p; test_parser p;
try try
{ {
p->parse_from_string(svg_str); p->parse_from_string(svg_str);
} } catch (std::exception const& ex)
catch (std::exception const& ex)
{ {
REQUIRE(ex.what() == join(expected_errors)); REQUIRE(ex.what() == join(expected_errors));
} }
@ -127,17 +118,13 @@ TEST_CASE("SVG parser") {
SECTION("SVG::parse_from_string syntax error") SECTION("SVG::parse_from_string syntax error")
{ {
std::string svg_name("./test/data/svg/invalid.svg"); std::string svg_name("./test/data/svg/invalid.svg");
char const* expected_errors[] = char const* expected_errors[] = {"SVG error: unable to parse \"./test/data/svg/invalid.svg\""};
{
"SVG error: unable to parse \"./test/data/svg/invalid.svg\""
};
test_parser p; test_parser p;
try try
{ {
p->parse(svg_name); p->parse(svg_name);
} } catch (std::exception const& ex)
catch (std::exception const& ex)
{ {
REQUIRE(ex.what() == join(expected_errors)); REQUIRE(ex.what() == join(expected_errors));
} }
@ -145,18 +132,14 @@ TEST_CASE("SVG parser") {
SECTION("SVG parser color <fail>") SECTION("SVG parser color <fail>")
{ {
std::string svg_name("./test/data/svg/color_fail.svg"); std::string svg_name("./test/data/svg/color_fail.svg");
char const* expected_errors[] = char const* expected_errors[] = {
{
"SVG parse error: can't infer valid image dimensions from width:\"100%\" height:\"100%\"", "SVG parse error: can't infer valid image dimensions from width:\"100%\" height:\"100%\"",
"SVG parse error: failed to parse <color> with value \"fail\"", "SVG parse error: failed to parse <color> with value \"fail\"",
"SVG parse error: failed to parse <number> with value \"fail\"" "SVG parse error: failed to parse <number> with value \"fail\""};
};
std::ifstream in(svg_name.c_str()); std::ifstream in(svg_name.c_str());
std::string svg_str((std::istreambuf_iterator<char>(in)), std::string svg_str((std::istreambuf_iterator<char>(in)), std::istreambuf_iterator<char>());
std::istreambuf_iterator<char>());
{ {
test_parser p; test_parser p;
@ -168,8 +151,7 @@ TEST_CASE("SVG parser") {
try try
{ {
p->parse_from_string(svg_str); p->parse_from_string(svg_str);
} } catch (std::exception const& ex)
catch (std::exception const& ex)
{ {
REQUIRE(ex.what() == std::string(expected_errors[0])); REQUIRE(ex.what() == std::string(expected_errors[0]));
} }
@ -179,8 +161,7 @@ TEST_CASE("SVG parser") {
SECTION("SVG - cope with erroneous geometries") SECTION("SVG - cope with erroneous geometries")
{ {
std::string svg_name("./test/data/svg/errors.svg"); std::string svg_name("./test/data/svg/errors.svg");
char const* expected_errors[] = char const* expected_errors[] = {
{
"SVG parse error: can't infer valid image dimensions from width:\"100%\" height:\"100%\"", "SVG parse error: can't infer valid image dimensions from width:\"100%\" height:\"100%\"",
"SVG validation error: invalid <rect> width \"-100\"", "SVG validation error: invalid <rect> width \"-100\"",
"SVG parse error: failed to parse <number> with value \"FAIL\"", "SVG parse error: failed to parse <number> with value \"FAIL\"",
@ -194,12 +175,10 @@ TEST_CASE("SVG parser") {
"SVG parse error: failed to parse <polygon> points", "SVG parse error: failed to parse <polygon> points",
"SVG parse error: failed to parse <polyline> points", "SVG parse error: failed to parse <polyline> points",
"SVG validation error: invalid <ellipse> rx \"-10\"", "SVG validation error: invalid <ellipse> rx \"-10\"",
"SVG validation error: invalid <ellipse> ry \"-10\"" "SVG validation error: invalid <ellipse> ry \"-10\""};
};
std::ifstream in(svg_name.c_str()); std::ifstream in(svg_name.c_str());
std::string svg_str((std::istreambuf_iterator<char>(in)), std::string svg_str((std::istreambuf_iterator<char>(in)), std::istreambuf_iterator<char>());
std::istreambuf_iterator<char>());
{ {
test_parser p; test_parser p;
@ -213,8 +192,7 @@ TEST_CASE("SVG parser") {
try try
{ {
p->parse_from_string(svg_str); p->parse_from_string(svg_str);
} } catch (std::exception const& ex)
catch (std::exception const& ex)
{ {
REQUIRE(ex.what() == std::string(expected_errors[0])); REQUIRE(ex.what() == std::string(expected_errors[0]));
} }
@ -223,16 +201,11 @@ TEST_CASE("SVG parser") {
SECTION("SVG parser double % <fail>") SECTION("SVG parser double % <fail>")
{ {
std::string svg_name("./test/data/svg/gradient-radial-error.svg"); std::string svg_name("./test/data/svg/gradient-radial-error.svg");
char const* expected_errors[] = char const* expected_errors[] = {"SVG parse error: failed to parse <number> with value \"FAIL\""};
{
"SVG parse error: failed to parse <number> with value \"FAIL\""
};
std::ifstream in(svg_name.c_str()); std::ifstream in(svg_name.c_str());
std::string svg_str((std::istreambuf_iterator<char>(in)), std::string svg_str((std::istreambuf_iterator<char>(in)), std::istreambuf_iterator<char>());
std::istreambuf_iterator<char>());
{ {
test_parser p; test_parser p;
@ -244,8 +217,7 @@ TEST_CASE("SVG parser") {
try try
{ {
p->parse_from_string(svg_str); p->parse_from_string(svg_str);
} } catch (std::exception const& ex)
catch (std::exception const& ex)
{ {
REQUIRE(ex.what() == std::string(expected_errors[0])); REQUIRE(ex.what() == std::string(expected_errors[0]));
} }
@ -254,7 +226,6 @@ TEST_CASE("SVG parser") {
SECTION("SVG parser display=none") SECTION("SVG parser display=none")
{ {
std::string svg_name("./test/data/svg/invisible.svg"); std::string svg_name("./test/data/svg/invisible.svg");
std::shared_ptr<mapnik::marker const> marker = mapnik::marker_cache::instance().find(svg_name, false); std::shared_ptr<mapnik::marker const> marker = mapnik::marker_cache::instance().find(svg_name, false);
REQUIRE(marker); REQUIRE(marker);
@ -272,7 +243,6 @@ TEST_CASE("SVG parser") {
SECTION("SVG parser stroke-linecap=square") SECTION("SVG parser stroke-linecap=square")
{ {
std::string svg_name("./test/data/svg/stroke-linecap-square.svg"); std::string svg_name("./test/data/svg/stroke-linecap-square.svg");
std::shared_ptr<mapnik::marker const> marker = mapnik::marker_cache::instance().find(svg_name, false); std::shared_ptr<mapnik::marker const> marker = mapnik::marker_cache::instance().find(svg_name, false);
REQUIRE(marker); REQUIRE(marker);
@ -383,8 +353,7 @@ TEST_CASE("SVG parser") {
{ {
std::string svg_name("./test/data/svg/viewbox-missing-width-and-height.svg"); std::string svg_name("./test/data/svg/viewbox-missing-width-and-height.svg");
std::ifstream in(svg_name.c_str()); std::ifstream in(svg_name.c_str());
std::string svg_str((std::istreambuf_iterator<char>(in)), std::string svg_str((std::istreambuf_iterator<char>(in)), std::istreambuf_iterator<char>());
std::istreambuf_iterator<char>());
test_parser p; test_parser p;
p->parse_from_string(svg_str); p->parse_from_string(svg_str);
auto width = p.svg.width(); auto width = p.svg.width();
@ -482,26 +451,14 @@ TEST_CASE("SVG parser") {
cmd = path.vertex(&x, &y); cmd = path.vertex(&x, &y);
vec.emplace_back(x, y, cmd); vec.emplace_back(x, y, cmd);
} }
std::vector<std::tuple<double,double,unsigned>> expected = {std::make_tuple(1, 1, 1), std::vector<std::tuple<double, double, unsigned>> expected = {
std::make_tuple(1199, 1, 2), std::make_tuple(1, 1, 1), std::make_tuple(1199, 1, 2), std::make_tuple(1199, 399, 2),
std::make_tuple(1199, 399, 2), std::make_tuple(1, 399, 2), std::make_tuple(1, 1, 79), std::make_tuple(0, 0, 0),
std::make_tuple(1, 399, 2), std::make_tuple(100, 300, 1), std::make_tuple(300, 100, 2), std::make_tuple(0, 0, 0),
std::make_tuple(1, 1, 79), std::make_tuple(300, 300, 1), std::make_tuple(500, 100, 2), std::make_tuple(0, 0, 0),
std::make_tuple(0, 0, 0), std::make_tuple(500, 300, 1), std::make_tuple(700, 100, 2), std::make_tuple(0, 0, 0),
std::make_tuple(100, 300, 1), std::make_tuple(700, 300, 1), std::make_tuple(900, 100, 2), std::make_tuple(0, 0, 0),
std::make_tuple(300, 100, 2), std::make_tuple(900, 300, 1), std::make_tuple(1100, 100, 2)};
std::make_tuple(0, 0, 0),
std::make_tuple(300, 300, 1),
std::make_tuple(500, 100, 2),
std::make_tuple(0, 0, 0),
std::make_tuple(500, 300, 1),
std::make_tuple(700, 100, 2),
std::make_tuple(0, 0, 0),
std::make_tuple(700, 300, 1),
std::make_tuple(900, 100, 2),
std::make_tuple(0, 0, 0),
std::make_tuple(900, 300, 1),
std::make_tuple(1100, 100, 2)};
REQUIRE(std::equal(expected.begin(), expected.end(), vec.begin())); REQUIRE(std::equal(expected.begin(), expected.end(), vec.begin()));
} }
@ -530,33 +487,16 @@ TEST_CASE("SVG parser") {
vec.emplace_back(x, y, cmd); vec.emplace_back(x, y, cmd);
} }
std::vector<std::tuple<double,double,unsigned>> expected = {std::make_tuple(1, 1, 1), std::vector<std::tuple<double, double, unsigned>> expected = {
std::make_tuple(1199, 1, 2), std::make_tuple(1, 1, 1), std::make_tuple(1199, 1, 2), std::make_tuple(1199, 399, 2),
std::make_tuple(1199, 399, 2), std::make_tuple(1, 399, 2), std::make_tuple(1, 1, 79), std::make_tuple(0, 0, 0),
std::make_tuple(1, 399, 2), std::make_tuple(50, 375, 1), std::make_tuple(150, 375, 2), std::make_tuple(150, 325, 2),
std::make_tuple(1, 1, 79), std::make_tuple(250, 325, 2), std::make_tuple(250, 375, 2), std::make_tuple(350, 375, 2),
std::make_tuple(0, 0, 0), std::make_tuple(350, 250, 2), std::make_tuple(450, 250, 2), std::make_tuple(450, 375, 2),
std::make_tuple(50, 375, 1), std::make_tuple(550, 375, 2), std::make_tuple(550, 175, 2), std::make_tuple(650, 175, 2),
std::make_tuple(150, 375, 2), std::make_tuple(650, 375, 2), std::make_tuple(750, 375, 2), std::make_tuple(750, 100, 2),
std::make_tuple(150, 325, 2), std::make_tuple(850, 100, 2), std::make_tuple(850, 375, 2), std::make_tuple(950, 375, 2),
std::make_tuple(250, 325, 2), std::make_tuple(950, 25, 2), std::make_tuple(1050, 25, 2), std::make_tuple(1050, 375, 2),
std::make_tuple(250, 375, 2),
std::make_tuple(350, 375, 2),
std::make_tuple(350, 250, 2),
std::make_tuple(450, 250, 2),
std::make_tuple(450, 375, 2),
std::make_tuple(550, 375, 2),
std::make_tuple(550, 175, 2),
std::make_tuple(650, 175, 2),
std::make_tuple(650, 375, 2),
std::make_tuple(750, 375, 2),
std::make_tuple(750, 100, 2),
std::make_tuple(850, 100, 2),
std::make_tuple(850, 375, 2),
std::make_tuple(950, 375, 2),
std::make_tuple(950, 25, 2),
std::make_tuple(1050, 25, 2),
std::make_tuple(1050, 375, 2),
std::make_tuple(1150, 375, 2)}; std::make_tuple(1150, 375, 2)};
REQUIRE(std::equal(expected.begin(), expected.end(), vec.begin())); REQUIRE(std::equal(expected.begin(), expected.end(), vec.begin()));
@ -586,30 +526,15 @@ TEST_CASE("SVG parser") {
vec.emplace_back(x, y, cmd); vec.emplace_back(x, y, cmd);
} }
std::vector<std::tuple<double,double,unsigned>> expected = {std::make_tuple(1, 1, 1), std::vector<std::tuple<double, double, unsigned>> expected = {
std::make_tuple(1199, 1, 2), std::make_tuple(1, 1, 1), std::make_tuple(1199, 1, 2), std::make_tuple(1199, 399, 2),
std::make_tuple(1199, 399, 2), std::make_tuple(1, 399, 2), std::make_tuple(1, 1, 79), std::make_tuple(0, 0, 0),
std::make_tuple(1, 399, 2), std::make_tuple(350, 75, 1), std::make_tuple(379, 161, 2), std::make_tuple(469, 161, 2),
std::make_tuple(1, 1, 79), std::make_tuple(397, 215, 2), std::make_tuple(423, 301, 2), std::make_tuple(350, 250, 2),
std::make_tuple(0, 0, 0), std::make_tuple(277, 301, 2), std::make_tuple(303, 215, 2), std::make_tuple(231, 161, 2),
std::make_tuple(350, 75, 1), std::make_tuple(321, 161, 2), std::make_tuple(350, 75, 79), std::make_tuple(0, 0, 0),
std::make_tuple(379, 161, 2), std::make_tuple(850, 75, 1), std::make_tuple(958, 137.5, 2), std::make_tuple(958, 262.5, 2),
std::make_tuple(469, 161, 2), std::make_tuple(850, 325, 2), std::make_tuple(742, 262.6, 2), std::make_tuple(742, 137.5, 2),
std::make_tuple(397, 215, 2),
std::make_tuple(423, 301, 2),
std::make_tuple(350, 250, 2),
std::make_tuple(277, 301, 2),
std::make_tuple(303, 215, 2),
std::make_tuple(231, 161, 2),
std::make_tuple(321, 161, 2),
std::make_tuple(350, 75, 79),
std::make_tuple(0, 0, 0),
std::make_tuple(850, 75, 1),
std::make_tuple(958, 137.5, 2),
std::make_tuple(958, 262.5, 2),
std::make_tuple(850, 325, 2),
std::make_tuple(742, 262.6, 2),
std::make_tuple(742, 137.5, 2),
std::make_tuple(850, 75, 79)}; std::make_tuple(850, 75, 79)};
REQUIRE(std::equal(expected.begin(), expected.end(), vec.begin())); REQUIRE(std::equal(expected.begin(), expected.end(), vec.begin()));
@ -664,11 +589,8 @@ TEST_CASE("SVG parser") {
SECTION("SVG missing <gradient> def") SECTION("SVG missing <gradient> def")
{ {
std::string svg_name("./test/data/svg/gradient-nodef.svg"); std::string svg_name("./test/data/svg/gradient-nodef.svg");
char const* expected_errors[] = char const* expected_errors[] = {"SVG parse error: failed to locate fill with <id> \"MyGradient\"",
{ "SVG parse error: failed to locate stroke with <id> \"MyGradient\""};
"SVG parse error: failed to locate fill with <id> \"MyGradient\"",
"SVG parse error: failed to locate stroke with <id> \"MyGradient\""
};
{ {
test_parser p; test_parser p;
p->parse(svg_name); p->parse(svg_name);
@ -679,8 +601,7 @@ TEST_CASE("SVG parser") {
try try
{ {
p->parse(svg_name); p->parse(svg_name);
} } catch (std::exception const& ex)
catch (std::exception const& ex)
{ {
REQUIRE(ex.what() == std::string(expected_errors[0])); REQUIRE(ex.what() == std::string(expected_errors[0]));
} }
@ -690,15 +611,11 @@ TEST_CASE("SVG parser") {
SECTION("SVG missing <gradient> id") SECTION("SVG missing <gradient> id")
{ {
std::string svg_name("./test/data/svg/gradient-no-id.svg"); std::string svg_name("./test/data/svg/gradient-no-id.svg");
char const* expected_errors[] = char const* expected_errors[] = {"SVG parse error: failed to locate fill with <id> \"MyGradient\"",
{ "SVG parse error: failed to locate stroke with <id> \"MyGradient\""};
"SVG parse error: failed to locate fill with <id> \"MyGradient\"",
"SVG parse error: failed to locate stroke with <id> \"MyGradient\""
};
std::ifstream in(svg_name.c_str()); std::ifstream in(svg_name.c_str());
std::string svg_str((std::istreambuf_iterator<char>(in)), std::string svg_str((std::istreambuf_iterator<char>(in)), std::istreambuf_iterator<char>());
std::istreambuf_iterator<char>());
{ {
test_parser p; test_parser p;
@ -710,8 +627,7 @@ TEST_CASE("SVG parser") {
try try
{ {
p->parse_from_string(svg_str); p->parse_from_string(svg_str);
} } catch (std::exception const& ex)
catch (std::exception const& ex)
{ {
REQUIRE(ex.what() == std::string(expected_errors[0])); REQUIRE(ex.what() == std::string(expected_errors[0]));
} }

View file

@ -52,17 +52,16 @@ void test_path_parser(std::string const& str, Expected const& expected)
} }
REQUIRE(std::equal(expected.begin(), expected.end(), vec.begin(), vertex_equal<3>())); REQUIRE(std::equal(expected.begin(), expected.end(), vec.begin(), vertex_equal<3>()));
} }
} // anonymous ns } // namespace
TEST_CASE("SVG path parser") {
TEST_CASE("SVG path parser")
{
SECTION("MoveTo/LineTo") SECTION("MoveTo/LineTo")
{ {
std::string str = "M 100 100 L 300 100 L 200 300 z"; std::string str = "M 100 100 L 300 100 L 200 300 z";
std::string str2 = "M100,100L300,100L200,300z"; std::string str2 = "M100,100L300,100L200,300z";
std::string str3 = "M100,100l200 0L200,300z"; std::string str3 = "M100,100l200 0L200,300z";
std::vector<std::tuple<double,double,unsigned>> expected = { std::vector<std::tuple<double, double, unsigned>> expected = {std::make_tuple(100, 100, 1),
std::make_tuple(100, 100, 1),
std::make_tuple(300, 100, 2), std::make_tuple(300, 100, 2),
std::make_tuple(200, 300, 2), std::make_tuple(200, 300, 2),
std::make_tuple(100, 100, 79)}; std::make_tuple(100, 100, 79)};
@ -75,12 +74,10 @@ TEST_CASE("SVG path parser") {
{ {
std::string str = "M100 100H300V200z"; std::string str = "M100 100H300V200z";
std::string str2 = "M100,100h200v100z"; std::string str2 = "M100,100h200v100z";
std::vector<std::tuple<double,double,unsigned>> expected = { std::vector<std::tuple<double, double, unsigned>> expected = {std::make_tuple(100, 100, 1),
std::make_tuple(100, 100, 1),
std::make_tuple(300, 100, 2), std::make_tuple(300, 100, 2),
std::make_tuple(300, 200, 2), std::make_tuple(300, 200, 2),
std::make_tuple(100, 100, 79) std::make_tuple(100, 100, 79)};
};
test_path_parser(str, expected); test_path_parser(str, expected);
test_path_parser(str2, expected); test_path_parser(str2, expected);
} }
@ -89,8 +86,7 @@ TEST_CASE("SVG path parser") {
{ {
std::string str = "M300,200 h-150 a150,150 0 1,0 150,-150 z"; std::string str = "M300,200 h-150 a150,150 0 1,0 150,-150 z";
std::vector<std::tuple<double,double,unsigned>> expected = { std::vector<std::tuple<double, double, unsigned>> expected = {std::make_tuple(300, 200, 1),
std::make_tuple(300, 200, 1),
std::make_tuple(150, 200, 2), std::make_tuple(150, 200, 2),
std::make_tuple(150, 282.843, 4), std::make_tuple(150, 282.843, 4),
std::make_tuple(217.157, 350, 4), std::make_tuple(217.157, 350, 4),
@ -105,13 +101,11 @@ TEST_CASE("SVG path parser") {
test_path_parser(str, expected); test_path_parser(str, expected);
} }
SECTION("Arcs 2") SECTION("Arcs 2")
{ {
std::string str = "M275,175 v-150 a150,150 0 0,0 -150,150 z"; std::string str = "M275,175 v-150 a150,150 0 0,0 -150,150 z";
std::vector<std::tuple<double,double,unsigned>> expected = { std::vector<std::tuple<double, double, unsigned>> expected = {std::make_tuple(275, 175, 1),
std::make_tuple(275, 175, 1),
std::make_tuple(275, 25, 2), std::make_tuple(275, 25, 2),
std::make_tuple(192.157, 25, 4), std::make_tuple(192.157, 25, 4),
std::make_tuple(125, 92.1573, 4), std::make_tuple(125, 92.1573, 4),
@ -129,36 +123,21 @@ TEST_CASE("SVG path parser") {
"a25,100-30 0150-25l50-25"; "a25,100-30 0150-25l50-25";
std::vector<std::tuple<double, double, unsigned>> expected = { std::vector<std::tuple<double, double, unsigned>> expected = {
std::make_tuple(600, 350, 1), std::make_tuple(600, 350, 1), std::make_tuple(650, 325, 2),
std::make_tuple(650, 325, 2), std::make_tuple(643.096, 311.193, 4), std::make_tuple(648.693, 294.404, 4),
std::make_tuple(643.096, 311.193, 4), std::make_tuple(662.5, 287.5, 4), std::make_tuple(676.307, 280.596, 4),
std::make_tuple(648.693, 294.404, 4), std::make_tuple(693.096, 286.193, 4), std::make_tuple(700, 300, 4),
std::make_tuple(662.5, 287.5, 4), std::make_tuple(750, 275, 2), std::make_tuple(734.991, 248.079, 4),
std::make_tuple(676.307, 280.596, 4), std::make_tuple(734.017, 220.66, 4), std::make_tuple(747.825, 213.756, 4),
std::make_tuple(693.096, 286.193, 4), std::make_tuple(761.632, 206.852, 4), std::make_tuple(784.991, 223.079, 4),
std::make_tuple(700, 300, 4), std::make_tuple(800, 250, 4), std::make_tuple(850, 225, 2),
std::make_tuple(750, 275, 2), std::make_tuple(827.153, 184.812, 4), std::make_tuple(819.825, 146.636, 4),
std::make_tuple(734.991, 248.079, 4), std::make_tuple(833.632, 139.733, 4), std::make_tuple(847.44, 132.829, 4),
std::make_tuple(734.017, 220.66, 4), std::make_tuple(877.153, 159.812, 4), std::make_tuple(900, 200, 4),
std::make_tuple(747.825, 213.756, 4), std::make_tuple(950, 175, 2), std::make_tuple(919.382, 121.506, 4),
std::make_tuple(761.632, 206.852, 4), std::make_tuple(905.754, 72.5436, 4), std::make_tuple(919.561, 65.64, 4),
std::make_tuple(784.991, 223.079, 4), std::make_tuple(933.368, 58.7365, 4), std::make_tuple(969.382, 96.5057, 4),
std::make_tuple(800, 250, 4), std::make_tuple(1000, 150, 4), std::make_tuple(1050, 125, 2)};
std::make_tuple(850, 225, 2),
std::make_tuple(827.153, 184.812, 4),
std::make_tuple(819.825, 146.636, 4),
std::make_tuple(833.632, 139.733, 4),
std::make_tuple(847.44, 132.829, 4),
std::make_tuple(877.153, 159.812, 4),
std::make_tuple(900, 200, 4),
std::make_tuple(950, 175, 2),
std::make_tuple(919.382, 121.506, 4),
std::make_tuple(905.754, 72.5436, 4),
std::make_tuple(919.561, 65.64, 4),
std::make_tuple(933.368, 58.7365, 4),
std::make_tuple(969.382, 96.5057, 4),
std::make_tuple(1000, 150, 4),
std::make_tuple(1050, 125, 2)};
test_path_parser(str, expected); test_path_parser(str, expected);
} }
@ -166,8 +145,7 @@ TEST_CASE("SVG path parser") {
{ {
std::string str = "M200,300 Q400,50 600,300 T1000,300"; std::string str = "M200,300 Q400,50 600,300 T1000,300";
std::vector<std::tuple<double,double,unsigned>> expected = { std::vector<std::tuple<double, double, unsigned>> expected = {std::make_tuple(200, 300, 1),
std::make_tuple(200, 300, 1),
std::make_tuple(400, 50, 3), std::make_tuple(400, 50, 3),
std::make_tuple(600, 300, 3), std::make_tuple(600, 300, 3),
std::make_tuple(800, 550, 3), std::make_tuple(800, 550, 3),
@ -179,8 +157,7 @@ TEST_CASE("SVG path parser") {
{ {
std::string str = "M100,200 C100,100 250,100 250,200S400,300 400,200"; std::string str = "M100,200 C100,100 250,100 250,200S400,300 400,200";
std::vector<std::tuple<double,double,unsigned>> expected = { std::vector<std::tuple<double, double, unsigned>> expected = {std::make_tuple(100, 200, 1),
std::make_tuple(100, 200, 1),
std::make_tuple(100, 100, 4), std::make_tuple(100, 100, 4),
std::make_tuple(250, 100, 4), std::make_tuple(250, 100, 4),
std::make_tuple(250, 200, 4), std::make_tuple(250, 200, 4),

View file

@ -44,8 +44,7 @@ MAPNIK_DISABLE_WARNING_PUSH
#include "agg_scanline_u.h" #include "agg_scanline_u.h"
MAPNIK_DISABLE_WARNING_POP MAPNIK_DISABLE_WARNING_POP
namespace namespace {
{
mapnik::image_rgba8 render_svg(std::string const& filename, double scale_factor) mapnik::image_rgba8 render_svg(std::string const& filename, double scale_factor)
{ {
@ -73,11 +72,9 @@ mapnik::image_rgba8 render_svg(std::string const& filename, double scale_factor)
mapnik::svg::vertex_stl_adapter<mapnik::svg::svg_path_storage> stl_storage(svg.get_data()->source()); mapnik::svg::vertex_stl_adapter<mapnik::svg::svg_path_storage> stl_storage(svg.get_data()->source());
mapnik::svg::svg_path_adapter svg_path(stl_storage); mapnik::svg::svg_path_adapter svg_path(stl_storage);
mapnik::svg::renderer_agg<mapnik::svg_path_adapter, mapnik::svg::
mapnik::svg_attribute_type, renderer_agg<mapnik::svg_path_adapter, mapnik::svg_attribute_type, renderer_solid, agg::pixfmt_rgba32_pre>
renderer_solid, renderer(svg_path, svg.get_data()->attributes());
agg::pixfmt_rgba32_pre > renderer(svg_path,
svg.get_data()->attributes());
double opacity = 1.0; double opacity = 1.0;
renderer.render(ras_ptr, sl, renb, mtx, opacity, {0, 0, svg_width, svg_height}); renderer.render(ras_ptr, sl, renb, mtx, opacity, {0, 0, svg_width, svg_height});
return im; return im;
@ -90,14 +87,15 @@ bool equal(mapnik::image_rgba8 const& im1, mapnik::image_rgba8 const& im2)
for (auto tup : boost::combine(im1, im2)) for (auto tup : boost::combine(im1, im2))
{ {
if (boost::get<0>(tup) != boost::get<1>(tup)) return false; if (boost::get<0>(tup) != boost::get<1>(tup))
return false;
} }
return true; return true;
} }
} } // namespace
TEST_CASE("SVG renderer") {
TEST_CASE("SVG renderer")
{
SECTION("SVG octocat inline/css") SECTION("SVG octocat inline/css")
{ {
double scale_factor = 1.0; double scale_factor = 1.0;

View file

@ -34,11 +34,10 @@ struct vertex_equal
bool operator()(T const& lhs, T const& rhs) const bool operator()(T const& lhs, T const& rhs) const
{ {
static const double eps = 1.0 / std::pow(10, N); static const double eps = 1.0 / std::pow(10, N);
return (std::fabs(std::get<0>(lhs) - std::get<0>(rhs)) < eps) return (std::fabs(std::get<0>(lhs) - std::get<0>(rhs)) < eps) &&
&& (std::fabs(std::get<1>(lhs) - std::get<1>(rhs)) < eps) (std::fabs(std::get<1>(lhs) - std::get<1>(rhs)) < eps) && std::get<2>(lhs) == std::get<2>(rhs);
&& std::get<2>(lhs) == std::get<2>(rhs);
} }
}; };
} } // namespace
#endif // TEST_UNIT_SVG_UTIL_HPP #endif // TEST_UNIT_SVG_UTIL_HPP

View file

@ -7,10 +7,10 @@
using namespace mapnik; using namespace mapnik;
TEST_CASE("marker placement vertex last") { TEST_CASE("marker placement vertex last")
{
SECTION("empty geometry") { SECTION("empty geometry")
{
mapnik::geometry::line_string<double> g; mapnik::geometry::line_string<double> g;
using va_type = mapnik::geometry::line_string_vertex_adapter<double>; using va_type = mapnik::geometry::line_string_vertex_adapter<double>;
va_type va(g); va_type va(g);
@ -20,10 +20,15 @@ SECTION("empty geometry") {
using placement_type = mapnik::markers_vertex_last_placement<va_type, detector_type>; using placement_type = mapnik::markers_vertex_last_placement<va_type, detector_type>;
mapnik::markers_placement_params params { mapnik::markers_placement_params params{mapnik::box2d<double>(0, 0, 10, 10),
mapnik::box2d<double>(0, 0, 10, 10),
agg::trans_affine(), agg::trans_affine(),
0, NAN, 0, false, false, DIRECTION_AUTO, 1.0 }; 0,
NAN,
0,
false,
false,
DIRECTION_AUTO,
1.0};
placement_type placement(va, detector, params); placement_type placement(va, detector, params);
@ -31,8 +36,8 @@ SECTION("empty geometry") {
CHECK(!placement.get_point(x, y, angle, true)); CHECK(!placement.get_point(x, y, angle, true));
} }
SECTION("point") { SECTION("point")
{
mapnik::geometry::point<double> g(2.0, 3.0); mapnik::geometry::point<double> g(2.0, 3.0);
using va_type = mapnik::geometry::point_vertex_adapter<double>; using va_type = mapnik::geometry::point_vertex_adapter<double>;
va_type va(g); va_type va(g);
@ -42,10 +47,15 @@ SECTION("point") {
using placement_type = mapnik::markers_vertex_last_placement<va_type, detector_type>; using placement_type = mapnik::markers_vertex_last_placement<va_type, detector_type>;
mapnik::markers_placement_params params { mapnik::markers_placement_params params{mapnik::box2d<double>(0, 0, 10, 10),
mapnik::box2d<double>(0, 0, 10, 10),
agg::trans_affine(), agg::trans_affine(),
0, NAN, 0, false, false, DIRECTION_AUTO, 1.0 }; 0,
NAN,
0,
false,
false,
DIRECTION_AUTO,
1.0};
placement_type placement(va, detector, params); placement_type placement(va, detector, params);
@ -59,8 +69,8 @@ SECTION("point") {
CHECK(!placement.get_point(x, y, angle, true)); CHECK(!placement.get_point(x, y, angle, true));
} }
SECTION("line string") { SECTION("line string")
{
mapnik::geometry::line_string<double> g; mapnik::geometry::line_string<double> g;
g.emplace_back(1.0, 1.0); g.emplace_back(1.0, 1.0);
g.emplace_back(2.0, 3.0); g.emplace_back(2.0, 3.0);
@ -72,10 +82,15 @@ SECTION("line string") {
using placement_type = mapnik::markers_vertex_last_placement<va_type, detector_type>; using placement_type = mapnik::markers_vertex_last_placement<va_type, detector_type>;
mapnik::markers_placement_params params { mapnik::markers_placement_params params{mapnik::box2d<double>(0, 0, 10, 10),
mapnik::box2d<double>(0, 0, 10, 10),
agg::trans_affine(), agg::trans_affine(),
0, NAN, 0, false, false, DIRECTION_AUTO, 1.0 }; 0,
NAN,
0,
false,
false,
DIRECTION_AUTO,
1.0};
placement_type placement(va, detector, params); placement_type placement(va, detector, params);
@ -89,8 +104,8 @@ SECTION("line string") {
CHECK(!placement.get_point(x, y, angle, true)); CHECK(!placement.get_point(x, y, angle, true));
} }
SECTION("polygon") { SECTION("polygon")
{
mapnik::geometry::polygon<double> g; mapnik::geometry::polygon<double> g;
g.emplace_back(); g.emplace_back();
auto& exterior = g.back(); auto& exterior = g.back();
@ -106,10 +121,15 @@ SECTION("polygon") {
using placement_type = mapnik::markers_vertex_last_placement<va_type, detector_type>; using placement_type = mapnik::markers_vertex_last_placement<va_type, detector_type>;
mapnik::markers_placement_params params { mapnik::markers_placement_params params{mapnik::box2d<double>(0, 0, 10, 10),
mapnik::box2d<double>(0, 0, 10, 10),
agg::trans_affine(), agg::trans_affine(),
0, NAN, 0, false, false, DIRECTION_AUTO, 1.0 }; 0,
NAN,
0,
false,
false,
DIRECTION_AUTO,
1.0};
placement_type placement(va, detector, params); placement_type placement(va, detector, params);
@ -122,5 +142,4 @@ SECTION("polygon") {
CHECK(!placement.get_point(x, y, angle, true)); CHECK(!placement.get_point(x, y, angle, true));
} }
} }

View file

@ -7,10 +7,10 @@
using namespace mapnik; using namespace mapnik;
TEST_CASE("marker placement point") { TEST_CASE("marker placement point")
{
SECTION("empty geometry") { SECTION("empty geometry")
{
mapnik::geometry::line_string<double> g; mapnik::geometry::line_string<double> g;
using va_type = mapnik::geometry::line_string_vertex_adapter<double>; using va_type = mapnik::geometry::line_string_vertex_adapter<double>;
va_type va(g); va_type va(g);
@ -20,10 +20,15 @@ SECTION("empty geometry") {
using placement_type = mapnik::markers_point_placement<va_type, detector_type>; using placement_type = mapnik::markers_point_placement<va_type, detector_type>;
mapnik::markers_placement_params params { mapnik::markers_placement_params params{mapnik::box2d<double>(0, 0, 10, 10),
mapnik::box2d<double>(0, 0, 10, 10),
agg::trans_affine(), agg::trans_affine(),
0, NAN, 0, false, false, DIRECTION_AUTO, 1.0 }; 0,
NAN,
0,
false,
false,
DIRECTION_AUTO,
1.0};
placement_type placement(va, detector, params); placement_type placement(va, detector, params);
@ -31,8 +36,8 @@ SECTION("empty geometry") {
CHECK(!placement.get_point(x, y, angle, true)); CHECK(!placement.get_point(x, y, angle, true));
} }
SECTION("point") { SECTION("point")
{
mapnik::geometry::point<double> g(2.0, 3.0); mapnik::geometry::point<double> g(2.0, 3.0);
using va_type = mapnik::geometry::point_vertex_adapter<double>; using va_type = mapnik::geometry::point_vertex_adapter<double>;
va_type va(g); va_type va(g);
@ -42,10 +47,15 @@ SECTION("point") {
using placement_type = mapnik::markers_point_placement<va_type, detector_type>; using placement_type = mapnik::markers_point_placement<va_type, detector_type>;
mapnik::markers_placement_params params { mapnik::markers_placement_params params{mapnik::box2d<double>(0, 0, 10, 10),
mapnik::box2d<double>(0, 0, 10, 10),
agg::trans_affine(), agg::trans_affine(),
0, NAN, 0, false, false, DIRECTION_AUTO, 1.0 }; 0,
NAN,
0,
false,
false,
DIRECTION_AUTO,
1.0};
placement_type placement(va, detector, params); placement_type placement(va, detector, params);
@ -59,8 +69,8 @@ SECTION("point") {
CHECK(!placement.get_point(x, y, angle, true)); CHECK(!placement.get_point(x, y, angle, true));
} }
SECTION("line string") { SECTION("line string")
{
mapnik::geometry::line_string<double> g; mapnik::geometry::line_string<double> g;
g.emplace_back(1.0, 1.0); g.emplace_back(1.0, 1.0);
g.emplace_back(2.0, 2.0); g.emplace_back(2.0, 2.0);
@ -72,10 +82,15 @@ SECTION("line string") {
using placement_type = mapnik::markers_point_placement<va_type, detector_type>; using placement_type = mapnik::markers_point_placement<va_type, detector_type>;
mapnik::markers_placement_params params { mapnik::markers_placement_params params{mapnik::box2d<double>(0, 0, 10, 10),
mapnik::box2d<double>(0, 0, 10, 10),
agg::trans_affine(), agg::trans_affine(),
0, NAN, 0, false, false, DIRECTION_AUTO, 1.0 }; 0,
NAN,
0,
false,
false,
DIRECTION_AUTO,
1.0};
placement_type placement(va, detector, params); placement_type placement(va, detector, params);
@ -89,8 +104,8 @@ SECTION("line string") {
CHECK(!placement.get_point(x, y, angle, true)); CHECK(!placement.get_point(x, y, angle, true));
} }
SECTION("line string zero length") { SECTION("line string zero length")
{
mapnik::geometry::line_string<double> g; mapnik::geometry::line_string<double> g;
g.emplace_back(1.0, 1.0); g.emplace_back(1.0, 1.0);
g.emplace_back(1.0, 1.0); g.emplace_back(1.0, 1.0);
@ -102,10 +117,15 @@ SECTION("line string zero length") {
using placement_type = mapnik::markers_point_placement<va_type, detector_type>; using placement_type = mapnik::markers_point_placement<va_type, detector_type>;
mapnik::markers_placement_params params { mapnik::markers_placement_params params{mapnik::box2d<double>(0, 0, 10, 10),
mapnik::box2d<double>(0, 0, 10, 10),
agg::trans_affine(), agg::trans_affine(),
0, NAN, 0, false, false, DIRECTION_AUTO, 1.0 }; 0,
NAN,
0,
false,
false,
DIRECTION_AUTO,
1.0};
placement_type placement(va, detector, params); placement_type placement(va, detector, params);
@ -118,5 +138,4 @@ SECTION("line string zero length") {
CHECK(!placement.get_point(x, y, angle, true)); CHECK(!placement.get_point(x, y, angle, true));
} }
} }

View file

@ -6,11 +6,12 @@
using namespace mapnik; using namespace mapnik;
TEST_CASE("symbolizer") { TEST_CASE("symbolizer")
{
SECTION("enums") { SECTION("enums")
{
try { try
{
marker_multi_policy_enum policy_in = MARKER_WHOLE_MULTI; marker_multi_policy_enum policy_in = MARKER_WHOLE_MULTI;
REQUIRE(policy_in == MARKER_WHOLE_MULTI); REQUIRE(policy_in == MARKER_WHOLE_MULTI);
markers_symbolizer sym; markers_symbolizer sym;
@ -18,12 +19,10 @@ SECTION("enums") {
REQUIRE(sym.properties.count(keys::markers_multipolicy) == static_cast<unsigned long>(1)); REQUIRE(sym.properties.count(keys::markers_multipolicy) == static_cast<unsigned long>(1));
marker_multi_policy_enum policy_out = get<mapnik::marker_multi_policy_enum>(sym, keys::markers_multipolicy); marker_multi_policy_enum policy_out = get<mapnik::marker_multi_policy_enum>(sym, keys::markers_multipolicy);
REQUIRE(policy_out == MARKER_WHOLE_MULTI); REQUIRE(policy_out == MARKER_WHOLE_MULTI);
} } catch (std::exception const& ex)
catch (std::exception const & ex)
{ {
std::clog << ex.what() << std::endl; std::clog << ex.what() << std::endl;
REQUIRE(false); REQUIRE(false);
} }
} }
} }

View file

@ -11,8 +11,10 @@ TEST_CASE("nested script runs")
std::size_t size = 0; std::size_t size = 0;
while (runs.next()) while (runs.next())
{ {
if (count & 1) CHECK(runs.getScriptCode() == USCRIPT_CYRILLIC); if (count & 1)
else CHECK(runs.getScriptCode() == USCRIPT_LATIN); CHECK(runs.getScriptCode() == USCRIPT_CYRILLIC);
else
CHECK(runs.getScriptCode() == USCRIPT_LATIN);
size += runs.getScriptEnd() - runs.getScriptStart(); size += runs.getScriptEnd() - runs.getScriptStart();
++count; ++count;
} }

View file

@ -9,8 +9,11 @@ namespace {
using mapnik::util::from_u8string; using mapnik::util::from_u8string;
void test_shaping( mapnik::font_set const& fontset, mapnik::face_manager& fm, void test_shaping(mapnik::font_set const& fontset,
std::vector<std::pair<unsigned, unsigned>> const& expected, char const* str, bool debug = false) mapnik::face_manager& fm,
std::vector<std::pair<unsigned, unsigned>> const& expected,
char const* str,
bool debug = false)
{ {
mapnik::transcoder tr("utf8"); mapnik::transcoder tr("utf8");
std::map<unsigned, double> width_map; std::map<unsigned, double> width_map;
@ -25,18 +28,17 @@ void test_shaping( mapnik::font_set const& fontset, mapnik::face_manager& fm,
itemizer.add_text(ustr, props); itemizer.add_text(ustr, props);
mapnik::text_line line(0, length); mapnik::text_line line(0, length);
mapnik::harfbuzz_shaper::shape_text(line, itemizer, mapnik::harfbuzz_shaper::shape_text(line, itemizer, width_map, fm, scale_factor);
width_map,
fm,
scale_factor);
std::size_t index = 0; std::size_t index = 0;
for (auto const& g : line) for (auto const& g : line)
{ {
if (debug) if (debug)
{ {
if (index++ > 0) std::cerr << ","; if (index++ > 0)
std::cerr << "{" << g.glyph_index << ", " << g.char_index std::cerr << ",";
std::cerr << "{" << g.glyph_index << ", "
<< g.char_index
//<< ", " << g.face->family_name() << ":" << g.face->style_name() //<< ", " << g.face->family_name() << ":" << g.face->style_name()
<< "}"; << "}";
} }
@ -50,7 +52,7 @@ void test_shaping( mapnik::font_set const& fontset, mapnik::face_manager& fm,
} }
} }
} }
} } // namespace
TEST_CASE("shaping") TEST_CASE("shaping")
{ {
@ -93,12 +95,10 @@ TEST_CASE("shaping")
{ {
// "ⵃⴰⵢ ⵚⵉⵏⴰⵄⵉ الحي الصناعي" // "ⵃⴰⵢ ⵚⵉⵏⴰⵄⵉ الحي الصناعي"
std::vector<std::pair<unsigned, unsigned>> expected = std::vector<std::pair<unsigned, unsigned>> expected = {
{{0, 0}, {0, 1}, {0, 2}, {3, 3}, {0, 4}, {0, 5}, {0, 6}, {0, 7}, {0, 0}, {0, 1}, {0, 2}, {3, 3}, {0, 4}, {0, 5}, {0, 6}, {0, 7},
{0, 8}, {0, 9}, {3, 10}, {509, 22}, {481, 21}, {438, 20}, {503, 19}, {0, 8}, {0, 9}, {3, 10}, {509, 22}, {481, 21}, {438, 20}, {503, 19}, {470, 18},
{470, 18}, {496, 17}, {43, 16}, {3, 15}, {509, 14}, {454, 13}, {496, 12}, {43, 11}}; {496, 17}, {43, 16}, {3, 15}, {509, 14}, {454, 13}, {496, 12}, {43, 11}};
test_shaping(fontset, fm, expected, from_u8string(u8"ⵃⴰⵢ ⵚⵉⵏⴰⵄⵉ الحي الصناعي").c_str()); test_shaping(fontset, fm, expected, from_u8string(u8"ⵃⴰⵢ ⵚⵉⵏⴰⵄⵉ الحي الصناعي").c_str());
} }
} }

View file

@ -3,10 +3,10 @@
#include <mapnik/util/char_array_buffer.hpp> #include <mapnik/util/char_array_buffer.hpp>
#include <istream> #include <istream>
TEST_CASE("char_array_buffer") { TEST_CASE("char_array_buffer")
{
SECTION("std::istream seekg, tellg") { SECTION("std::istream seekg, tellg")
{
const std::size_t buffer_size = 66; const std::size_t buffer_size = 66;
char buffer[buffer_size]; char buffer[buffer_size];
mapnik::util::char_array_buffer array_buff(buffer, buffer_size); mapnik::util::char_array_buffer array_buff(buffer, buffer_size);

View file

@ -33,15 +33,15 @@ std::string dump_path(T & path)
path.rewind(0); path.rewind(0);
while ((cmd = path.vertex(&x, &y)) != mapnik::SEG_END) while ((cmd = path.vertex(&x, &y)) != mapnik::SEG_END)
{ {
if (idx > 0) s << ","; if (idx > 0)
s << ",";
s << x << " " << y << " " << cmd; s << x << " " << y << " " << cmd;
idx++; idx++;
} }
return s.str(); return s.str();
} }
std::string clip_line(mapnik::box2d<double> const& bbox, std::string clip_line(mapnik::box2d<double> const& bbox, mapnik::path_type const& path)
mapnik::path_type const& path)
{ {
using line_clipper = agg::conv_clip_polyline<mapnik::vertex_adapter>; using line_clipper = agg::conv_clip_polyline<mapnik::vertex_adapter>;
mapnik::vertex_adapter va(path); mapnik::vertex_adapter va(path);
@ -50,8 +50,8 @@ std::string clip_line(mapnik::box2d<double> const& bbox,
return dump_path(clipped); return dump_path(clipped);
} }
void parse_geom(mapnik::path_type & path, void parse_geom(mapnik::path_type& path, std::string const& geom_string)
std::string const& geom_string) { {
std::vector<std::string> vertices; std::vector<std::string> vertices;
boost::split(vertices, geom_string, boost::is_any_of(",")); boost::split(vertices, geom_string, boost::is_any_of(","));
for (std::string const& vert : vertices) for (std::string const& vert : vertices)
@ -65,9 +65,8 @@ void parse_geom(mapnik::path_type & path,
double x = 0; double x = 0;
double y = 0; double y = 0;
int c = 0; int c = 0;
if (mapnik::util::string2double(commands[0],x) if (mapnik::util::string2double(commands[0], x) && mapnik::util::string2double(commands[1], y) &&
&& mapnik::util::string2double(commands[1],y) mapnik::util::string2int(commands[2], c))
&& mapnik::util::string2int(commands[2],c))
{ {
path.push_vertex(x, y, (mapnik::CommandType)c); path.push_vertex(x, y, (mapnik::CommandType)c);
} }
@ -78,12 +77,12 @@ void parse_geom(mapnik::path_type & path,
} }
} }
TEST_CASE("clipping") { TEST_CASE("clipping")
{
SECTION("lines") { SECTION("lines")
{
try { try
{
std::string filename("test/unit/data/cases.txt"); std::string filename("test/unit/data/cases.txt");
std::ifstream stream(filename.c_str(), std::ios_base::in | std::ios_base::binary); std::ifstream stream(filename.c_str(), std::ios_base::in | std::ios_base::binary);
if (!stream.is_open()) if (!stream.is_open())
@ -92,12 +91,14 @@ SECTION("lines") {
std::string csv_line; std::string csv_line;
while (std::getline(stream, csv_line, '\n')) while (std::getline(stream, csv_line, '\n'))
{ {
if (csv_line.empty() || csv_line[0] == '#') continue; if (csv_line.empty() || csv_line[0] == '#')
continue;
std::vector<std::string> parts; std::vector<std::string> parts;
boost::split(parts, csv_line, boost::is_any_of(";")); boost::split(parts, csv_line, boost::is_any_of(";"));
// first part is clipping box // first part is clipping box
mapnik::box2d<double> bbox; mapnik::box2d<double> bbox;
if (!bbox.from_string(parts[0])) { if (!bbox.from_string(parts[0]))
{
throw std::runtime_error(std::string("could not parse bbox '") + parts[0] + "'"); throw std::runtime_error(std::string("could not parse bbox '") + parts[0] + "'");
} }
// second part is input geometry // second part is input geometry
@ -108,12 +109,9 @@ SECTION("lines") {
REQUIRE(clip_line(bbox, path) == mapnik::util::trim_copy(parts[2])); REQUIRE(clip_line(bbox, path) == mapnik::util::trim_copy(parts[2]));
} }
stream.close(); stream.close();
} } catch (std::exception const& ex)
catch (std::exception const& ex)
{ {
std::cerr << ex.what() << "\n"; std::cerr << ex.what() << "\n";
} }
} }
} }

View file

@ -9,24 +9,25 @@
namespace offset_test { namespace offset_test {
TEST_CASE("extend converter") { TEST_CASE("extend converter")
{
SECTION("empty") { SECTION("empty")
{
try try
{ {
fake_path path = {}; fake_path path = {};
mapnik::extend_converter<fake_path> c(path, 1000); mapnik::extend_converter<fake_path> c(path, 1000);
double x, y; double x, y;
REQUIRE(c.vertex(&x, &y) == mapnik::SEG_END); REQUIRE(c.vertex(&x, &y) == mapnik::SEG_END);
} } catch (std::exception const& ex)
catch (std::exception const& ex)
{ {
std::cerr << ex.what() << "\n"; std::cerr << ex.what() << "\n";
REQUIRE(false); REQUIRE(false);
} }
} }
SECTION("one point") { SECTION("one point")
{
try try
{ {
fake_path path = {0, 0}; fake_path path = {0, 0};
@ -37,15 +38,15 @@ SECTION("one point") {
REQUIRE(y == 0); REQUIRE(y == 0);
REQUIRE(c.vertex(&x, &y) == mapnik::SEG_END); REQUIRE(c.vertex(&x, &y) == mapnik::SEG_END);
REQUIRE(c.vertex(&x, &y) == mapnik::SEG_END); REQUIRE(c.vertex(&x, &y) == mapnik::SEG_END);
} } catch (std::exception const& ex)
catch (std::exception const& ex)
{ {
std::cerr << ex.what() << "\n"; std::cerr << ex.what() << "\n";
REQUIRE(false); REQUIRE(false);
} }
} }
SECTION("two points") { SECTION("two points")
{
try try
{ {
fake_path path = {0, 0, 1, 0}; fake_path path = {0, 0, 1, 0};
@ -58,15 +59,15 @@ SECTION("two points") {
REQUIRE(x == 1001); REQUIRE(x == 1001);
REQUIRE(y == 0); REQUIRE(y == 0);
REQUIRE(c.vertex(&x, &y) == mapnik::SEG_END); REQUIRE(c.vertex(&x, &y) == mapnik::SEG_END);
} } catch (std::exception const& ex)
catch (std::exception const& ex)
{ {
std::cerr << ex.what() << "\n"; std::cerr << ex.what() << "\n";
REQUIRE(false); REQUIRE(false);
} }
} }
SECTION("three points") { SECTION("three points")
{
try try
{ {
fake_path path = {0, 0, 1, 0, 2, 0}; fake_path path = {0, 0, 1, 0, 2, 0};
@ -82,15 +83,15 @@ SECTION("three points") {
REQUIRE(x == 1002); REQUIRE(x == 1002);
REQUIRE(y == 0); REQUIRE(y == 0);
REQUIRE(c.vertex(&x, &y) == mapnik::SEG_END); REQUIRE(c.vertex(&x, &y) == mapnik::SEG_END);
} } catch (std::exception const& ex)
catch (std::exception const& ex)
{ {
std::cerr << ex.what() << "\n"; std::cerr << ex.what() << "\n";
REQUIRE(false); REQUIRE(false);
} }
} }
SECTION("more points") { SECTION("more points")
{
try try
{ {
fake_path path = {0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0}; fake_path path = {0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0};
@ -115,14 +116,12 @@ SECTION("more points") {
REQUIRE(x == 1005); REQUIRE(x == 1005);
REQUIRE(y == 0); REQUIRE(y == 0);
REQUIRE(c.vertex(&x, &y) == mapnik::SEG_END); REQUIRE(c.vertex(&x, &y) == mapnik::SEG_END);
} } catch (std::exception const& ex)
catch (std::exception const& ex)
{ {
std::cerr << ex.what() << "\n"; std::cerr << ex.what() << "\n";
REQUIRE(false); REQUIRE(false);
} }
} }
} }
} } // namespace offset_test

View file

@ -27,8 +27,7 @@
#include <vector> #include <vector>
#include <tuple> #include <tuple>
namespace detail namespace detail {
{
template<typename T> template<typename T>
struct fake_path struct fake_path
@ -40,13 +39,11 @@ struct fake_path
fake_path(std::initializer_list<T> l) fake_path(std::initializer_list<T> l)
: fake_path(l.begin(), l.size()) : fake_path(l.begin(), l.size())
{ {}
}
fake_path(std::vector<T> const& v, bool make_invalid = false) fake_path(std::vector<T> const& v, bool make_invalid = false)
: fake_path(v.begin(), v.size(), make_invalid) : fake_path(v.begin(), v.size(), make_invalid)
{ {}
}
template<typename Itr> template<typename Itr>
fake_path(Itr itr, size_t sz, bool make_invalid = false) fake_path(Itr itr, size_t sz, bool make_invalid = false)
@ -81,13 +78,9 @@ struct fake_path
return cmd; return cmd;
} }
void rewind(unsigned) void rewind(unsigned) { itr_ = vertices_.begin(); }
{
itr_ = vertices_.begin();
}
}; };
} } // namespace detail
using fake_path = detail::fake_path<double>; using fake_path = detail::fake_path<double>;

View file

@ -9,8 +9,7 @@
// stl // stl
#include <iostream> #include <iostream>
double dist(mapnik::pixel_position const &a, double dist(mapnik::pixel_position const& a, mapnik::pixel_position const& b)
mapnik::pixel_position const &b)
{ {
mapnik::pixel_position d = a - b; mapnik::pixel_position d = a - b;
return std::sqrt(d.x * d.x + d.y * d.y); return std::sqrt(d.x * d.x + d.y * d.y);
@ -22,51 +21,64 @@ void test_simple_segment(double const &offset)
fake_path path = {0, 0, 1, 0}, off_path = {0, offset, 1, offset}; fake_path path = {0, 0, 1, 0}, off_path = {0, offset, 1, offset};
mapnik::vertex_cache vc(path), off_vc(off_path); mapnik::vertex_cache vc(path), off_vc(off_path);
vc.reset(); vc.next_subpath(); vc.reset();
off_vc.reset(); off_vc.next_subpath(); vc.next_subpath();
off_vc.reset();
off_vc.next_subpath();
while (vc.move(dx)) { while (vc.move(dx))
{
double pos = vc.linear_position(); double pos = vc.linear_position();
double off_pos = off_vc.position_closest_to(vc.current_position()); double off_pos = off_vc.position_closest_to(vc.current_position());
REQUIRE(std::abs(pos - off_pos) < 1.0e-6); REQUIRE(std::abs(pos - off_pos) < 1.0e-6);
} }
} }
void test_straight_line(double const &offset) { void test_straight_line(double const& offset)
{
const double dx = 0.01; const double dx = 0.01;
fake_path path = {0, 0, 0.1, 0, 0.9, 0, 1, 0}, fake_path path = {0, 0, 0.1, 0, 0.9, 0, 1, 0}, off_path = {0, offset, 0.4, offset, 0.6, offset, 1, offset};
off_path = {0, offset, 0.4, offset, 0.6, offset, 1, offset};
mapnik::vertex_cache vc(path), off_vc(off_path); mapnik::vertex_cache vc(path), off_vc(off_path);
vc.reset(); vc.next_subpath(); vc.reset();
off_vc.reset(); off_vc.next_subpath(); vc.next_subpath();
off_vc.reset();
off_vc.next_subpath();
while (vc.move(dx)) { while (vc.move(dx))
{
double pos = vc.linear_position(); double pos = vc.linear_position();
double off_pos = off_vc.position_closest_to(vc.current_position()); double off_pos = off_vc.position_closest_to(vc.current_position());
REQUIRE(std::abs(pos - off_pos) < 1.0e-6); REQUIRE(std::abs(pos - off_pos) < 1.0e-6);
} }
} }
void test_offset_curve(double const &offset) { void test_offset_curve(double const& offset)
{
const double dx = 0.01; const double dx = 0.01;
const double r = (1.0 + offset); const double r = (1.0 + offset);
std::vector<double> pos, off_pos; std::vector<double> pos, off_pos;
const size_t max_i = 1000; const size_t max_i = 1000;
for (size_t i = 0; i <= max_i; ++i) { for (size_t i = 0; i <= max_i; ++i)
{
double x = mapnik::util::pi * double(i) / max_i; double x = mapnik::util::pi * double(i) / max_i;
pos.push_back(-std::cos(x)); pos.push_back(std::sin(x)); pos.push_back(-std::cos(x));
off_pos.push_back(-r * std::cos(x)); off_pos.push_back(r * std::sin(x)); pos.push_back(std::sin(x));
off_pos.push_back(-r * std::cos(x));
off_pos.push_back(r * std::sin(x));
} }
fake_path path(pos), off_path(off_pos); fake_path path(pos), off_path(off_pos);
mapnik::vertex_cache vc(path), off_vc(off_path); mapnik::vertex_cache vc(path), off_vc(off_path);
vc.reset(); vc.next_subpath(); vc.reset();
off_vc.reset(); off_vc.next_subpath(); vc.next_subpath();
off_vc.reset();
off_vc.next_subpath();
while (vc.move(dx)) { while (vc.move(dx))
{
double mpos = vc.linear_position(); double mpos = vc.linear_position();
double moff_pos = off_vc.position_closest_to(vc.current_position()); double moff_pos = off_vc.position_closest_to(vc.current_position());
{ {
@ -80,31 +92,41 @@ void test_offset_curve(double const &offset) {
} }
} }
void test_s_shaped_curve(double const &offset) { void test_s_shaped_curve(double const& offset)
{
const double dx = 0.01; const double dx = 0.01;
const double r = (1.0 + offset); const double r = (1.0 + offset);
const double r2 = (1.0 - offset); const double r2 = (1.0 - offset);
std::vector<double> pos, off_pos; std::vector<double> pos, off_pos;
const size_t max_i = 1000; const size_t max_i = 1000;
for (size_t i = 0; i <= max_i; ++i) { for (size_t i = 0; i <= max_i; ++i)
{
double x = mapnik::util::pi * double(i) / max_i; double x = mapnik::util::pi * double(i) / max_i;
pos.push_back(-std::cos(x) - 1); pos.push_back(std::sin(x)); pos.push_back(-std::cos(x) - 1);
off_pos.push_back(-r * std::cos(x) - 1); off_pos.push_back(r * std::sin(x)); pos.push_back(std::sin(x));
off_pos.push_back(-r * std::cos(x) - 1);
off_pos.push_back(r * std::sin(x));
} }
for (size_t i = 0; i <= max_i; ++i) { for (size_t i = 0; i <= max_i; ++i)
{
double x = mapnik::util::pi * double(i) / max_i; double x = mapnik::util::pi * double(i) / max_i;
pos.push_back(-std::cos(x) + 1); pos.push_back(-std::sin(x)); pos.push_back(-std::cos(x) + 1);
off_pos.push_back(-r2 * std::cos(x) + 1); off_pos.push_back(-r2 * std::sin(x)); pos.push_back(-std::sin(x));
off_pos.push_back(-r2 * std::cos(x) + 1);
off_pos.push_back(-r2 * std::sin(x));
} }
fake_path path(pos), off_path(off_pos); fake_path path(pos), off_path(off_pos);
mapnik::vertex_cache vc(path), off_vc(off_path); mapnik::vertex_cache vc(path), off_vc(off_path);
vc.reset(); vc.next_subpath(); vc.reset();
off_vc.reset(); off_vc.next_subpath(); vc.next_subpath();
off_vc.reset();
off_vc.next_subpath();
while (vc.move(dx)) { while (vc.move(dx))
{
double moff_pos = off_vc.position_closest_to(vc.current_position()); double moff_pos = off_vc.position_closest_to(vc.current_position());
{ {
mapnik::vertex_cache::scoped_state s(off_vc); mapnik::vertex_cache::scoped_state s(off_vc);
@ -114,13 +136,15 @@ void test_s_shaped_curve(double const &offset) {
} }
} }
TEST_CASE("offsets") { TEST_CASE("offsets")
{
SECTION("line") { SECTION("line")
try { {
try
{
std::vector<double> offsets = {0.01, 0.02, 0.1, 0.2}; std::vector<double> offsets = {0.01, 0.02, 0.1, 0.2};
for (double offset : offsets) { for (double offset : offsets)
{
// test simple straight line segment - should be easy to // test simple straight line segment - should be easy to
// find the correspondance here. // find the correspondance here.
test_simple_segment(offset); test_simple_segment(offset);
@ -137,8 +161,7 @@ SECTION("line") {
// curve. // curve.
test_s_shaped_curve(offset); test_s_shaped_curve(offset);
} }
} } catch (std::exception const& ex)
catch (std::exception const& ex)
{ {
std::cerr << ex.what() << "\n"; std::cerr << ex.what() << "\n";
REQUIRE(false); REQUIRE(false);

View file

@ -45,7 +45,6 @@ void test_invalid_segment(double const &offset)
REQUIRE(off_path_new.vertex(&x0, &y0) == mapnik::SEG_END); REQUIRE(off_path_new.vertex(&x0, &y0) == mapnik::SEG_END);
} }
void test_simple_segment(double const& offset) void test_simple_segment(double const& offset)
{ {
fake_path path = {0, 0, 1, 0}, off_path = {0, offset, 1, offset}; fake_path path = {0, 0, 1, 0}, off_path = {0, offset, 1, offset};
@ -56,7 +55,8 @@ void test_simple_segment(double const &offset)
unsigned cmd0 = off_path_new.vertex(&x0, &y0); unsigned cmd0 = off_path_new.vertex(&x0, &y0);
unsigned cmd1 = off_path.vertex(&x1, &y1); unsigned cmd1 = off_path.vertex(&x1, &y1);
double d = dist(x0, y0, x1, y1); double d = dist(x0, y0, x1, y1);
while (true) { while (true)
{
if (d > (std::abs(offset) + DELTA_BUFF)) if (d > (std::abs(offset) + DELTA_BUFF))
{ {
cmd0 = off_path_new.vertex(&x0, &y0); cmd0 = off_path_new.vertex(&x0, &y0);
@ -67,11 +67,11 @@ void test_simple_segment(double const &offset)
else else
{ {
REQUIRE(d <= (std::abs(offset) + DELTA_BUFF)); REQUIRE(d <= (std::abs(offset) + DELTA_BUFF));
} }
cmd1 = off_path.vertex(&x1, &y1); cmd1 = off_path.vertex(&x1, &y1);
if (cmd1 == mapnik::SEG_END) break; if (cmd1 == mapnik::SEG_END)
break;
d = dist(x0, y0, x1, y1); d = dist(x0, y0, x1, y1);
bool done = false; bool done = false;
while (d <= (std::abs(offset) + DELTA_BUFF)) while (d <= (std::abs(offset) + DELTA_BUFF))
@ -84,13 +84,14 @@ void test_simple_segment(double const &offset)
break; break;
} }
} }
if (done) break; if (done)
break;
} }
} }
void test_straight_line(double const &offset) { void test_straight_line(double const& offset)
fake_path path = {0, 0, 1, 0, 9, 0, 10, 0}, {
off_path = {0, offset, 1, offset, 9, offset, 10, offset}; fake_path path = {0, 0, 1, 0, 9, 0, 10, 0}, off_path = {0, offset, 1, offset, 9, offset, 10, offset};
mapnik::offset_converter<fake_path> off_path_new(path); mapnik::offset_converter<fake_path> off_path_new(path);
off_path_new.set_offset(offset); off_path_new.set_offset(offset);
@ -98,7 +99,8 @@ void test_straight_line(double const &offset) {
unsigned cmd0 = off_path_new.vertex(&x0, &y0); unsigned cmd0 = off_path_new.vertex(&x0, &y0);
unsigned cmd1 = off_path.vertex(&x1, &y1); unsigned cmd1 = off_path.vertex(&x1, &y1);
double d = dist(x0, y0, x1, y1); double d = dist(x0, y0, x1, y1);
while (true) { while (true)
{
if (d > (std::abs(offset) + DELTA_BUFF)) if (d > (std::abs(offset) + DELTA_BUFF))
{ {
cmd0 = off_path_new.vertex(&x0, &y0); cmd0 = off_path_new.vertex(&x0, &y0);
@ -109,7 +111,6 @@ void test_straight_line(double const &offset) {
else else
{ {
REQUIRE(d <= (std::abs(offset) + DELTA_BUFF)); REQUIRE(d <= (std::abs(offset) + DELTA_BUFF));
} }
cmd1 = off_path.vertex(&x1, &y1); cmd1 = off_path.vertex(&x1, &y1);
@ -125,19 +126,24 @@ void test_straight_line(double const &offset) {
break; break;
} }
} }
if (done) break; if (done)
break;
} }
} }
void test_offset_curve(double const &offset) { void test_offset_curve(double const& offset)
{
const double r = (1.0 + offset); const double r = (1.0 + offset);
std::vector<double> pos, off_pos; std::vector<double> pos, off_pos;
const size_t max_i = 1000; const size_t max_i = 1000;
for (size_t i = 0; i <= max_i; ++i) { for (size_t i = 0; i <= max_i; ++i)
{
double x = mapnik::util::pi * double(i) / max_i; double x = mapnik::util::pi * double(i) / max_i;
pos.push_back(-std::cos(x)); pos.push_back(std::sin(x)); pos.push_back(-std::cos(x));
off_pos.push_back(-r * std::cos(x)); off_pos.push_back(r * std::sin(x)); pos.push_back(std::sin(x));
off_pos.push_back(-r * std::cos(x));
off_pos.push_back(r * std::sin(x));
} }
fake_path path(pos), off_path(off_pos); fake_path path(pos), off_path(off_pos);
@ -148,7 +154,8 @@ void test_offset_curve(double const &offset) {
unsigned cmd0 = off_path_new.vertex(&x0, &y0); unsigned cmd0 = off_path_new.vertex(&x0, &y0);
unsigned cmd1 = off_path.vertex(&x1, &y1); unsigned cmd1 = off_path.vertex(&x1, &y1);
double d = dist(x0, y0, x1, y1); double d = dist(x0, y0, x1, y1);
while (true) { while (true)
{
if (d > (std::abs(offset) + DELTA_BUFF)) if (d > (std::abs(offset) + DELTA_BUFF))
{ {
cmd0 = off_path_new.vertex(&x0, &y0); cmd0 = off_path_new.vertex(&x0, &y0);
@ -159,7 +166,6 @@ void test_offset_curve(double const &offset) {
else else
{ {
REQUIRE(d <= (std::abs(offset) + DELTA_BUFF)); REQUIRE(d <= (std::abs(offset) + DELTA_BUFF));
} }
cmd1 = off_path.vertex(&x1, &y1); cmd1 = off_path.vertex(&x1, &y1);
@ -175,25 +181,33 @@ void test_offset_curve(double const &offset) {
break; break;
} }
} }
if (done) break; if (done)
break;
} }
} }
void test_s_shaped_curve(double const &offset) { void test_s_shaped_curve(double const& offset)
{
const double r = (1.0 + offset); const double r = (1.0 + offset);
const double r2 = (1.0 - offset); const double r2 = (1.0 - offset);
std::vector<double> pos, off_pos; std::vector<double> pos, off_pos;
const size_t max_i = 1000; const size_t max_i = 1000;
for (size_t i = 0; i <= max_i; ++i) { for (size_t i = 0; i <= max_i; ++i)
{
double x = mapnik::util::pi * double(i) / max_i; double x = mapnik::util::pi * double(i) / max_i;
pos.push_back(-std::cos(x) - 1); pos.push_back(std::sin(x)); pos.push_back(-std::cos(x) - 1);
off_pos.push_back(-r * std::cos(x) - 1); off_pos.push_back(r * std::sin(x)); pos.push_back(std::sin(x));
off_pos.push_back(-r * std::cos(x) - 1);
off_pos.push_back(r * std::sin(x));
} }
for (size_t i = 0; i <= max_i; ++i) { for (size_t i = 0; i <= max_i; ++i)
{
double x = mapnik::util::pi * double(i) / max_i; double x = mapnik::util::pi * double(i) / max_i;
pos.push_back(-std::cos(x) + 1); pos.push_back(-std::sin(x)); pos.push_back(-std::cos(x) + 1);
off_pos.push_back(-r2 * std::cos(x) + 1); off_pos.push_back(-r2 * std::sin(x)); pos.push_back(-std::sin(x));
off_pos.push_back(-r2 * std::cos(x) + 1);
off_pos.push_back(-r2 * std::sin(x));
} }
fake_path path(pos), off_path(off_pos); fake_path path(pos), off_path(off_pos);
@ -204,7 +218,8 @@ void test_s_shaped_curve(double const &offset) {
unsigned cmd0 = off_path_new.vertex(&x0, &y0); unsigned cmd0 = off_path_new.vertex(&x0, &y0);
unsigned cmd1 = off_path.vertex(&x1, &y1); unsigned cmd1 = off_path.vertex(&x1, &y1);
double d = dist(x0, y0, x1, y1); double d = dist(x0, y0, x1, y1);
while (true) { while (true)
{
if (d > (std::abs(offset) + DELTA_BUFF)) if (d > (std::abs(offset) + DELTA_BUFF))
{ {
cmd0 = off_path_new.vertex(&x0, &y0); cmd0 = off_path_new.vertex(&x0, &y0);
@ -215,7 +230,6 @@ void test_s_shaped_curve(double const &offset) {
else else
{ {
REQUIRE(d <= (std::abs(offset) + DELTA_BUFF)); REQUIRE(d <= (std::abs(offset) + DELTA_BUFF));
} }
cmd1 = off_path.vertex(&x1, &y1); cmd1 = off_path.vertex(&x1, &y1);
@ -231,114 +245,120 @@ void test_s_shaped_curve(double const &offset) {
break; break;
} }
} }
if (done) break; if (done)
break;
} }
} }
} // END NS } // namespace offset_test
TEST_CASE("offset converter") {
SECTION("null segment") {
try {
TEST_CASE("offset converter")
{
SECTION("null segment")
{
try
{
std::vector<double> offsets = {1, -1}; std::vector<double> offsets = {1, -1};
for (double offset : offsets) { for (double offset : offsets)
{
// test simple straight line segment - should be easy to // test simple straight line segment - should be easy to
// find the correspondance here. // find the correspondance here.
offset_test::test_null_segment(offset); offset_test::test_null_segment(offset);
} }
} } catch (std::exception const& ex)
catch (std::exception const& ex)
{ {
std::cerr << ex.what() << "\n"; std::cerr << ex.what() << "\n";
REQUIRE(false); REQUIRE(false);
} }
} }
SECTION("invalid segment") { SECTION("invalid segment")
try { {
try
{
std::vector<double> offsets = {1, -1}; std::vector<double> offsets = {1, -1};
for (double offset : offsets) { for (double offset : offsets)
{
// test simple straight line segment - should be easy to // test simple straight line segment - should be easy to
// find the correspondance here. // find the correspondance here.
offset_test::test_invalid_segment(offset); offset_test::test_invalid_segment(offset);
} }
} } catch (std::exception const& ex)
catch (std::exception const& ex)
{ {
std::cerr << ex.what() << "\n"; std::cerr << ex.what() << "\n";
REQUIRE(false); REQUIRE(false);
} }
} }
SECTION("simple segment")
SECTION("simple segment") { {
try { try
{
std::vector<double> offsets = {1, -1}; std::vector<double> offsets = {1, -1};
for (double offset : offsets) { for (double offset : offsets)
{
// test simple straight line segment - should be easy to // test simple straight line segment - should be easy to
// find the correspondance here. // find the correspondance here.
offset_test::test_simple_segment(offset); offset_test::test_simple_segment(offset);
} }
} } catch (std::exception const& ex)
catch (std::exception const& ex)
{ {
std::cerr << ex.what() << "\n"; std::cerr << ex.what() << "\n";
REQUIRE(false); REQUIRE(false);
} }
} }
SECTION("straight line") { SECTION("straight line")
try { {
try
{
std::vector<double> offsets = {1, -1}; std::vector<double> offsets = {1, -1};
for (double offset : offsets) { for (double offset : offsets)
{
// test straight line consisting of more than one segment. // test straight line consisting of more than one segment.
offset_test::test_straight_line(offset); offset_test::test_straight_line(offset);
} }
} } catch (std::exception const& ex)
catch (std::exception const& ex)
{ {
std::cerr << ex.what() << "\n"; std::cerr << ex.what() << "\n";
REQUIRE(false); REQUIRE(false);
} }
} }
SECTION("curve") { SECTION("curve")
try { {
try
{
std::vector<double> offsets = {1, -1}; std::vector<double> offsets = {1, -1};
for (double offset : offsets) { for (double offset : offsets)
{
offset_test::test_offset_curve(offset); offset_test::test_offset_curve(offset);
} }
} } catch (std::exception const& ex)
catch (std::exception const& ex)
{ {
std::cerr << ex.what() << "\n"; std::cerr << ex.what() << "\n";
REQUIRE(false); REQUIRE(false);
} }
} }
SECTION("s curve") { SECTION("s curve")
try { {
try
{
std::vector<double> offsets = {1, -1}; std::vector<double> offsets = {1, -1};
for (double offset : offsets) { for (double offset : offsets)
{
offset_test::test_s_shaped_curve(offset); offset_test::test_s_shaped_curve(offset);
} }
} } catch (std::exception const& ex)
catch (std::exception const& ex)
{ {
std::cerr << ex.what() << "\n"; std::cerr << ex.what() << "\n";
REQUIRE(false); REQUIRE(false);
} }
} }
SECTION("offsect converter does not skip SEG_MOVETO or SEG_CLOSE vertices") { SECTION("offsect converter does not skip SEG_MOVETO or SEG_CLOSE vertices")
{
const double offset = 0.2; const double offset = 0.2;
fake_path path = {}; fake_path path = {};
@ -381,5 +401,4 @@ SECTION("offsect converter does not skip SEG_MOVETO or SEG_CLOSE vertices") {
CHECK(move_to_count == 2); CHECK(move_to_count == 2);
CHECK(close_count == 2); CHECK(close_count == 2);
} }
} }

View file

@ -41,37 +41,44 @@ void simplify(std::string const& wkt_in, double tolerance, std::string const& me
#endif #endif
} }
TEST_CASE("converters") { TEST_CASE("converters")
{
SECTION("simplify") { SECTION("simplify")
{
simplify(std::string("LineString(0 0,2 2,3 5,4 1,5 0,6 7,7 0)"), simplify(std::string("LineString(0 0,2 2,3 5,4 1,5 0,6 7,7 0)"),
4, "douglas-peucker", 4,
"douglas-peucker",
std::string("LineString(0 0,6 7,7 0)")); std::string("LineString(0 0,6 7,7 0)"));
simplify(std::string("LineString(0 0,2 2,3 5,4 1,5 0,6 7,7 0)"), simplify(std::string("LineString(0 0,2 2,3 5,4 1,5 0,6 7,7 0)"),
2, "douglas-peucker", 2,
"douglas-peucker",
std::string("LineString(0 0,3 5,5 0,6 7,7 0)")); std::string("LineString(0 0,3 5,5 0,6 7,7 0)"));
simplify( std::string("LineString(10 0,9 -4,7 -7,4 -9,0 -10,-4 -9,-7 -7,-9 -4,-10 0,-9 4,-7 7,-4 9,0 10,4 9,7 7,9 4)"), simplify(
4, "douglas-peucker", std::string("LineString(10 0,9 -4,7 -7,4 -9,0 -10,-4 -9,-7 -7,-9 -4,-10 0,-9 4,-7 7,-4 9,0 10,4 9,7 7,9 4)"),
4,
"douglas-peucker",
std::string("LineString(10 0,0 -10,-10 0,0 10,9 4)")); std::string("LineString(10 0,0 -10,-10 0,0 10,9 4)"));
simplify(std::string("LineString(0 0,1 1,2 2,0 10,0 0)"), simplify(std::string("LineString(0 0,1 1,2 2,0 10,0 0)"),
10, "douglas-peucker", 10,
"douglas-peucker",
std::string("LineString(0 0,0 0)")); std::string("LineString(0 0,0 0)"));
simplify(std::string("LineString(0 0,1 1,2 2,0 10,0 0)"), simplify(std::string("LineString(0 0,1 1,2 2,0 10,0 0)"),
8, "douglas-peucker", 8,
"douglas-peucker",
std::string("LineString(0 0,0 10,0 0)")); std::string("LineString(0 0,0 10,0 0)"));
simplify(std::string("LineString(0 0,1 1,2 2,0 10,0 0)"), simplify(std::string("LineString(0 0,1 1,2 2,0 10,0 0)"),
1, "douglas-peucker", 1,
"douglas-peucker",
std::string("LineString(0 0,2 2,0 10,0 0)")); std::string("LineString(0 0,2 2,0 10,0 0)"));
simplify(std::string("LineString(0 0, 1 -1, 2 2, 0 -10, 0 0, -5 7, 4 6)"), simplify(std::string("LineString(0 0, 1 -1, 2 2, 0 -10, 0 0, -5 7, 4 6)"),
3, "douglas-peucker", 3,
"douglas-peucker",
std::string("LineString(0 0,0 -10,-5 7,4 6)")); std::string("LineString(0 0,0 -10,-5 7,4 6)"));
} }
} }

View file

@ -8,11 +8,11 @@
#include <mapnik/proj_transform.hpp> #include <mapnik/proj_transform.hpp>
#include <mapnik/projection.hpp> #include <mapnik/projection.hpp>
TEST_CASE("transform_path_adapter")
TEST_CASE("transform_path_adapter") { {
#ifdef MAPNIK_USE_PROJ #ifdef MAPNIK_USE_PROJ
SECTION("polygon closing - epsg 2330") { SECTION("polygon closing - epsg 2330")
{
mapnik::geometry::polygon<double> g; mapnik::geometry::polygon<double> g;
g.emplace_back(); g.emplace_back();
auto& exterior = g.back(); auto& exterior = g.back();
@ -64,7 +64,8 @@ SECTION("polygon closing - epsg 2330") {
CHECK(y == 0); CHECK(y == 0);
} }
SECTION("polygon closing - epsg 32633") { SECTION("polygon closing - epsg 32633")
{
mapnik::geometry::polygon<double> g; mapnik::geometry::polygon<double> g;
g.emplace_back(); g.emplace_back();
auto& exterior = g.back(); auto& exterior = g.back();

View file

@ -3,9 +3,10 @@
#include <mapnik/vertex_adapters.hpp> #include <mapnik/vertex_adapters.hpp>
#include <mapnik/geometry/correct.hpp> #include <mapnik/geometry/correct.hpp>
TEST_CASE("vertex_adapters") { TEST_CASE("vertex_adapters")
{
SECTION("polygon") { SECTION("polygon")
{
mapnik::geometry::polygon<double> g; mapnik::geometry::polygon<double> g;
g.emplace_back(); g.emplace_back();
g.back().emplace_back(1, 1); g.back().emplace_back(1, 1);
@ -45,7 +46,8 @@ SECTION("polygon") {
REQUIRE(y == 0); REQUIRE(y == 0);
} }
SECTION("polygon with hole") { SECTION("polygon with hole")
{
mapnik::geometry::polygon<double> g; mapnik::geometry::polygon<double> g;
g.emplace_back(); g.emplace_back();
g.back().emplace_back(0, 0); g.back().emplace_back(0, 0);
@ -268,7 +270,8 @@ SECTION("polygon with hole") {
REQUIRE(y == 0); REQUIRE(y == 0);
} }
SECTION("polygon with empty exterior ring") { SECTION("polygon with empty exterior ring")
{
mapnik::geometry::polygon<double> g; mapnik::geometry::polygon<double> g;
g.emplace_back(); g.emplace_back();
@ -282,7 +285,8 @@ SECTION("polygon with empty exterior ring") {
CHECK(y == Approx(0)); CHECK(y == Approx(0));
} }
SECTION("polygon with empty interior ring") { SECTION("polygon with empty interior ring")
{
mapnik::geometry::polygon<double> g; mapnik::geometry::polygon<double> g;
g.emplace_back(); g.emplace_back();
g.back().emplace_back(-1, -1); g.back().emplace_back(-1, -1);
@ -333,5 +337,4 @@ SECTION("polygon with empty interior ring") {
REQUIRE(x == Approx(0)); REQUIRE(x == Approx(0));
REQUIRE(y == Approx(0)); REQUIRE(y == Approx(0));
} }
} }

View file

@ -34,12 +34,14 @@
#include <mapnik/geometry/box2d.hpp> #include <mapnik/geometry/box2d.hpp>
namespace visual_tests namespace visual_tests {
{
struct map_size struct map_size
{ {
map_size(std::size_t _width, std::size_t _height) : width(_width), height(_height) { } map_size(std::size_t _width, std::size_t _height)
: width(_width)
, height(_height)
{}
map_size() {} map_size() {}
std::size_t width = 0; std::size_t width = 0;
std::size_t height = 0; std::size_t height = 0;
@ -47,12 +49,14 @@ struct map_size
struct config struct config
{ {
config() : status(true), config()
scales({ 1.0, 2.0 }), : status(true)
sizes({ { 500, 100 } }), , scales({1.0, 2.0})
tiles({ { 1, 1 } }), , sizes({{500, 100}})
bbox(), , tiles({{1, 1}})
ignored_renderers() { } , bbox()
, ignored_renderers()
{}
bool status; bool status;
std::vector<double> scales; std::vector<double> scales;
@ -62,13 +66,7 @@ struct config
std::set<std::string> ignored_renderers; std::set<std::string> ignored_renderers;
}; };
enum result_state : std::uint8_t enum result_state : std::uint8_t { STATE_OK, STATE_FAIL, STATE_ERROR, STATE_OVERWRITE };
{
STATE_OK,
STATE_FAIL,
STATE_ERROR,
STATE_OVERWRITE
};
struct result struct result
{ {
@ -87,6 +85,6 @@ struct result
using result_list = std::vector<result>; using result_list = std::vector<result>;
} } // namespace visual_tests
#endif #endif

View file

@ -29,19 +29,14 @@ MAPNIK_DISABLE_WARNING_PUSH
#include <boost/fusion/include/adapt_struct.hpp> #include <boost/fusion/include/adapt_struct.hpp>
MAPNIK_DISABLE_WARNING_POP MAPNIK_DISABLE_WARNING_POP
BOOST_FUSION_ADAPT_STRUCT ( BOOST_FUSION_ADAPT_STRUCT(visual_tests::map_size, (std::size_t, width)(std::size_t, height))
visual_tests::map_size,
(std::size_t, width)
(std::size_t, height)
)
namespace visual_tests { namespace visual_tests {
namespace x3 = boost::spirit::x3; namespace x3 = boost::spirit::x3;
using x3::ulong_; using x3::ulong_;
auto const map_size_rule = x3::rule<class map_size_rule, map_size>{} = ulong_ >> ',' >> ulong_; auto const map_size_rule = x3::rule<class map_size_rule, map_size>{} = ulong_ >> ',' >> ulong_;
auto const map_sizes_grammar = x3::rule<class map_sizes_grammar_type, std::vector<map_size> > {} = auto const map_sizes_grammar = x3::rule<class map_sizes_grammar_type, std::vector<map_size>>{} = map_size_rule % ';';
map_size_rule % ';' ;
void parse_map_sizes(std::string const& str, std::vector<map_size>& sizes) void parse_map_sizes(std::string const& str, std::vector<map_size>& sizes)
{ {
@ -54,4 +49,4 @@ void parse_map_sizes(std::string const & str, std::vector<map_size> & sizes)
} }
} }
} } // namespace visual_tests

View file

@ -60,8 +60,7 @@
// boost // boost
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
namespace visual_tests namespace visual_tests {
{
template<typename ImageType> template<typename ImageType>
struct raster_renderer_base struct raster_renderer_base
@ -156,9 +155,7 @@ using surface_create_type = cairo_surface_t *(&)(cairo_write_func_t, void *, dou
template<surface_create_type SurfaceCreateFunction> template<surface_create_type SurfaceCreateFunction>
struct cairo_vector_renderer : vector_renderer_base struct cairo_vector_renderer : vector_renderer_base
{ {
static cairo_status_t write(void *closure, static cairo_status_t write(void* closure, const unsigned char* data, unsigned int length)
const unsigned char *data,
unsigned int length)
{ {
std::ostringstream& ss = *reinterpret_cast<std::ostringstream*>(closure); std::ostringstream& ss = *reinterpret_cast<std::ostringstream*>(closure);
ss.write(reinterpret_cast<char const*>(data), length); ss.write(reinterpret_cast<char const*>(data), length);
@ -168,8 +165,7 @@ struct cairo_vector_renderer : vector_renderer_base
image_type render(mapnik::Map const& map, double scale_factor) const image_type render(mapnik::Map const& map, double scale_factor) const
{ {
std::ostringstream ss(std::stringstream::binary); std::ostringstream ss(std::stringstream::binary);
mapnik::cairo_surface_ptr image_surface( mapnik::cairo_surface_ptr image_surface(SurfaceCreateFunction(write, &ss, map.width(), map.height()),
SurfaceCreateFunction(write, &ss, map.width(), map.height()),
mapnik::cairo_surface_closer()); mapnik::cairo_surface_closer());
mapnik::cairo_ptr image_context(mapnik::create_context(image_surface)); mapnik::cairo_ptr image_context(mapnik::create_context(image_surface));
mapnik::cairo_renderer<mapnik::cairo_ptr> ren(map, image_context, scale_factor); mapnik::cairo_renderer<mapnik::cairo_ptr> ren(map, image_context, scale_factor);
@ -180,10 +176,7 @@ struct cairo_vector_renderer : vector_renderer_base
}; };
#ifdef CAIRO_HAS_SVG_SURFACE #ifdef CAIRO_HAS_SVG_SURFACE
inline cairo_surface_t *create_svg_1_2(cairo_write_func_t write_func, inline cairo_surface_t* create_svg_1_2(cairo_write_func_t write_func, void* closure, double width, double height)
void *closure,
double width,
double height)
{ {
cairo_surface_t* surface = cairo_svg_surface_create_for_stream(write_func, closure, width, height); cairo_surface_t* surface = cairo_svg_surface_create_for_stream(write_func, closure, width, height);
cairo_svg_surface_restrict_to_version(surface, CAIRO_SVG_VERSION_1_2); cairo_svg_surface_restrict_to_version(surface, CAIRO_SVG_VERSION_1_2);
@ -310,14 +303,13 @@ public:
using image_type = typename Renderer::image_type; using image_type = typename Renderer::image_type;
renderer(boost::filesystem::path const& _output_dir, boost::filesystem::path const& _reference_dir, bool _overwrite) renderer(boost::filesystem::path const& _output_dir, boost::filesystem::path const& _reference_dir, bool _overwrite)
: ren(), output_dir(_output_dir), reference_dir(_reference_dir), overwrite(_overwrite) : ren()
{ , output_dir(_output_dir)
} , reference_dir(_reference_dir)
, overwrite(_overwrite)
{}
image_type render(mapnik::Map const & map, double scale_factor) const image_type render(mapnik::Map const& map, double scale_factor) const { return ren.render(map, scale_factor); }
{
return ren.render(map, scale_factor);
}
image_type render(mapnik::Map& map, double scale_factor, map_size const& tiles) const image_type render(mapnik::Map& map, double scale_factor, map_size const& tiles) const
{ {
@ -330,8 +322,7 @@ public:
{ {
for (std::size_t tile_x = 0; tile_x < tiles.width; tile_x++) for (std::size_t tile_x = 0; tile_x < tiles.width; tile_x++)
{ {
mapnik::box2d<double> tile_box( mapnik::box2d<double> tile_box(box.minx() + tile_x * tile_box_width,
box.minx() + tile_x * tile_box_width,
box.miny() + tile_y * tile_box_height, box.miny() + tile_y * tile_box_height,
box.minx() + (tile_x + 1) * tile_box_width, box.minx() + (tile_x + 1) * tile_box_width,
box.miny() + (tile_y + 1) * tile_box_height); box.miny() + (tile_y + 1) * tile_box_height);
@ -410,25 +401,31 @@ private:
using renderer_type = mapnik::util::variant<renderer<agg_renderer> using renderer_type = mapnik::util::variant<renderer<agg_renderer>
#if defined(HAVE_CAIRO) #if defined(HAVE_CAIRO)
,renderer<cairo_renderer> ,
renderer<cairo_renderer>
#ifdef CAIRO_HAS_SVG_SURFACE #ifdef CAIRO_HAS_SVG_SURFACE
,renderer<cairo_svg_renderer> ,
renderer<cairo_svg_renderer>
#endif #endif
#ifdef CAIRO_HAS_PS_SURFACE #ifdef CAIRO_HAS_PS_SURFACE
,renderer<cairo_ps_renderer> ,
renderer<cairo_ps_renderer>
#endif #endif
#ifdef CAIRO_HAS_PDF_SURFACE #ifdef CAIRO_HAS_PDF_SURFACE
,renderer<cairo_pdf_renderer> ,
renderer<cairo_pdf_renderer>
#endif #endif
#endif #endif
#if defined(SVG_RENDERER) #if defined(SVG_RENDERER)
,renderer<svg_renderer> ,
renderer<svg_renderer>
#endif #endif
#if defined(GRID_RENDERER) #if defined(GRID_RENDERER)
,renderer<grid_renderer> ,
renderer<grid_renderer>
#endif #endif
>; >;
} } // namespace visual_tests
#endif #endif

View file

@ -28,8 +28,7 @@
#include "report.hpp" #include "report.hpp"
namespace visual_tests namespace visual_tests {
{
void console_report::report(result const& r) void console_report::report(result const& r)
{ {
@ -64,10 +63,18 @@ unsigned console_report::summary(result_list const & results)
{ {
switch (r.state) switch (r.state)
{ {
case STATE_OK: ok++; break; case STATE_OK:
case STATE_FAIL: fail++; break; ok++;
case STATE_ERROR: error++; break; break;
case STATE_OVERWRITE: overwrite++; break; case STATE_FAIL:
fail++;
break;
case STATE_ERROR:
error++;
break;
case STATE_OVERWRITE:
overwrite++;
break;
} }
if (show_duration) if (show_duration)
@ -85,16 +92,16 @@ unsigned console_report::summary(result_list const & results)
} }
s << std::endl; s << std::endl;
s << "Visual rendering: " << fail << " failed / " << ok << " passed / " s << "Visual rendering: " << fail << " failed / " << ok << " passed / " << overwrite << " overwritten / " << error
<< overwrite << " overwritten / " << error << " errors" << std::endl; << " errors" << std::endl;
if (show_duration) if (show_duration)
{ {
high_resolution_clock::duration total(0); high_resolution_clock::duration total(0);
for (auto const& duration : durations) for (auto const& duration : durations)
{ {
s << duration.first << ": \t" << duration_cast<milliseconds>(duration.second).count() s << duration.first << ": \t" << duration_cast<milliseconds>(duration.second).count() << " milliseconds"
<< " milliseconds" << std::endl; << std::endl;
total += duration.second; total += duration.second;
} }
s << "total: \t" << duration_cast<milliseconds>(total).count() << " milliseconds" << std::endl; s << "total: \t" << duration_cast<milliseconds>(total).count() << " milliseconds" << std::endl;
@ -188,7 +195,7 @@ void html_report::report(result const & r, boost::filesystem::path const & outpu
} }
copy_file(r.reference_image_path, reference); copy_file(r.reference_image_path, reference);
copy_file(r.actual_image_path, actual); copy_file(r.actual_image_path, actual);
// clang-format off
s << "<p>" << r.diff << "</p>\n" s << "<p>" << r.diff << "</p>\n"
"<div class=\"r\">" "<div class=\"r\">"
" <div class=\"i\">" " <div class=\"i\">"
@ -202,6 +209,7 @@ void html_report::report(result const & r, boost::filesystem::path const & outpu
" </a>\n" " </a>\n"
" </div>\n" " </div>\n"
"</div>\n"; "</div>\n";
// clang-format on
} }
} }
@ -256,4 +264,4 @@ void html_summary(result_list const & results, boost::filesystem::path output_di
report.summary(results, html_root); report.summary(results, html_root);
} }
} } // namespace visual_tests

View file

@ -30,19 +30,19 @@
#include "config.hpp" #include "config.hpp"
namespace visual_tests namespace visual_tests {
{
class console_report class console_report
{ {
public: public:
console_report(bool _show_duration) : s(std::clog), show_duration(_show_duration) console_report(bool _show_duration)
{ : s(std::clog)
} , show_duration(_show_duration)
{}
console_report(std::ostream & _s) : s(_s) console_report(std::ostream& _s)
{ : s(_s)
} {}
void report(result const& r); void report(result const& r);
unsigned summary(result_list const& results); unsigned summary(result_list const& results);
@ -58,13 +58,13 @@ protected:
class console_short_report : public console_report class console_short_report : public console_report
{ {
public: public:
console_short_report(bool _show_duration) : console_report(_show_duration) console_short_report(bool _show_duration)
{ : console_report(_show_duration)
} {}
console_short_report(std::ostream & _s) : console_report(_s) console_short_report(std::ostream& _s)
{ : console_report(_s)
} {}
void report(result const& r); void report(result const& r);
}; };
@ -72,9 +72,9 @@ public:
class html_report class html_report
{ {
public: public:
html_report(std::ostream & _s) : s(_s) html_report(std::ostream& _s)
{ : s(_s)
} {}
void report(result const& r, boost::filesystem::path const& output_dir); void report(result const& r, boost::filesystem::path const& output_dir);
void summary(result_list const& results, boost::filesystem::path const& output_dir); void summary(result_list const& results, boost::filesystem::path const& output_dir);
@ -90,8 +90,7 @@ class report_visitor
public: public:
report_visitor(result const& r) report_visitor(result const& r)
: result_(r) : result_(r)
{ {}
}
template<typename T> template<typename T>
void operator()(T& report) const void operator()(T& report) const
@ -108,8 +107,7 @@ class summary_visitor
public: public:
summary_visitor(result_list const& r) summary_visitor(result_list const& r)
: result_(r) : result_(r)
{ {}
}
template<typename T> template<typename T>
unsigned operator()(T& report) const unsigned operator()(T& report) const
@ -123,6 +121,6 @@ private:
void html_summary(result_list const& results, boost::filesystem::path output_dir); void html_summary(result_list const& results, boost::filesystem::path output_dir);
} } // namespace visual_tests
#endif #endif

View file

@ -34,21 +34,17 @@
#ifdef MAPNIK_LOG #ifdef MAPNIK_LOG
using log_levels_map = std::map<std::string, mapnik::logger::severity_type>; using log_levels_map = std::map<std::string, mapnik::logger::severity_type>;
log_levels_map log_levels log_levels_map log_levels{{"debug", mapnik::logger::severity_type::debug},
{
{ "debug", mapnik::logger::severity_type::debug },
{"warn", mapnik::logger::severity_type::warn}, {"warn", mapnik::logger::severity_type::warn},
{"error", mapnik::logger::severity_type::error}, {"error", mapnik::logger::severity_type::error},
{ "none", mapnik::logger::severity_type::none } {"none", mapnik::logger::severity_type::none}};
};
#endif #endif
using namespace visual_tests; using namespace visual_tests;
namespace po = boost::program_options; namespace po = boost::program_options;
runner::renderer_container create_renderers(po::variables_map const & args, runner::renderer_container
boost::filesystem::path const & output_dir, create_renderers(po::variables_map const& args, boost::filesystem::path const& output_dir, bool force_append = false)
bool force_append = false)
{ {
boost::filesystem::path reference_dir(args["images-dir"].as<std::string>()); boost::filesystem::path reference_dir(args["images-dir"].as<std::string>());
bool overwrite = args.count("overwrite"); bool overwrite = args.count("overwrite");
@ -106,6 +102,7 @@ runner::renderer_container create_renderers(po::variables_map const & args,
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
po::options_description desc("visual test runner"); po::options_description desc("visual test runner");
// clang-format off
desc.add_options() desc.add_options()
("help,h", "produce usage message") ("help,h", "produce usage message")
("verbose,v", "verbose output") ("verbose,v", "verbose output")
@ -147,7 +144,7 @@ int main(int argc, char** argv)
(grid_renderer::name, "render with Grid renderer") (grid_renderer::name, "render with Grid renderer")
#endif #endif
; ;
// clang-format on
po::positional_options_description p; po::positional_options_description p;
p.add("styles", -1); p.add("styles", -1);
po::variables_map vm; po::variables_map vm;
@ -194,7 +191,8 @@ int main(int argc, char** argv)
vm["jobs"].as<std::size_t>(), vm["jobs"].as<std::size_t>(),
create_renderers(vm, output_dir)); create_renderers(vm, output_dir));
bool show_duration = vm.count("duration"); bool show_duration = vm.count("duration");
report_type report(vm.count("verbose") ? report_type((console_report(show_duration))) : report_type((console_short_report(show_duration)))); report_type report(vm.count("verbose") ? report_type((console_report(show_duration)))
: report_type((console_short_report(show_duration))));
result_list results; result_list results;
try try
@ -207,8 +205,7 @@ int main(int argc, char** argv)
{ {
results = run.test_all(report); results = run.test_all(report);
} }
} } catch (std::exception& e)
catch (std::exception & e)
{ {
std::cerr << "Error running tests: " << e.what() << std::endl; std::cerr << "Error running tests: " << e.what() << std::endl;
return 1; return 1;

View file

@ -25,14 +25,12 @@
#include <future> #include <future>
#include <atomic> #include <atomic>
#include <mapnik/load_map.hpp> #include <mapnik/load_map.hpp>
#include "runner.hpp" #include "runner.hpp"
#include "parse_map_sizes.hpp" #include "parse_map_sizes.hpp"
namespace visual_tests namespace visual_tests {
{
struct renderer_name_visitor struct renderer_name_visitor
{ {
@ -55,17 +53,16 @@ public:
std::size_t iterations, std::size_t iterations,
bool is_fail_limit, bool is_fail_limit,
std::atomic<std::size_t>& fail_count) std::atomic<std::size_t>& fail_count)
: name_(name), : name_(name)
map_(map), , map_(map)
tiles_(tiles), , tiles_(tiles)
scale_factor_(scale_factor), , scale_factor_(scale_factor)
results_(results), , results_(results)
report_(report), , report_(report)
iterations_(iterations), , iterations_(iterations)
is_fail_limit_(is_fail_limit), , is_fail_limit_(is_fail_limit)
fail_count_(fail_count) , fail_count_(fail_count)
{ {}
}
template<typename T, typename std::enable_if<T::renderer_type::support_tiles>::type* = nullptr> template<typename T, typename std::enable_if<T::renderer_type::support_tiles>::type* = nullptr>
void operator()(T const& renderer) const void operator()(T const& renderer) const
@ -142,14 +139,13 @@ runner::runner(runner::path_type const & styles_dir,
std::size_t fail_limit, std::size_t fail_limit,
std::size_t jobs, std::size_t jobs,
runner::renderer_container const& renderers) runner::renderer_container const& renderers)
: styles_dir_(styles_dir), : styles_dir_(styles_dir)
defaults_(defaults), , defaults_(defaults)
jobs_(jobs), , jobs_(jobs)
iterations_(iterations), , iterations_(iterations)
fail_limit_(fail_limit), , fail_limit_(fail_limit)
renderers_(renderers) , renderers_(renderers)
{ {}
}
result_list runner::test_all(report_type& report) const result_list runner::test_all(report_type& report) const
{ {
@ -163,15 +159,17 @@ result_list runner::test(std::vector<std::string> const & style_names, report_ty
{ {
std::vector<runner::path_type> files; std::vector<runner::path_type> files;
files.reserve(style_names.size()); files.reserve(style_names.size());
std::transform(style_names.begin(), style_names.end(), std::back_inserter(files), std::transform(style_names.begin(),
[&](runner::path_type const & name) style_names.end(),
{ std::back_inserter(files),
[&](runner::path_type const& name) {
return (name.extension() == ".xml") ? name : (styles_dir_ / (name.string() + ".xml")); return (name.extension() == ".xml") ? name : (styles_dir_ / (name.string() + ".xml"));
}); });
return test_parallel(files, report, jobs_); return test_parallel(files, report, jobs_);
} }
result_list runner::test_parallel(std::vector<runner::path_type> const & files, report_type & report, std::size_t jobs) const result_list
runner::test_parallel(std::vector<runner::path_type> const& files, report_type& report, std::size_t jobs) const
{ {
result_list results; result_list results;
@ -236,8 +234,7 @@ result_list runner::test_range(files_iterator begin,
{ {
result_list r = test_one(file, report, fail_count.get()); result_list r = test_one(file, report, fail_count.get());
std::move(r.begin(), r.end(), std::back_inserter(results)); std::move(r.begin(), r.end(), std::back_inserter(results));
} } catch (std::exception const& ex)
catch (std::exception const& ex)
{ {
result r; result r;
r.state = STATE_ERROR; r.state = STATE_ERROR;
@ -296,9 +293,8 @@ void runner::parse_params(mapnik::parameters const & params, config & cfg) const
} }
} }
result_list runner::test_one(runner::path_type const& style_path, result_list
report_type & report, runner::test_one(runner::path_type const& style_path, report_type& report, std::atomic<std::size_t>& fail_count) const
std::atomic<std::size_t> & fail_count) const
{ {
config cfg(defaults_); config cfg(defaults_);
mapnik::Map map(cfg.sizes.front().width, cfg.sizes.front().height); mapnik::Map map(cfg.sizes.front().width, cfg.sizes.front().height);
@ -307,8 +303,7 @@ result_list runner::test_one(runner::path_type const& style_path,
try try
{ {
mapnik::load_map(map, style_path.string(), true); mapnik::load_map(map, style_path.string(), true);
} } catch (std::exception const& ex)
catch (std::exception const& ex)
{ {
std::string what = ex.what(); std::string what = ex.what();
if (what.find("Could not create datasource") != std::string::npos || if (what.find("Could not create datasource") != std::string::npos ||
@ -368,7 +363,8 @@ result_list runner::test_one(runner::path_type const& style_path,
report, report,
iterations_, iterations_,
fail_limit_, fail_limit_,
fail_count), ren); fail_count),
ren);
if (fail_limit_ && fail_count >= fail_limit_) if (fail_limit_ && fail_count >= fail_limit_)
{ {
return results; return results;
@ -380,4 +376,4 @@ result_list runner::test_one(runner::path_type const& style_path,
return results; return results;
} }
} } // namespace visual_tests

View file

@ -27,8 +27,7 @@
#include "report.hpp" #include "report.hpp"
#include "renderer.hpp" #include "renderer.hpp"
namespace visual_tests namespace visual_tests {
{
class runner class runner
{ {
@ -54,9 +53,7 @@ private:
files_iterator end, files_iterator end,
std::reference_wrapper<report_type> report, std::reference_wrapper<report_type> report,
std::reference_wrapper<std::atomic<std::size_t>> fail_limit) const; std::reference_wrapper<std::atomic<std::size_t>> fail_limit) const;
result_list test_one(path_type const & style_path, result_list test_one(path_type const& style_path, report_type& report, std::atomic<std::size_t>& fail_limit) const;
report_type & report,
std::atomic<std::size_t> & fail_limit) const;
void parse_params(mapnik::parameters const& params, config& cfg) const; void parse_params(mapnik::parameters const& params, config& cfg) const;
const path_type styles_dir_; const path_type styles_dir_;
@ -67,6 +64,6 @@ private:
const renderer_container renderers_; const renderer_container renderers_;
}; };
} } // namespace visual_tests
#endif // VISUAL_TEST_RUNNER_HPP #endif // VISUAL_TEST_RUNNER_HPP