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_INTERSECTION_LINEAR_LINEAR_HPP 11 #define BOOST_GEOMETRY_TEST_INTERSECTION_LINEAR_LINEAR_HPP 12 13 #include <limits> 14 15 #include <boost/type_traits/is_same.hpp> 16 17 #include <boost/geometry/geometry.hpp> 18 #include "../test_set_ops_linear_linear.hpp" 19 #include <from_wkt.hpp> 20 #include <to_svg.hpp> 21 22 23 //================================================================== 24 //================================================================== 25 // intersection of (linear) geometries 26 //================================================================== 27 //================================================================== 28 29 template 30 < 31 typename Geometry1, typename Geometry2, 32 typename MultiLineString 33 > 34 class test_intersection_of_geometries 35 { 36 private: base_test(Geometry1 const & geometry1,Geometry2 const & geometry2,MultiLineString const & mls_int1,MultiLineString const & mls_int2,std::string const & case_id,double tolerance,bool test_vector_and_deque=false)37 static inline void base_test(Geometry1 const& geometry1, 38 Geometry2 const& geometry2, 39 MultiLineString const& mls_int1, 40 MultiLineString const& mls_int2, 41 std::string const& case_id, 42 double tolerance, 43 bool test_vector_and_deque = false) 44 { 45 static bool vector_deque_already_tested = false; 46 47 typedef typename boost::range_value<MultiLineString>::type LineString; 48 typedef std::vector<LineString> linestring_vector; 49 typedef std::deque<LineString> linestring_deque; 50 51 MultiLineString mls_output; 52 53 linestring_vector ls_vector_output; 54 linestring_deque ls_deque_output; 55 56 bg::intersection(geometry1, geometry2, mls_output); 57 58 BOOST_CHECK_MESSAGE( equals::apply(mls_int1, mls_output, tolerance) 59 || equals::apply(mls_int2, mls_output, tolerance), 60 "case id: " << case_id 61 << ", intersection L/L: " << bg::wkt(geometry1) 62 << " " << bg::wkt(geometry2) 63 << " -> Expected: " << bg::wkt(mls_int1) 64 << " or: " << bg::wkt(mls_int2) 65 << " computed: " << bg::wkt(mls_output) ); 66 67 set_operation_output("intersection", case_id, 68 geometry1, geometry2, mls_output); 69 #ifdef BOOST_GEOMETRY_TEST_DEBUG 70 std::cout << "Geometry #1: " << bg::wkt(geometry1) << std::endl; 71 std::cout << "Geometry #2: " << bg::wkt(geometry2) << std::endl; 72 std::cout << "intersection : " << bg::wkt(mls_output) << std::endl; 73 std::cout << "expected intersection : " << bg::wkt(mls_int1) 74 << " or: " << bg::wkt(mls_int2) << std::endl; 75 std::cout << std::endl; 76 std::cout << "************************************" << std::endl; 77 std::cout << std::endl; 78 std::cout << std::endl; 79 #endif 80 81 if ( !vector_deque_already_tested && test_vector_and_deque ) 82 { 83 vector_deque_already_tested = true; 84 #ifdef BOOST_GEOMETRY_TEST_DEBUG 85 std::cout << std::endl; 86 std::cout << "Testing with vector and deque as output container..." 87 << std::endl; 88 #endif 89 bg::intersection(geometry1, geometry2, ls_vector_output); 90 bg::intersection(geometry1, geometry2, ls_deque_output); 91 92 BOOST_CHECK(multilinestring_equals 93 < 94 false 95 >::apply(mls_int1, ls_vector_output, tolerance)); 96 97 BOOST_CHECK(multilinestring_equals 98 < 99 false 100 >::apply(mls_int1, ls_deque_output, tolerance)); 101 102 #ifdef BOOST_GEOMETRY_TEST_DEBUG 103 std::cout << "Done!" << std::endl << std::endl; 104 #endif 105 } 106 107 // check the intersection where the order of the two 108 // geometries is reversed 109 bg::clear(mls_output); 110 bg::intersection(geometry2, geometry1, mls_output); 111 112 BOOST_CHECK_MESSAGE( equals::apply(mls_int1, mls_output, tolerance) 113 || equals::apply(mls_int2, mls_output, tolerance), 114 "case id: " << case_id 115 << ", intersection L/L: " << bg::wkt(geometry1) 116 << " " << bg::wkt(geometry2) 117 << " -> Expected: " << bg::wkt(mls_int1) 118 << " or: " << bg::wkt(mls_int2) 119 << " computed: " << bg::wkt(mls_output) ); 120 121 #ifdef BOOST_GEOMETRY_TEST_DEBUG 122 std::cout << "Geometry #1: " << bg::wkt(geometry2) << std::endl; 123 std::cout << "Geometry #2: " << bg::wkt(geometry1) << std::endl; 124 std::cout << "intersection : " << bg::wkt(mls_output) << std::endl; 125 std::cout << "expected intersection : " << bg::wkt(mls_int1) 126 << " or: " << bg::wkt(mls_int2) << std::endl; 127 std::cout << std::endl; 128 std::cout << "************************************" << std::endl; 129 std::cout << std::endl; 130 std::cout << std::endl; 131 #endif 132 } 133 134 #ifdef BOOST_GEOMETRY_TEST_DEBUG base_test_all(Geometry1 const & geometry1,Geometry2 const & geometry2)135 static inline void base_test_all(Geometry1 const& geometry1, 136 Geometry2 const& geometry2) 137 { 138 typedef typename bg::point_type<MultiLineString>::type Point; 139 typedef bg::model::multi_point<Point> multi_point; 140 141 MultiLineString mls12_output, mls21_output; 142 multi_point mp12_output, mp21_output; 143 144 bg::intersection(geometry1, geometry2, mls12_output); 145 bg::intersection(geometry1, geometry2, mp12_output); 146 bg::intersection(geometry2, geometry1, mls21_output); 147 bg::intersection(geometry2, geometry1, mp21_output); 148 149 std::cout << "************************************" << std::endl; 150 std::cout << "Geometry #1: " << bg::wkt(geometry1) << std::endl; 151 std::cout << "Geometry #2: " << bg::wkt(geometry2) << std::endl; 152 std::cout << "intersection(1,2) [MLS]: " << bg::wkt(mls12_output) 153 << std::endl; 154 std::cout << "intersection(2,1) [MLS]: " << bg::wkt(mls21_output) 155 << std::endl; 156 std::cout << std::endl; 157 std::cout << "intersection(1,2) [MP]: " << bg::wkt(mp12_output) 158 << std::endl; 159 std::cout << "intersection(2,1) [MP]: " << bg::wkt(mp21_output) 160 << std::endl; 161 std::cout << std::endl; 162 std::cout << "************************************" << std::endl; 163 std::cout << std::endl; 164 std::cout << std::endl; 165 } 166 #else base_test_all(Geometry1 const &,Geometry2 const &)167 static inline void base_test_all(Geometry1 const&, Geometry2 const&) 168 { 169 } 170 #endif 171 172 173 public: apply(Geometry1 const & geometry1,Geometry2 const & geometry2,MultiLineString const & mls_int1,MultiLineString const & mls_int2,std::string const & case_id,double tolerance=std::numeric_limits<double>::epsilon ())174 static inline void apply(Geometry1 const& geometry1, 175 Geometry2 const& geometry2, 176 MultiLineString const& mls_int1, 177 MultiLineString const& mls_int2, 178 std::string const& case_id, 179 double tolerance 180 = std::numeric_limits<double>::epsilon()) 181 { 182 #ifdef BOOST_GEOMETRY_TEST_DEBUG 183 std::cout << "test case: " << case_id << std::endl; 184 std::stringstream sstr; 185 sstr << "svgs/" << case_id << ".svg"; 186 #ifdef TEST_WITH_SVG 187 to_svg(geometry1, geometry2, sstr.str()); 188 #endif 189 #endif 190 191 Geometry1 rg1(geometry1); 192 bg::reverse<Geometry1>(rg1); 193 194 Geometry2 rg2(geometry2); 195 bg::reverse<Geometry2>(rg2); 196 197 typedef typename bg::tag_cast 198 < 199 Geometry1, bg::linear_tag 200 >::type tag1_type; 201 202 typedef typename bg::tag_cast 203 < 204 Geometry2, bg::linear_tag 205 >::type tag2_type; 206 207 bool const are_linear 208 = boost::is_same<tag1_type, bg::linear_tag>::value 209 && boost::is_same<tag2_type, bg::linear_tag>::value; 210 211 test_get_turns_ll_invariance<are_linear>::apply(geometry1, geometry2); 212 #ifdef BOOST_GEOMETRY_TEST_DEBUG 213 std::cout << std::endl 214 << "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" 215 << std::endl << std::endl; 216 #endif 217 test_get_turns_ll_invariance<are_linear>::apply(rg1, geometry2); 218 219 base_test(geometry1, geometry2, mls_int1, mls_int2, case_id, tolerance); 220 // base_test(rg1, rg2, mls_int1, mls_int2); 221 base_test_all(geometry1, geometry2); 222 223 #ifdef BOOST_GEOMETRY_TEST_DEBUG 224 std::cout << std::endl; 225 std::cout << std::endl; 226 #endif 227 } 228 229 230 apply(Geometry1 const & geometry1,Geometry2 const & geometry2,MultiLineString const & mls_int,std::string const & case_id,double tolerance=std::numeric_limits<double>::epsilon ())231 static inline void apply(Geometry1 const& geometry1, 232 Geometry2 const& geometry2, 233 MultiLineString const& mls_int, 234 std::string const& case_id, 235 double tolerance 236 = std::numeric_limits<double>::epsilon()) 237 { 238 apply(geometry1, geometry2, mls_int, mls_int, case_id, tolerance); 239 } 240 }; 241 242 243 #endif // BOOST_GEOMETRY_TEST_INTERSECTION_LINEAR_LINEAR_HPP 244