]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/geometry/test/algorithms/overlay/test_get_turns.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / libs / geometry / test / algorithms / overlay / test_get_turns.hpp
1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2
3 // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
4 // Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
5 // Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
6
7 // This file was modified by Oracle on 2014, 2016, 2017.
8 // Modifications copyright (c) 2014-2017 Oracle and/or its affiliates.
9
10 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
11 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
12
13 // Use, modification and distribution is subject to the Boost Software License,
14 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
15 // http://www.boost.org/LICENSE_1_0.txt)
16
17 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
18
19 #ifndef BOOST_GEOMETRY_TEST_ALGORITHMS_OVERLAY_TEST_GET_TURNS_HPP
20 #define BOOST_GEOMETRY_TEST_ALGORITHMS_OVERLAY_TEST_GET_TURNS_HPP
21
22 #include <iostream>
23 #include <iomanip>
24
25 #include <geometry_test_common.hpp>
26
27 #include <boost/geometry/strategies/strategies.hpp>
28
29 #include <boost/geometry/algorithms/detail/overlay/get_turns.hpp>
30
31 #include <boost/geometry/algorithms/detail/overlay/debug_turn_info.hpp>
32
33 #include <boost/geometry/io/wkt/read.hpp>
34 #include <boost/geometry/io/wkt/write.hpp>
35
36 struct expected_pusher
37 {
38 void push_back(std::string const& ex)
39 {
40 vec.push_back(ex);
41 }
42
43 expected_pusher & operator()(std::string const& ex)
44 {
45 push_back(ex);
46 return *this;
47 }
48
49 typedef std::vector<std::string>::iterator iterator;
50 typedef std::vector<std::string>::const_iterator const_iterator;
51
52 iterator begin() { return vec.begin(); }
53 iterator end() { return vec.end(); }
54 const_iterator begin() const { return vec.begin(); }
55 const_iterator end() const { return vec.end(); }
56
57 std::vector<std::string> vec;
58 };
59
60 inline expected_pusher expected(std::string const& ex)
61 {
62 expected_pusher res;
63 return res(ex);
64 }
65
66 struct equal_turn
67 {
68 equal_turn(std::string const& s) : turn_ptr(&s) {}
69
70 template <typename T>
71 bool operator()(T const& t) const
72 {
73 std::string const& s = (*turn_ptr);
74 std::string::size_type const count = s.size();
75
76 return (count > 0
77 ? bg::method_char(t.method) == s[0]
78 : true)
79 && (count > 1
80 ? bg::operation_char(t.operations[0].operation) == s[1]
81 : true)
82 && (count > 2
83 ? bg::operation_char(t.operations[1].operation) == s[2]
84 : true)
85 && equal_operations_ex(t.operations[0], t.operations[1], s);
86 }
87
88 template <typename P, typename R>
89 static bool equal_operations_ex(bg::detail::overlay::turn_operation<P, R> const& op0,
90 bg::detail::overlay::turn_operation<P, R> const& op1,
91 std::string const& s)
92 {
93 return true;
94 }
95
96 template <typename P, typename R>
97 static bool equal_operations_ex(bg::detail::overlay::turn_operation_linear<P, R> const& op0,
98 bg::detail::overlay::turn_operation_linear<P, R> const& op1,
99 std::string const& s)
100 {
101 std::string::size_type const count = s.size();
102
103 return (count > 3
104 ? is_colinear_char(op0.is_collinear) == s[3]
105 : true)
106 && (count > 4
107 ? is_colinear_char(op1.is_collinear) == s[4]
108 : true);
109 }
110
111 static char is_colinear_char(bool is_collinear)
112 {
113 return is_collinear ? '=' : '+';
114 }
115
116 const std::string * turn_ptr;
117 };
118
119 template <typename Geometry1, typename Geometry2, typename Expected, typename Strategy>
120 void check_geometry_range(Geometry1 const& g1,
121 Geometry2 const& g2,
122 std::string const& wkt1,
123 std::string const& wkt2,
124 Expected const& expected,
125 Strategy const& strategy)
126 {
127 typedef bg::detail::no_rescale_policy robust_policy_type;
128 typedef typename bg::point_type<Geometry2>::type point_type;
129
130 typedef typename bg::segment_ratio_type
131 <
132 point_type, robust_policy_type
133 >::type segment_ratio_type;
134
135 typedef bg::detail::overlay::turn_info
136 <
137 typename bg::point_type<Geometry2>::type,
138 segment_ratio_type,
139 typename bg::detail::get_turns::turn_operation_type
140 <
141 Geometry1,
142 Geometry2,
143 segment_ratio_type
144 >::type
145 > turn_info;
146 typedef bg::detail::overlay::assign_null_policy assign_policy_t;
147 typedef bg::detail::get_turns::no_interrupt_policy interrupt_policy_t;
148
149 std::vector<turn_info> turns;
150 interrupt_policy_t interrupt_policy;
151 robust_policy_type robust_policy;
152
153 // Don't switch the geometries
154 typedef bg::detail::get_turns::get_turn_info_type
155 <
156 Geometry1, Geometry2, assign_policy_t
157 > turn_policy_t;
158
159 bg::dispatch::get_turns
160 <
161 typename bg::tag<Geometry1>::type, typename bg::tag<Geometry2>::type,
162 Geometry1, Geometry2, false, false,
163 turn_policy_t
164 >::apply(0, g1, 1, g2, strategy, robust_policy, turns, interrupt_policy);
165
166 bool ok = boost::size(expected) == turns.size();
167
168 #ifdef BOOST_GEOMETRY_TEST_DEBUG
169 std::vector<turn_info> turns_dbg = turns;
170 #endif
171
172 BOOST_CHECK_MESSAGE(ok,
173 "get_turns: " << wkt1 << " and " << wkt2
174 << " -> Expected turns #: " << boost::size(expected) << " detected turns #: " << turns.size());
175
176 for ( typename boost::range_iterator<Expected const>::type sit = boost::begin(expected) ;
177 sit != boost::end(expected) ; ++sit)
178 {
179 typename std::vector<turn_info>::iterator
180 it = std::find_if(turns.begin(), turns.end(), equal_turn(*sit));
181
182 if ( it != turns.end() )
183 turns.erase(it);
184 else
185 {
186 ok = false;
187 BOOST_CHECK_MESSAGE(false,
188 "get_turns: " << wkt1 << " and " << wkt2
189 << " -> Expected turn: " << *sit << " not found");
190 }
191 }
192
193 #ifdef BOOST_GEOMETRY_TEST_DEBUG
194 if ( !ok )
195 {
196 std::cout << "Coordinates: "
197 << typeid(typename bg::coordinate_type<Geometry1>::type).name()
198 << ", "
199 << typeid(typename bg::coordinate_type<Geometry2>::type).name()
200 << std::endl;
201 std::cout << "Detected: ";
202 if ( turns_dbg.empty() )
203 {
204 std::cout << "{empty}";
205 }
206 else
207 {
208 for ( typename std::vector<turn_info>::const_iterator it = turns_dbg.begin() ;
209 it != turns_dbg.end() ; ++it )
210 {
211 if ( it != turns_dbg.begin() )
212 std::cout << ", ";
213 std::cout << bg::method_char(it->method);
214 std::cout << bg::operation_char(it->operations[0].operation);
215 std::cout << bg::operation_char(it->operations[1].operation);
216 std::cout << equal_turn<1>::is_colinear_char(it->operations[0].is_collinear);
217 std::cout << equal_turn<1>::is_colinear_char(it->operations[1].is_collinear);
218 }
219 }
220 std::cout << std::endl;
221 }
222 #endif
223 }
224
225 template <typename Geometry1, typename Geometry2, typename Expected>
226 void check_geometry_range(Geometry1 const& g1,
227 Geometry2 const& g2,
228 std::string const& wkt1,
229 std::string const& wkt2,
230 Expected const& expected)
231 {
232 typename bg::strategy::intersection::services::default_strategy
233 <
234 typename bg::cs_tag<Geometry1>::type
235 >::type strategy;
236
237 check_geometry_range(g1, g2, wkt1, wkt2, expected, strategy);
238 }
239
240 template <typename Geometry1, typename Geometry2, typename Expected, typename Strategy>
241 void test_geometry_range(std::string const& wkt1, std::string const& wkt2,
242 Expected const& expected, Strategy const& strategy)
243 {
244 Geometry1 geometry1;
245 Geometry2 geometry2;
246 bg::read_wkt(wkt1, geometry1);
247 bg::read_wkt(wkt2, geometry2);
248 check_geometry_range(geometry1, geometry2, wkt1, wkt2, expected, strategy);
249 }
250
251 template <typename Geometry1, typename Geometry2, typename Expected>
252 void test_geometry_range(std::string const& wkt1, std::string const& wkt2,
253 Expected const& expected)
254 {
255 Geometry1 geometry1;
256 Geometry2 geometry2;
257 bg::read_wkt(wkt1, geometry1);
258 bg::read_wkt(wkt2, geometry2);
259 check_geometry_range(geometry1, geometry2, wkt1, wkt2, expected);
260 }
261
262 template <typename G1, typename G2>
263 void test_geometry(std::string const& wkt1, std::string const& wkt2,
264 std::string const& ex0)
265 {
266 test_geometry_range<G1, G2>(wkt1, wkt2, expected(ex0));
267 }
268
269 template <typename G1, typename G2>
270 void test_geometry(std::string const& wkt1, std::string const& wkt2,
271 std::string const& ex0, std::string const& ex1)
272 {
273 test_geometry_range<G1, G2>(wkt1, wkt2, expected(ex0)(ex1));
274 }
275
276 template <typename G1, typename G2>
277 void test_geometry(std::string const& wkt1, std::string const& wkt2,
278 std::string const& ex0, std::string const& ex1, std::string const& ex2)
279 {
280 test_geometry_range<G1, G2>(wkt1, wkt2, expected(ex0)(ex1)(ex2));
281 }
282
283 template <typename G1, typename G2>
284 void test_geometry(std::string const& wkt1, std::string const& wkt2,
285 expected_pusher const& expected)
286 {
287 test_geometry_range<G1, G2>(wkt1, wkt2, expected);
288 }
289
290 template <typename G1, typename G2, typename Strategy>
291 void test_geometry(std::string const& wkt1, std::string const& wkt2,
292 expected_pusher const& expected,
293 Strategy const& strategy)
294 {
295 test_geometry_range<G1, G2>(wkt1, wkt2, expected, strategy);
296 }
297
298 #endif // BOOST_GEOMETRY_TEST_ALGORITHMS_OVERLAY_TEST_GET_TURNS_HPP