first pass at a lower level set of clipping tests that avoid complexity of wkt and vertex converters - refs #1699
This commit is contained in:
parent
cecba84877
commit
96c65979a1
2 changed files with 130 additions and 0 deletions
123
tests/cpp_tests/clipping_test.cpp
Normal file
123
tests/cpp_tests/clipping_test.cpp
Normal file
|
@ -0,0 +1,123 @@
|
|||
|
||||
// mapnik
|
||||
#include <mapnik/geometry.hpp>
|
||||
#include <mapnik/util/conversions.hpp>
|
||||
|
||||
// boost
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
// stl
|
||||
#include <exception>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
|
||||
// agg
|
||||
#include "agg_conv_clip_polygon.h"
|
||||
#include "agg_conv_clip_polyline.h"
|
||||
//#include "agg_path_storage.h"
|
||||
//#include "agg_conv_clipper.h"
|
||||
|
||||
|
||||
template <typename T>
|
||||
std::string dump_path(T & path)
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (idx > 0) s << ",";
|
||||
s << x << " " << y << " " << cmd;
|
||||
idx++;
|
||||
}
|
||||
return s.str();
|
||||
}
|
||||
|
||||
std::string clip_line(mapnik::box2d<double> const& bbox,
|
||||
mapnik::geometry_type & geom)
|
||||
{
|
||||
typedef agg::conv_clip_polyline<mapnik::geometry_type> line_clipper;
|
||||
line_clipper clipped(geom);
|
||||
clipped.clip_box(bbox.minx(),bbox.miny(),bbox.maxx(),bbox.maxy());
|
||||
return dump_path(clipped);
|
||||
}
|
||||
|
||||
void parse_geom(mapnik::geometry_type & geom,
|
||||
std::string const& geom_string) {
|
||||
std::vector<std::string> vertices;
|
||||
boost::split(vertices, geom_string, boost::is_any_of(","));
|
||||
BOOST_FOREACH(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;
|
||||
if (mapnik::util::string2double(commands[0],x)
|
||||
&& mapnik::util::string2double(commands[1],y)
|
||||
&& mapnik::util::string2int(commands[2],c))
|
||||
{
|
||||
geom.push_vertex(x,y,(mapnik::CommandType)c);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::runtime_error(std::string("could not parse geometry '") + geom_string + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main( int, char*[] )
|
||||
{
|
||||
try {
|
||||
std::string filename("tests/cpp_tests/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::geometry_type geom;
|
||||
parse_geom(geom,parts[1]);
|
||||
//std::clog << dump_path(geom) << "\n";
|
||||
// third part is expected, clipped geometry
|
||||
BOOST_TEST_EQ(clip_line(bbox,geom),parts[2]);
|
||||
}
|
||||
stream.close();
|
||||
}
|
||||
catch (std::exception const& ex)
|
||||
{
|
||||
std::cerr << ex.what() << "\n";
|
||||
}
|
||||
|
||||
if (!::boost::detail::test_errors())
|
||||
{
|
||||
std::clog << "C++ clipping: \x1b[1;32m✓ \x1b[0m\n";
|
||||
#if BOOST_VERSION >= 104600
|
||||
::boost::detail::report_errors_remind().called_report_errors_function = true;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
return ::boost::report_errors();
|
||||
}
|
||||
}
|
7
tests/cpp_tests/data/cases.txt
Normal file
7
tests/cpp_tests/data/cases.txt
Normal file
|
@ -0,0 +1,7 @@
|
|||
# testcase format is:
|
||||
# <bbox>;<input geometry>;<expected clipped geometry>
|
||||
# SEG_END=0 SEG_MOVETO = 1 SEG_LINETO = 2 SEG_CLOSE = (0x40 | 0x0f)
|
||||
50,50,150,150;0 0 1,200 200 2;50 50 1,150 150 2
|
||||
50,50,150,150;50 50 1,150 50 2,150 150 2,50 150 2,50 50 2;50 50 1,150 50 2,150 150 2,50 150 2,50 50 2
|
||||
# TODO - should the close path be kept after clipping?
|
||||
50,50,150,150;50 50 1,150 50 2,150 150 2,50 150 2,50 50 2,0 0 79;50 50 1,150 50 2,150 150 2,50 150 2,50 50 2, 0 0 79
|
Loading…
Reference in a new issue