]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // Boost.Geometry (aka GGL, Generic Geometry Library) |
2 | // Unit Test | |
3 | ||
4 | // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. | |
5 | // Use, modification and distribution is subject to the Boost Software License, | |
6 | // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at | |
7 | // http://www.boost.org/LICENSE_1_0.txt) | |
8 | ||
9 | #ifndef BOOST_GEOMETRY_TEST_SIMPLIFY_HPP | |
10 | #define BOOST_GEOMETRY_TEST_SIMPLIFY_HPP | |
11 | ||
12 | // Test-functionality, shared between single and multi tests | |
13 | ||
14 | #include <iomanip> | |
15 | #include <sstream> | |
16 | #include <geometry_test_common.hpp> | |
11fdf7f2 TL |
17 | #include <boost/geometry/algorithms/correct_closure.hpp> |
18 | #include <boost/geometry/algorithms/equals.hpp> | |
7c673cae FG |
19 | #include <boost/geometry/algorithms/simplify.hpp> |
20 | #include <boost/geometry/algorithms/distance.hpp> | |
21 | #include <boost/geometry/strategies/strategies.hpp> | |
22 | #include <boost/geometry/io/wkt/wkt.hpp> | |
23 | #include <boost/variant/variant.hpp> | |
24 | ||
11fdf7f2 TL |
25 | |
26 | template | |
27 | < | |
28 | typename GeometryForTag, | |
29 | typename Tag = typename bg::tag<GeometryForTag>::type | |
30 | > | |
31 | struct test_equality | |
32 | { | |
33 | template <typename Geometry, typename Expected> | |
34 | static void apply(Geometry const& geometry, Expected const& expected) | |
35 | { | |
36 | // Verify both spatially equal AND number of points, because several | |
37 | // of the tests only check explicitly on collinear points being | |
38 | // simplified away | |
39 | bool const result | |
40 | = bg::equals(geometry, expected) | |
41 | && bg::num_points(geometry) == bg::num_points(expected); | |
42 | ||
43 | BOOST_CHECK_MESSAGE(result, | |
44 | " result: " << bg::wkt(geometry) << " " << bg::area(geometry) | |
45 | << " expected: " << bg::wkt(expected) << " " << bg::area(expected)); | |
46 | ||
47 | } | |
48 | }; | |
49 | ||
50 | // Linestring does NOT yet have "geometry::equals" implemented | |
51 | // Until then, WKT's are compared (which is acceptable for linestrings, but not | |
52 | // for polygons, because simplify might rotate them) | |
53 | template <typename GeometryForTag> | |
54 | struct test_equality<GeometryForTag, bg::linestring_tag> | |
55 | { | |
56 | template <typename Geometry, typename Expected> | |
57 | static void apply(Geometry const& geometry, Expected const& expected) | |
58 | { | |
59 | std::ostringstream out1, out2; | |
60 | out1 << bg::wkt(geometry); | |
61 | out2 << bg::wkt(expected); | |
62 | BOOST_CHECK_EQUAL(out1.str(), out2.str()); | |
63 | } | |
64 | }; | |
65 | ||
66 | ||
67 | template <typename Tag> | |
7c673cae FG |
68 | struct test_inserter |
69 | { | |
11fdf7f2 TL |
70 | template <typename Geometry, typename Expected> |
71 | static void apply(Geometry& , Expected const& , double ) | |
7c673cae FG |
72 | {} |
73 | }; | |
74 | ||
11fdf7f2 TL |
75 | template <> |
76 | struct test_inserter<bg::linestring_tag> | |
7c673cae | 77 | { |
11fdf7f2 | 78 | template <typename Geometry, typename Expected, typename DistanceMeasure> |
7c673cae | 79 | static void apply(Geometry& geometry, |
11fdf7f2 | 80 | Expected const& expected, |
7c673cae FG |
81 | DistanceMeasure const& distance) |
82 | { | |
83 | { | |
84 | Geometry simplified; | |
85 | bg::detail::simplify::simplify_insert(geometry, | |
86 | std::back_inserter(simplified), distance); | |
87 | ||
11fdf7f2 | 88 | test_equality<Geometry>::apply(simplified, expected); |
7c673cae FG |
89 | } |
90 | ||
91 | #ifdef TEST_PULL89 | |
92 | { | |
93 | typedef typename bg::point_type<Geometry>::type point_type; | |
94 | typedef typename bg::strategy::distance::detail::projected_point_ax<>::template result_type<point_type, point_type>::type distance_type; | |
95 | typedef bg::strategy::distance::detail::projected_point_ax_less<distance_type> less_comparator; | |
96 | ||
97 | distance_type max_distance(distance); | |
98 | less_comparator less(max_distance); | |
99 | ||
100 | bg::strategy::simplify::detail::douglas_peucker | |
101 | < | |
102 | point_type, | |
103 | bg::strategy::distance::detail::projected_point_ax<>, | |
104 | less_comparator | |
105 | > strategy(less); | |
106 | ||
107 | Geometry simplified; | |
108 | bg::detail::simplify::simplify_insert(geometry, | |
109 | std::back_inserter(simplified), max_distance, strategy); | |
110 | ||
11fdf7f2 | 111 | test_equality<Geometry>::apply(simplified, expected); |
7c673cae FG |
112 | } |
113 | #endif | |
114 | } | |
115 | }; | |
116 | ||
11fdf7f2 | 117 | template <typename Geometry, typename Expected, typename DistanceMeasure> |
7c673cae | 118 | void check_geometry(Geometry const& geometry, |
11fdf7f2 TL |
119 | Expected const& expected, |
120 | DistanceMeasure const& distance) | |
7c673cae FG |
121 | { |
122 | Geometry simplified; | |
123 | bg::simplify(geometry, simplified, distance); | |
11fdf7f2 | 124 | test_equality<Expected>::apply(simplified, expected); |
7c673cae FG |
125 | } |
126 | ||
11fdf7f2 | 127 | template <typename Geometry, typename Expected, typename Strategy, typename DistanceMeasure> |
7c673cae | 128 | void check_geometry(Geometry const& geometry, |
11fdf7f2 | 129 | Expected const& expected, |
7c673cae FG |
130 | DistanceMeasure const& distance, |
131 | Strategy const& strategy) | |
132 | { | |
133 | Geometry simplified; | |
134 | bg::simplify(geometry, simplified, distance, strategy); | |
11fdf7f2 TL |
135 | test_equality<Expected>::apply(simplified, expected); |
136 | } | |
7c673cae | 137 | |
11fdf7f2 TL |
138 | template <typename Geometry, typename DistanceMeasure> |
139 | void check_geometry_with_area(Geometry const& geometry, | |
140 | double expected_area, | |
141 | DistanceMeasure const& distance) | |
142 | { | |
143 | Geometry simplified; | |
144 | bg::simplify(geometry, simplified, distance); | |
145 | BOOST_CHECK_CLOSE(bg::area(simplified), expected_area, 0.01); | |
7c673cae FG |
146 | } |
147 | ||
148 | ||
149 | template <typename Geometry, typename DistanceMeasure> | |
150 | void test_geometry(std::string const& wkt, | |
11fdf7f2 | 151 | std::string const& expected_wkt, |
7c673cae FG |
152 | DistanceMeasure distance) |
153 | { | |
154 | typedef typename bg::point_type<Geometry>::type point_type; | |
155 | ||
11fdf7f2 TL |
156 | Geometry geometry, expected; |
157 | ||
7c673cae | 158 | bg::read_wkt(wkt, geometry); |
11fdf7f2 TL |
159 | bg::read_wkt(expected_wkt, expected); |
160 | ||
7c673cae FG |
161 | boost::variant<Geometry> v(geometry); |
162 | ||
163 | // Define default strategy for testing | |
164 | typedef bg::strategy::simplify::douglas_peucker | |
165 | < | |
166 | typename bg::point_type<Geometry>::type, | |
167 | bg::strategy::distance::projected_point<double> | |
168 | > dp; | |
169 | ||
170 | check_geometry(geometry, expected, distance); | |
171 | check_geometry(v, expected, distance); | |
172 | ||
173 | ||
174 | BOOST_CONCEPT_ASSERT( (bg::concepts::SimplifyStrategy<dp, point_type>) ); | |
175 | ||
176 | check_geometry(geometry, expected, distance, dp()); | |
177 | check_geometry(v, expected, distance, dp()); | |
178 | ||
179 | // Check inserter (if applicable) | |
180 | test_inserter | |
181 | < | |
11fdf7f2 | 182 | typename bg::tag<Geometry>::type |
7c673cae FG |
183 | >::apply(geometry, expected, distance); |
184 | ||
185 | #ifdef TEST_PULL89 | |
186 | // Check using non-default less comparator in douglass_peucker | |
187 | typedef typename bg::strategy::distance::detail::projected_point_ax<>::template result_type<point_type, point_type>::type distance_type; | |
188 | typedef bg::strategy::distance::detail::projected_point_ax_less<distance_type> less_comparator; | |
189 | ||
190 | distance_type const max_distance(distance); | |
191 | less_comparator const less(max_distance); | |
192 | ||
193 | typedef bg::strategy::simplify::detail::douglas_peucker | |
194 | < | |
195 | point_type, | |
196 | bg::strategy::distance::detail::projected_point_ax<>, | |
197 | less_comparator | |
198 | > douglass_peucker_with_less; | |
199 | ||
200 | BOOST_CONCEPT_ASSERT( (bg::concepts::SimplifyStrategy<douglass_peucker_with_less, point_type>) ); | |
201 | ||
202 | check_geometry(geometry, expected, distance, douglass_peucker_with_less(less)); | |
203 | check_geometry(v, expected, distance, douglass_peucker_with_less(less)); | |
204 | #endif | |
205 | } | |
206 | ||
207 | template <typename Geometry, typename Strategy, typename DistanceMeasure> | |
208 | void test_geometry(std::string const& wkt, | |
11fdf7f2 | 209 | std::string const& expected_wkt, |
7c673cae FG |
210 | DistanceMeasure const& distance, |
211 | Strategy const& strategy) | |
212 | { | |
11fdf7f2 TL |
213 | Geometry geometry, expected; |
214 | ||
7c673cae | 215 | bg::read_wkt(wkt, geometry); |
11fdf7f2 TL |
216 | bg::read_wkt(expected_wkt, expected); |
217 | bg::correct_closure(geometry); | |
218 | bg::correct_closure(expected); | |
219 | ||
7c673cae FG |
220 | boost::variant<Geometry> v(geometry); |
221 | ||
222 | BOOST_CONCEPT_ASSERT( (bg::concepts::SimplifyStrategy<Strategy, | |
223 | typename bg::point_type<Geometry>::type>) ); | |
224 | ||
225 | check_geometry(geometry, expected, distance, strategy); | |
226 | check_geometry(v, expected, distance, strategy); | |
227 | } | |
228 | ||
11fdf7f2 TL |
229 | template <typename Geometry, typename DistanceMeasure> |
230 | void test_geometry(std::string const& wkt, | |
231 | double expected_area, | |
232 | DistanceMeasure const& distance) | |
233 | { | |
234 | Geometry geometry; | |
235 | bg::read_wkt(wkt, geometry); | |
236 | bg::correct_closure(geometry); | |
237 | ||
238 | check_geometry_with_area(geometry, expected_area, distance); | |
239 | } | |
240 | ||
7c673cae | 241 | #endif |