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