]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // Boost.Geometry (aka GGL, Generic Geometry Library) |
2 | // Unit Test | |
3 | ||
4 | // Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands. | |
5 | // Copyright (c) 2008-2015 Bruno Lalande, Paris, France. | |
6 | // Copyright (c) 2009-2015 Mateusz Loskot, London, UK. | |
7 | // Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland. | |
8 | ||
9 | // Use, modification and distribution is subject to the Boost Software License, | |
10 | // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at | |
11 | // http://www.boost.org/LICENSE_1_0.txt) | |
12 | ||
13 | #include <iostream> | |
14 | #include <iomanip> | |
15 | #include <string> | |
16 | ||
17 | // Instead of having a separate (and nearly similar) unit test to test multipolygons, | |
18 | // we now include them here and compile them by default. Only undefining the next line | |
19 | // will avoid testing multi-geometries | |
20 | #define BOOST_GEOMETRY_UNIT_TEST_MULTI | |
21 | ||
22 | #include <boost/variant/variant.hpp> | |
23 | ||
24 | #include <geometry_test_common.hpp> | |
25 | ||
26 | // The include to test | |
27 | #include <boost/geometry/algorithms/remove_spikes.hpp> | |
28 | ||
29 | // Helper includes | |
30 | #include <boost/geometry/algorithms/area.hpp> | |
31 | #include <boost/geometry/algorithms/correct.hpp> | |
32 | #include <boost/geometry/algorithms/perimeter.hpp> | |
33 | #include <boost/geometry/geometries/geometries.hpp> | |
34 | #include <boost/geometry/geometries/point_xy.hpp> | |
35 | #include <boost/geometry/io/wkt/wkt.hpp> | |
36 | #include <boost/geometry/strategies/strategies.hpp> | |
37 | ||
38 | #if defined(BOOST_GEOMETRY_UNIT_TEST_MULTI) | |
39 | # include <boost/geometry/geometries/multi_polygon.hpp> | |
40 | #endif | |
41 | ||
42 | ||
43 | #if defined(TEST_WITH_SVG) | |
44 | # include <boost/geometry/io/svg/svg_mapper.hpp> | |
45 | #endif | |
46 | ||
47 | ||
48 | template <typename Geometry> | |
49 | inline void test_remove_spikes(std::string const& /*id*/, | |
50 | Geometry& geometry, | |
51 | double expected_area, double expected_perimeter) | |
52 | { | |
53 | bg::remove_spikes(geometry); | |
54 | ||
55 | double detected_area = bg::area(geometry); | |
56 | double detected_perimeter = bg::perimeter(geometry); | |
57 | ||
58 | BOOST_CHECK_CLOSE(detected_area, expected_area, 0.01); | |
59 | BOOST_CHECK_CLOSE(detected_perimeter, expected_perimeter, 0.01); | |
60 | } | |
61 | ||
62 | template <typename Geometry> | |
63 | void test_geometry(std::string const& id, std::string const& wkt, | |
64 | double expected_area, double expected_perimeter) | |
65 | { | |
66 | Geometry geometry; | |
67 | bg::read_wkt(wkt, geometry); | |
68 | bg::correct(geometry); | |
69 | boost::variant<Geometry> v(geometry); | |
70 | ||
71 | #if defined(TEST_WITH_SVG) | |
72 | std::ostringstream filename; | |
73 | filename << "remove_spikes_" << id; | |
74 | if (! bg::closure<Geometry>::value) | |
75 | { | |
76 | filename << "_open"; | |
77 | } | |
78 | filename << ".svg"; | |
79 | std::ofstream svg(filename.str().c_str()); | |
80 | ||
81 | bg::svg_mapper<typename bg::point_type<Geometry>::type> mapper(svg, 500, 500); | |
82 | mapper.add(geometry); | |
83 | mapper.map(geometry, "fill-opacity:0.3;opacity:0.6;fill:rgb(51,51,153);stroke:rgb(0,0,255);stroke-width:2"); | |
84 | #endif | |
85 | ||
86 | test_remove_spikes(id, geometry, expected_area, expected_perimeter); | |
87 | test_remove_spikes(id, v, expected_area, expected_perimeter); | |
88 | ||
89 | #if defined(TEST_WITH_SVG) | |
90 | mapper.map(geometry, "opacity:0.6;fill:none;stroke:rgb(255,0,0);stroke-width:3"); | |
91 | #endif | |
92 | } | |
93 | ||
94 | template <typename P, bool Clockwise, bool Closed> | |
95 | void test_polygons() | |
96 | { | |
97 | typedef bg::model::ring<P, Clockwise, Closed> ring; | |
98 | typedef bg::model::polygon<P, Clockwise, Closed> polygon; | |
99 | ||
100 | test_geometry<ring>("box", | |
101 | "POLYGON((0 0,0 4,4 4,4 0,0 0))", | |
102 | 16, 16); | |
103 | test_geometry<polygon>("box", | |
104 | "POLYGON((0 0,0 4,4 4,4 0,0 0))", | |
105 | 16, 16); | |
106 | test_geometry<polygon>("box2", | |
107 | "POLYGON((0 0,0 2,0 4,2 4,4 4,4 2,4 0,2 0,0 0))", | |
108 | 16, 16); | |
109 | test_geometry<polygon>("spike_right", | |
110 | "POLYGON((0 0,0 4,4 4,4 2,6 2,4 2,4 0,0 0))", | |
111 | 16, 16); | |
112 | test_geometry<polygon>("spike_at_corner", | |
113 | "POLYGON((0 0,0 4,6 4,4 4,4 0,0 0))", | |
114 | 16, 16); | |
115 | test_geometry<polygon>("spike_at_first", | |
116 | "POLYGON((0 0,-1 3,0 0,0 4,4 4,4 0,0 0))", | |
117 | 16, 16); | |
118 | test_geometry<polygon>("spike_at_last", | |
119 | "POLYGON((0 0,0 4,4 4,4 0,6 0,0 0))", | |
120 | 16, 16); | |
121 | test_geometry<polygon>("spike_at_closing", | |
122 | "POLYGON((-1 0,0 0,0 4,4 4,4 0,0 0,-1 0))", | |
123 | 16, 16); | |
124 | test_geometry<polygon>("double_spike", | |
125 | "POLYGON((0 0,0 4,4 4,4 2,6 2,5 2,4 2,4 0,0 0))", | |
126 | 16, 16); | |
127 | test_geometry<polygon>("three_double_spike", | |
128 | "POLYGON((0 0,0 4,4 4,4 2,6 2,5 2,4.5 2,4 2,4 0,0 0))", | |
129 | 16, 16); | |
130 | test_geometry<polygon>("spike_with_corner", | |
131 | "POLYGON((0 0,0 4,4 4,4 2,6 2,6 4,6 2,4 2,4 0,0 0))", | |
132 | 16, 16); | |
133 | ||
134 | test_geometry<polygon>("triangle0", | |
135 | "POLYGON((0 0,0 4,2 0,4 0,0 0))", | |
136 | 4, 6 + sqrt(20.0)); | |
137 | test_geometry<polygon>("triangle1", | |
138 | "POLYGON((0 4,2 0,4 0,0 0,0 4))", | |
139 | 4, 6 + sqrt(20.0)); | |
140 | test_geometry<polygon>("triangle2", | |
141 | "POLYGON((2 0,4 0,0 0,0 4,2 0))", | |
142 | 4, 6 + sqrt(20.0)); | |
143 | test_geometry<polygon>("triangle3", | |
144 | "POLYGON((4 0,0 0,0 4,2 0,4 0))", | |
145 | 4, 6 + sqrt(20.0)); | |
146 | ||
147 | test_geometry<polygon>("only_spike1", | |
148 | "POLYGON((0 0,2 2,0 0))", | |
149 | 0, 0); | |
150 | test_geometry<polygon>("only_spike2", | |
151 | "POLYGON((0 0,2 2,4 4,2 2,0 0))", | |
152 | 0, 0); | |
153 | test_geometry<polygon>("only_spike3", | |
154 | "POLYGON((0 0,2 2,4 4,0 0))", | |
155 | 0, 0); | |
156 | test_geometry<polygon>("only_spike4", | |
157 | "POLYGON((0 0,4 4,2 2,0 0))", | |
158 | 0, 0); | |
159 | } | |
160 | ||
161 | ||
162 | template <typename P, bool Clockwise, bool Closed> | |
163 | void test_multi_polygons() | |
164 | { | |
165 | typedef bg::model::polygon<P, Clockwise, Closed> polygon; | |
166 | typedef bg::model::multi_polygon<polygon> multi_polygon; | |
167 | ||
168 | test_geometry<multi_polygon>("multi_spike_with_corner", | |
169 | "MULTIPOLYGON(((0 0,0 4,4 4,4 2,6 2,6 4,6 2,4 2,4 0,0 0)))", | |
170 | 16, 16); | |
171 | } | |
172 | ||
173 | template <typename P, bool Clockwise, bool Closed> | |
174 | void test_all() | |
175 | { | |
176 | test_polygons<P, Clockwise, Closed>(); | |
177 | test_multi_polygons<P, Clockwise, Closed>(); | |
178 | } | |
179 | ||
180 | int test_main(int, char* []) | |
181 | { | |
182 | test_all<bg::model::d2::point_xy<double>, true, true>(); | |
183 | test_all<bg::model::d2::point_xy<double>, true, false>(); | |
184 | return 0; | |
185 | } | |
186 |