File: clipping_test.cpp

package info (click to toggle)
mapnik 2.2.0%2Bds1-7
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 30,288 kB
  • ctags: 18,382
  • sloc: cpp: 115,128; python: 9,298; xml: 5,692; ansic: 3,726; makefile: 160; sh: 159; lisp: 13
file content (136 lines) | stat: -rw-r--r-- 3,950 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136

// 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 <stdexcept>
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>

// agg
#include "agg_conv_clip_polygon.h"
#include "agg_conv_clip_polyline.h"
//#include "agg_path_storage.h"
//#include "agg_conv_clipper.h"

#include "utils.hpp"

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 argc, char** argv)
{
    std::vector<std::string> args;
    for (int i=1;i<argc;++i)
    {
        args.push_back(argv[i]);
    }
    bool quiet = std::find(args.begin(), args.end(), "-q")!=args.end();

    try {

        BOOST_TEST(set_working_dir(args));

        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())
    {
        if (quiet) std::clog << "\x1b[1;32m.\x1b[0m";
        else 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();
    }
}