]>
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_FOR_EACH_HPP | |
10 | #define BOOST_GEOMETRY_TEST_FOR_EACH_HPP | |
11 | ||
12 | #include <geometry_test_common.hpp> | |
13 | ||
14 | #include <boost/config.hpp> | |
15 | #include <boost/geometry/algorithms/for_each.hpp> | |
16 | ||
17 | #include <boost/geometry/algorithms/distance.hpp> | |
18 | #include <boost/geometry/strategies/strategies.hpp> | |
19 | #include <boost/geometry/io/wkt/wkt.hpp> | |
20 | #include <boost/geometry/io/dsv/write.hpp> | |
21 | ||
22 | ||
23 | template<typename Point> | |
24 | inline void translate_x_function(Point& p) | |
25 | { | |
26 | bg::set<0>(p, bg::get<0>(p) + 100.0); | |
27 | } | |
28 | ||
29 | template<typename Point> | |
30 | struct scale_y_functor | |
31 | { | |
32 | inline void operator()(Point& p) | |
33 | { | |
34 | bg::set<1>(p, bg::get<1>(p) * 100.0); | |
35 | } | |
36 | }; | |
37 | ||
38 | template<typename Point> | |
39 | struct sum_x_functor | |
40 | { | |
41 | typename bg::coordinate_type<Point>::type sum; | |
42 | ||
43 | sum_x_functor() | |
44 | : sum(0) | |
45 | {} | |
46 | ||
47 | inline void operator()(Point const& p) | |
48 | { | |
49 | sum += bg::get<0>(p); | |
50 | } | |
51 | }; | |
52 | ||
53 | // Per segment | |
54 | static std::ostringstream g_out; | |
55 | ||
56 | template<typename Segment> | |
57 | inline void stream_segment(Segment const& s) | |
58 | { | |
59 | g_out << bg::dsv(s) << " "; | |
60 | } | |
61 | ||
62 | template<typename Segment> | |
63 | struct sum_segment_length | |
64 | { | |
65 | typename bg::coordinate_type<Segment>::type sum; | |
66 | ||
67 | sum_segment_length() | |
68 | : sum(0) | |
69 | {} | |
70 | inline void operator()(Segment const& s) | |
71 | { | |
72 | sum += bg::distance(s.first, s.second); | |
73 | } | |
74 | }; | |
75 | ||
76 | template<typename Segment> | |
77 | inline void modify_segment(Segment& s) | |
78 | { | |
79 | if (bg::math::equals(bg::get<0,0>(s), 1.0)) | |
80 | { | |
81 | bg::set<0,0>(s, 10.0); | |
82 | } | |
83 | } | |
84 | ||
85 | ||
86 | template <typename Geometry> | |
87 | void test_per_point_const(Geometry const& geometry, int expected) | |
88 | { | |
89 | typedef typename bg::point_type<Geometry>::type point_type; | |
90 | ||
91 | // Class (functor) | |
92 | sum_x_functor<point_type> functor; | |
93 | functor = bg::for_each_point(geometry, functor); | |
94 | BOOST_CHECK_EQUAL(functor.sum, expected); | |
95 | ||
96 | ||
97 | // Lambda | |
98 | #if !defined(BOOST_NO_CXX11_LAMBDAS) | |
99 | ||
100 | typename bg::coordinate_type<point_type>::type sum_x = 0; | |
101 | ||
102 | bg::for_each_point | |
103 | ( | |
104 | geometry, | |
105 | [&sum_x](point_type const& p) | |
106 | { | |
107 | sum_x += bg::get<0>(p); | |
108 | } | |
109 | ||
110 | ); | |
111 | ||
112 | BOOST_CHECK_EQUAL(sum_x, expected); | |
113 | #endif | |
114 | } | |
115 | ||
116 | template <typename Geometry> | |
117 | void test_per_point_non_const(Geometry& geometry, | |
118 | std::string const& expected1, | |
119 | std::string const& expected2) | |
120 | { | |
121 | #if !defined(BOOST_NO_CXX11_LAMBDAS) | |
122 | Geometry copy = geometry; | |
123 | #endif | |
124 | ||
125 | typedef typename bg::point_type<Geometry>::type point_type; | |
126 | ||
127 | // function | |
128 | bg::for_each_point(geometry, translate_x_function<point_type>); | |
129 | std::ostringstream out1; | |
130 | out1 << bg::wkt(geometry); | |
131 | ||
132 | BOOST_CHECK_MESSAGE(out1.str() == expected1, | |
133 | "for_each_point: " | |
134 | << " expected " << expected1 | |
135 | << " got " << bg::wkt(geometry)); | |
136 | ||
137 | // functor | |
138 | bg::for_each_point(geometry, scale_y_functor<point_type>()); | |
139 | ||
140 | std::ostringstream out2; | |
141 | out2 << bg::wkt(geometry); | |
142 | ||
143 | BOOST_CHECK_MESSAGE(out2.str() == expected2, | |
144 | "for_each_point: " | |
145 | << " expected " << expected2 | |
146 | << " got " << bg::wkt(geometry)); | |
147 | ||
148 | #if !defined(BOOST_NO_CXX11_LAMBDAS) | |
149 | // Lambda, both functions above together. Without / with capturing | |
150 | ||
151 | geometry = copy; | |
152 | bg::for_each_point | |
153 | ( | |
154 | geometry, | |
155 | [](point_type& p) | |
156 | { | |
157 | bg::set<0>(p, bg::get<0>(p) + 100); | |
158 | } | |
159 | ||
160 | ); | |
161 | ||
162 | typename bg::coordinate_type<point_type>::type scale = 100; | |
163 | bg::for_each_point | |
164 | ( | |
165 | geometry, | |
166 | [&](point_type& p) | |
167 | { | |
168 | bg::set<1>(p, bg::get<1>(p) * scale); | |
169 | } | |
170 | ||
171 | ); | |
172 | ||
173 | std::ostringstream out3; | |
174 | out3 << bg::wkt(geometry); | |
175 | ||
176 | BOOST_CHECK_MESSAGE(out3.str() == expected2, | |
177 | "for_each_point (lambda): " | |
178 | << " expected " << expected2 | |
179 | << " got " << bg::wkt(geometry)); | |
180 | #endif | |
181 | ||
182 | } | |
183 | ||
184 | ||
185 | template <typename Geometry> | |
186 | void test_per_point(std::string const& wkt | |
187 | , int expected_sum_x | |
188 | , std::string const& expected1 | |
189 | , std::string const& expected2 | |
190 | ) | |
191 | { | |
192 | Geometry geometry; | |
193 | bg::read_wkt(wkt, geometry); | |
194 | test_per_point_const(geometry, expected_sum_x); | |
195 | test_per_point_non_const(geometry, expected1, expected2); | |
196 | } | |
197 | ||
198 | ||
199 | ||
200 | template <typename Geometry> | |
201 | void test_per_segment_const(Geometry const& geometry, | |
202 | std::string const& expected_dsv, | |
203 | double expected_length) | |
204 | { | |
205 | typedef typename bg::point_type<Geometry>::type point_type; | |
206 | ||
207 | // function | |
208 | g_out.str(""); | |
209 | g_out.clear(); | |
210 | bg::for_each_segment(geometry, | |
211 | stream_segment<bg::model::referring_segment<point_type const> >); | |
212 | std::string out = g_out.str(); | |
213 | boost::trim(out); | |
214 | BOOST_CHECK_EQUAL(out, expected_dsv); | |
215 | ||
216 | // functor | |
217 | sum_segment_length<bg::model::referring_segment<point_type const> > functor; | |
218 | functor = bg::for_each_segment(geometry, functor); | |
219 | ||
220 | BOOST_CHECK_CLOSE(functor.sum, expected_length, 0.0001); | |
221 | } | |
222 | ||
223 | ||
224 | template <typename Geometry> | |
225 | void test_per_segment_non_const(Geometry& geometry, | |
226 | std::string const& expected_wkt) | |
227 | { | |
228 | typedef typename bg::point_type<Geometry>::type point_type; | |
229 | ||
230 | // function | |
231 | bg::for_each_segment(geometry, | |
232 | modify_segment<bg::model::referring_segment<point_type> >); | |
233 | ||
234 | std::ostringstream out; | |
235 | out << bg::wkt(geometry); | |
236 | ||
237 | BOOST_CHECK_MESSAGE(out.str() == expected_wkt, | |
238 | "for_each_segment: " | |
239 | << " expected " << expected_wkt | |
240 | << " got " << bg::wkt(geometry)); | |
241 | ||
242 | // function is working here, functor works for all others, | |
243 | // it will also work here. | |
244 | } | |
245 | ||
246 | ||
247 | template <typename Geometry> | |
248 | void test_per_segment(std::string const& wkt | |
249 | , std::string const& expected_dsv | |
250 | , double expected_length | |
251 | , std::string const& expected_wkt | |
252 | ) | |
253 | { | |
254 | Geometry geometry; | |
255 | bg::read_wkt(wkt, geometry); | |
256 | test_per_segment_const(geometry, expected_dsv, expected_length); | |
257 | test_per_segment_non_const(geometry, expected_wkt); | |
258 | } | |
259 | ||
260 | ||
261 | ||
262 | template <typename Geometry> | |
263 | void test_geometry(std::string const& wkt | |
264 | , int expected_sum_x | |
265 | , std::string const& expected1 | |
266 | , std::string const& expected2 | |
267 | , std::string const& expected_dsv | |
268 | , double expected_length | |
269 | , std::string const& expected_wkt | |
270 | ) | |
271 | { | |
272 | test_per_point<Geometry>(wkt, expected_sum_x, expected1, expected2); | |
273 | test_per_segment<Geometry>(wkt, expected_dsv, expected_length, expected_wkt); | |
274 | } | |
275 | ||
276 | ||
277 | #endif |