1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2 
3 // Copyright (c) 2014-2015, Oracle and/or its affiliates.
4 
5 // Licensed under the Boost Software License version 1.0.
6 // http://www.boost.org/users/license.html
7 
8 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
9 
10 #ifndef BOOST_GEOMETRY_TEST_UNION_LINEAR_LINEAR_HPP
11 #define BOOST_GEOMETRY_TEST_UNION_LINEAR_LINEAR_HPP
12 
13 #include <limits>
14 
15 #include <boost/geometry/geometry.hpp>
16 #include "../test_set_ops_linear_linear.hpp"
17 #include <from_wkt.hpp>
18 #include <to_svg.hpp>
19 
20 
21 //==================================================================
22 //==================================================================
23 // union of (linear) geometries
24 //==================================================================
25 //==================================================================
26 
27 template
28 <
29     typename Geometry1, typename Geometry2,
30     typename MultiLineString
31 >
32 class test_union_of_geometries
33 {
34 private:
base_test(Geometry1 const & geometry1,Geometry2 const & geometry2,MultiLineString const & mls_union1,MultiLineString const & mls_union2,std::string const & case_id,double tolerance,bool test_vector_and_deque=false)35     static inline void base_test(Geometry1 const& geometry1,
36                                  Geometry2 const& geometry2,
37                                  MultiLineString const& mls_union1,
38                                  MultiLineString const& mls_union2,
39                                  std::string const& case_id,
40                                  double tolerance,
41                                  bool test_vector_and_deque = false)
42     {
43         static bool vector_deque_already_tested = false;
44 
45         typedef typename boost::range_value<MultiLineString>::type LineString;
46         typedef std::vector<LineString> linestring_vector;
47         typedef std::deque<LineString> linestring_deque;
48 
49         MultiLineString mls_output;
50 
51         linestring_vector ls_vector_output;
52         linestring_deque ls_deque_output;
53 
54         bg::union_(geometry1, geometry2, mls_output);
55 
56         BOOST_CHECK_MESSAGE( equals::apply(mls_union1, mls_output, tolerance),
57                              "case id: " << case_id
58                              << ", union L/L: " << bg::wkt(geometry1)
59                              << " " << bg::wkt(geometry2)
60                              << " -> Expected: " << bg::wkt(mls_union1)
61                              << " computed: " << bg::wkt(mls_output) );
62 
63         set_operation_output("union", case_id,
64                              geometry1, geometry2, mls_output);
65 
66 #ifdef BOOST_GEOMETRY_TEST_DEBUG
67         std::cout << "Geometry #1: " << bg::wkt(geometry1) << std::endl;
68         std::cout << "Geometry #2: " << bg::wkt(geometry2) << std::endl;
69         std::cout << "union : " << bg::wkt(mls_output) << std::endl;
70         std::cout << "expected union : " << bg::wkt(mls_union1)
71                   << std::endl;
72         std::cout << std::endl;
73         std::cout << "************************************" << std::endl;
74         std::cout << std::endl;
75         std::cout << std::endl;
76 #endif
77 
78         if ( !vector_deque_already_tested && test_vector_and_deque )
79         {
80             vector_deque_already_tested = true;
81 #ifdef BOOST_GEOMETRY_TEST_DEBUG
82             std::cout << std::endl;
83             std::cout << "Testing with vector and deque as output container..."
84                       << std::endl;
85 #endif
86             bg::union_(geometry1, geometry2, ls_vector_output);
87             bg::union_(geometry1, geometry2, ls_deque_output);
88 
89             BOOST_CHECK(multilinestring_equals
90                         <
91                             false
92                         >::apply(mls_union1, ls_vector_output, tolerance));
93 
94             BOOST_CHECK(multilinestring_equals
95                         <
96                             false
97                         >::apply(mls_union1, ls_deque_output, tolerance));
98 
99 #ifdef BOOST_GEOMETRY_TEST_DEBUG
100             std::cout << "Done!" << std::endl << std::endl;
101 #endif
102         }
103 
104         // check the symmetric difference where the order of the two
105         // geometries is reversed
106         bg::clear(mls_output);
107         bg::union_(geometry2, geometry1, mls_output);
108 
109         BOOST_CHECK_MESSAGE( equals::apply(mls_union2, mls_output, tolerance),
110                              "case id: " << case_id
111                              << ", union L/L: " << bg::wkt(geometry2)
112                              << " " << bg::wkt(geometry1)
113                              << " -> Expected: " << bg::wkt(mls_union2)
114                              << " computed: " << bg::wkt(mls_output) );
115 
116 #ifdef BOOST_GEOMETRY_TEST_DEBUG
117         std::cout << "Geometry #1: " << bg::wkt(geometry2) << std::endl;
118         std::cout << "Geometry #2: " << bg::wkt(geometry1) << std::endl;
119         std::cout << "union : " << bg::wkt(mls_output) << std::endl;
120         std::cout << "expected union : " << bg::wkt(mls_union2)
121                   << std::endl;
122         std::cout << std::endl;
123         std::cout << "************************************" << std::endl;
124         std::cout << std::endl;
125         std::cout << std::endl;
126 #endif
127     }
128 
129 
130 public:
apply(Geometry1 const & geometry1,Geometry2 const & geometry2,MultiLineString const & mls_union1,MultiLineString const & mls_union2,std::string const & case_id,double tolerance=std::numeric_limits<double>::epsilon ())131     static inline void apply(Geometry1 const& geometry1,
132                              Geometry2 const& geometry2,
133                              MultiLineString const& mls_union1,
134                              MultiLineString const& mls_union2,
135                              std::string const& case_id,
136                              double tolerance
137                                  = std::numeric_limits<double>::epsilon())
138     {
139 #ifdef BOOST_GEOMETRY_TEST_DEBUG
140         std::cout << "test case: " << case_id << std::endl;
141         std::stringstream sstr;
142         sstr << "svgs/" << case_id << ".svg";
143         to_svg(geometry1, geometry2, sstr.str());
144 #endif
145 
146         Geometry1 rg1(geometry1);
147         bg::reverse<Geometry1>(rg1);
148 
149         Geometry2 rg2(geometry2);
150         bg::reverse<Geometry2>(rg2);
151 
152         test_get_turns_ll_invariance<>::apply(geometry1, geometry2);
153 #ifdef BOOST_GEOMETRY_TEST_DEBUG
154         std::cout << std::endl
155                   << "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"
156                   << std::endl << std::endl;
157 #endif
158         test_get_turns_ll_invariance<>::apply(rg1, geometry2);
159 
160         base_test(geometry1, geometry2, mls_union1, mls_union2,
161                   case_id, tolerance, true);
162         //        base_test(geometry1, rg2, mls_sym_diff);
163         //        base_test(rg1, geometry2, mls_sym_diff);
164         base_test(rg1, rg2, mls_union1, mls_union2, case_id, tolerance);
165 
166 #ifdef BOOST_GEOMETRY_TEST_DEBUG
167         std::cout << std::endl;
168         std::cout << std::endl;
169 #endif
170     }
171 
172 
apply(Geometry1 const & geometry1,Geometry2 const & geometry2,MultiLineString const & mls_union,std::string const & case_id,double tolerance=std::numeric_limits<double>::epsilon ())173     static inline void apply(Geometry1 const& geometry1,
174                              Geometry2 const& geometry2,
175                              MultiLineString const& mls_union,
176                              std::string const& case_id,
177                              double tolerance
178                                  = std::numeric_limits<double>::epsilon())
179     {
180         apply(geometry1, geometry2, mls_union, mls_union, case_id, tolerance);
181     }
182 };
183 
184 
185 #endif // BOOST_GEOMETRY_TEST_UNION1_HPP
186