mapnik/test/unit/vertex_adapter/clipping_test.cpp

119 lines
3.4 KiB
C++
Raw Normal View History

2015-04-24 14:40:22 +02:00
#include "catch.hpp"
// mapnik
#include <mapnik/util/conversions.hpp>
#include <mapnik/util/trim.hpp>
#include <mapnik/path.hpp>
#include <mapnik/warning.hpp>
MAPNIK_DISABLE_WARNING_PUSH
#include <mapnik/warning_ignore.hpp>
2015-04-24 14:40:22 +02:00
#include <boost/algorithm/string.hpp>
MAPNIK_DISABLE_WARNING_POP
2015-04-24 14:40:22 +02:00
// stl
#include <stdexcept>
#include <iostream>
#include <sstream>
#include <fstream>
#include <vector>
// agg
#include "agg_conv_clip_polyline.h"
2022-01-26 23:25:53 +01:00
template<typename T>
std::string dump_path(T& path)
2015-04-24 14:40:22 +02:00
{
unsigned cmd = 1;
double x = 0;
double y = 0;
unsigned idx = 0;
std::ostringstream s;
path.rewind(0);
while ((cmd = path.vertex(&x, &y)) != mapnik::SEG_END)
{
2022-01-26 23:25:53 +01:00
if (idx > 0)
s << ",";
2015-04-24 14:40:22 +02:00
s << x << " " << y << " " << cmd;
idx++;
}
return s.str();
}
2022-01-26 23:25:53 +01:00
std::string clip_line(mapnik::box2d<double> const& bbox, mapnik::path_type const& path)
2015-04-24 14:40:22 +02:00
{
using line_clipper = agg::conv_clip_polyline<mapnik::vertex_adapter>;
mapnik::vertex_adapter va(path);
line_clipper clipped(va);
2022-01-26 23:25:53 +01:00
clipped.clip_box(bbox.minx(), bbox.miny(), bbox.maxx(), bbox.maxy());
2015-04-24 14:40:22 +02:00
return dump_path(clipped);
}
2022-01-26 23:25:53 +01:00
void parse_geom(mapnik::path_type& path, std::string const& geom_string)
{
2015-04-24 14:40:22 +02:00
std::vector<std::string> vertices;
boost::split(vertices, geom_string, boost::is_any_of(","));
for (std::string const& vert : vertices)
{
std::vector<std::string> commands;
boost::split(commands, vert, boost::is_any_of(" "));
if (commands.size() != 3)
{
throw std::runtime_error(std::string("could not parse geometry '") + geom_string + "'");
}
double x = 0;
double y = 0;
int c = 0;
2022-01-26 23:25:53 +01:00
if (mapnik::util::string2double(commands[0], x) && mapnik::util::string2double(commands[1], y) &&
mapnik::util::string2int(commands[2], c))
2015-04-24 14:40:22 +02:00
{
2022-01-26 23:25:53 +01:00
path.push_vertex(x, y, (mapnik::CommandType)c);
2015-04-24 14:40:22 +02:00
}
else
{
throw std::runtime_error(std::string("could not parse geometry '") + geom_string + "'");
}
}
}
2022-01-26 23:25:53 +01:00
TEST_CASE("clipping")
{
SECTION("lines")
{
try
2015-04-24 14:40:22 +02:00
{
2022-01-26 23:25:53 +01:00
std::string filename("test/unit/data/cases.txt");
std::ifstream stream(filename.c_str(), std::ios_base::in | std::ios_base::binary);
if (!stream.is_open())
throw std::runtime_error("could not open: '" + filename + "'");
std::string csv_line;
while (std::getline(stream, csv_line, '\n'))
{
if (csv_line.empty() || csv_line[0] == '#')
continue;
std::vector<std::string> parts;
boost::split(parts, csv_line, boost::is_any_of(";"));
// first part is clipping box
mapnik::box2d<double> bbox;
if (!bbox.from_string(parts[0]))
{
throw std::runtime_error(std::string("could not parse bbox '") + parts[0] + "'");
}
// second part is input geometry
mapnik::path_type path;
parse_geom(path, parts[1]);
// std::clog << dump_path(path) << "\n";
// third part is expected, clipped geometry
REQUIRE(clip_line(bbox, path) == mapnik::util::trim_copy(parts[2]));
2015-04-24 14:40:22 +02:00
}
2022-01-26 23:25:53 +01:00
stream.close();
}
catch (std::exception const& ex)
2022-01-26 23:25:53 +01:00
{
std::cerr << ex.what() << "\n";
2015-04-24 14:40:22 +02:00
}
}
2017-05-05 13:02:01 +02:00
}