test_intersection_linear_linear.hpp 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Copyright (c) 2014-2017, Oracle and/or its affiliates.
  3. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
  4. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
  5. // Licensed under the Boost Software License version 1.0.
  6. // http://www.boost.org/users/license.html
  7. #ifndef BOOST_GEOMETRY_TEST_INTERSECTION_LINEAR_LINEAR_HPP
  8. #define BOOST_GEOMETRY_TEST_INTERSECTION_LINEAR_LINEAR_HPP
  9. #include <limits>
  10. #include <boost/type_traits/is_same.hpp>
  11. #include <boost/geometry/geometry.hpp>
  12. #include "../test_set_ops_linear_linear.hpp"
  13. #include <from_wkt.hpp>
  14. #include <to_svg.hpp>
  15. //==================================================================
  16. //==================================================================
  17. // intersection of (linear) geometries
  18. //==================================================================
  19. //==================================================================
  20. template <typename Geometry1, typename Geometry2, typename MultiLineString>
  21. inline void check_result(Geometry1 const& geometry1,
  22. Geometry2 const& geometry2,
  23. MultiLineString const& mls_output,
  24. MultiLineString const& mls_int1,
  25. MultiLineString const& mls_int2,
  26. std::string const& case_id,
  27. double tolerance)
  28. {
  29. BOOST_CHECK_MESSAGE( equals::apply(mls_int1, mls_output, tolerance)
  30. || equals::apply(mls_int2, mls_output, tolerance),
  31. "case id: " << case_id
  32. << ", intersection L/L: " << bg::wkt(geometry1)
  33. << " " << bg::wkt(geometry2)
  34. << " -> Expected: " << bg::wkt(mls_int1)
  35. << " or: " << bg::wkt(mls_int2)
  36. << " computed: " << bg::wkt(mls_output) );
  37. }
  38. template
  39. <
  40. typename Geometry1, typename Geometry2,
  41. typename MultiLineString
  42. >
  43. class test_intersection_of_geometries
  44. {
  45. private:
  46. static inline void base_test(Geometry1 const& geometry1,
  47. Geometry2 const& geometry2,
  48. MultiLineString const& mls_int1,
  49. MultiLineString const& mls_int2,
  50. std::string const& case_id,
  51. double tolerance,
  52. bool test_vector_and_deque = false)
  53. {
  54. static bool vector_deque_already_tested = false;
  55. typedef typename boost::range_value<MultiLineString>::type LineString;
  56. typedef std::vector<LineString> linestring_vector;
  57. typedef std::deque<LineString> linestring_deque;
  58. MultiLineString mls_output;
  59. linestring_vector ls_vector_output;
  60. linestring_deque ls_deque_output;
  61. // Check normal behaviour
  62. bg::intersection(geometry1, geometry2, mls_output);
  63. check_result(geometry1, geometry2, mls_output, mls_int1, mls_int2, case_id, tolerance);
  64. // Check strategy passed explicitly
  65. typedef typename bg::strategy::relate::services::default_strategy
  66. <
  67. Geometry1, Geometry2
  68. >::type strategy_type;
  69. bg::clear(mls_output);
  70. bg::intersection(geometry1, geometry2, mls_output, strategy_type());
  71. check_result(geometry1, geometry2, mls_output, mls_int1, mls_int2, case_id, tolerance);
  72. set_operation_output("intersection", case_id,
  73. geometry1, geometry2, mls_output);
  74. #ifdef BOOST_GEOMETRY_TEST_DEBUG
  75. std::cout << "Geometry #1: " << bg::wkt(geometry1) << std::endl;
  76. std::cout << "Geometry #2: " << bg::wkt(geometry2) << std::endl;
  77. std::cout << "intersection : " << bg::wkt(mls_output) << std::endl;
  78. std::cout << "expected intersection : " << bg::wkt(mls_int1)
  79. << " or: " << bg::wkt(mls_int2) << std::endl;
  80. std::cout << std::endl;
  81. std::cout << "************************************" << std::endl;
  82. std::cout << std::endl;
  83. std::cout << std::endl;
  84. #endif
  85. if ( !vector_deque_already_tested && test_vector_and_deque )
  86. {
  87. vector_deque_already_tested = true;
  88. #ifdef BOOST_GEOMETRY_TEST_DEBUG
  89. std::cout << std::endl;
  90. std::cout << "Testing with vector and deque as output container..."
  91. << std::endl;
  92. #endif
  93. bg::intersection(geometry1, geometry2, ls_vector_output);
  94. bg::intersection(geometry1, geometry2, ls_deque_output);
  95. BOOST_CHECK(multilinestring_equals
  96. <
  97. false
  98. >::apply(mls_int1, ls_vector_output, tolerance));
  99. BOOST_CHECK(multilinestring_equals
  100. <
  101. false
  102. >::apply(mls_int1, ls_deque_output, tolerance));
  103. #ifdef BOOST_GEOMETRY_TEST_DEBUG
  104. std::cout << "Done!" << std::endl << std::endl;
  105. #endif
  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. check_result(geometry1, geometry2, mls_output, mls_int1, mls_int2, case_id, tolerance);
  112. #ifdef BOOST_GEOMETRY_TEST_DEBUG
  113. std::cout << "Geometry #1: " << bg::wkt(geometry2) << std::endl;
  114. std::cout << "Geometry #2: " << bg::wkt(geometry1) << std::endl;
  115. std::cout << "intersection : " << bg::wkt(mls_output) << std::endl;
  116. std::cout << "expected intersection : " << bg::wkt(mls_int1)
  117. << " or: " << bg::wkt(mls_int2) << std::endl;
  118. std::cout << std::endl;
  119. std::cout << "************************************" << std::endl;
  120. std::cout << std::endl;
  121. std::cout << std::endl;
  122. #endif
  123. }
  124. #ifdef BOOST_GEOMETRY_TEST_DEBUG
  125. static inline void base_test_all(Geometry1 const& geometry1,
  126. Geometry2 const& geometry2)
  127. {
  128. typedef typename bg::point_type<MultiLineString>::type Point;
  129. typedef bg::model::multi_point<Point> multi_point;
  130. MultiLineString mls12_output, mls21_output;
  131. multi_point mp12_output, mp21_output;
  132. bg::intersection(geometry1, geometry2, mls12_output);
  133. bg::intersection(geometry1, geometry2, mp12_output);
  134. bg::intersection(geometry2, geometry1, mls21_output);
  135. bg::intersection(geometry2, geometry1, mp21_output);
  136. std::cout << "************************************" << std::endl;
  137. std::cout << "Geometry #1: " << bg::wkt(geometry1) << std::endl;
  138. std::cout << "Geometry #2: " << bg::wkt(geometry2) << std::endl;
  139. std::cout << "intersection(1,2) [MLS]: " << bg::wkt(mls12_output)
  140. << std::endl;
  141. std::cout << "intersection(2,1) [MLS]: " << bg::wkt(mls21_output)
  142. << std::endl;
  143. std::cout << std::endl;
  144. std::cout << "intersection(1,2) [MP]: " << bg::wkt(mp12_output)
  145. << std::endl;
  146. std::cout << "intersection(2,1) [MP]: " << bg::wkt(mp21_output)
  147. << std::endl;
  148. std::cout << std::endl;
  149. std::cout << "************************************" << std::endl;
  150. std::cout << std::endl;
  151. std::cout << std::endl;
  152. }
  153. #else
  154. static inline void base_test_all(Geometry1 const&, Geometry2 const&)
  155. {
  156. }
  157. #endif
  158. public:
  159. static inline void apply(Geometry1 const& geometry1,
  160. Geometry2 const& geometry2,
  161. MultiLineString const& mls_int1,
  162. MultiLineString const& mls_int2,
  163. std::string const& case_id,
  164. double tolerance
  165. = std::numeric_limits<double>::epsilon())
  166. {
  167. #ifdef BOOST_GEOMETRY_TEST_DEBUG
  168. std::cout << "test case: " << case_id << std::endl;
  169. std::stringstream sstr;
  170. sstr << "svgs/" << case_id << ".svg";
  171. #ifdef TEST_WITH_SVG
  172. to_svg(geometry1, geometry2, sstr.str());
  173. #endif
  174. #endif
  175. Geometry1 rg1(geometry1);
  176. bg::reverse<Geometry1>(rg1);
  177. Geometry2 rg2(geometry2);
  178. bg::reverse<Geometry2>(rg2);
  179. typedef typename bg::tag_cast
  180. <
  181. Geometry1, bg::linear_tag
  182. >::type tag1_type;
  183. typedef typename bg::tag_cast
  184. <
  185. Geometry2, bg::linear_tag
  186. >::type tag2_type;
  187. bool const are_linear
  188. = boost::is_same<tag1_type, bg::linear_tag>::value
  189. && boost::is_same<tag2_type, bg::linear_tag>::value;
  190. test_get_turns_ll_invariance<are_linear>::apply(geometry1, geometry2);
  191. #ifdef BOOST_GEOMETRY_TEST_DEBUG
  192. std::cout << std::endl
  193. << "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"
  194. << std::endl << std::endl;
  195. #endif
  196. test_get_turns_ll_invariance<are_linear>::apply(rg1, geometry2);
  197. base_test(geometry1, geometry2, mls_int1, mls_int2, case_id, tolerance);
  198. // base_test(rg1, rg2, mls_int1, mls_int2);
  199. base_test_all(geometry1, geometry2);
  200. #ifdef BOOST_GEOMETRY_TEST_DEBUG
  201. std::cout << std::endl;
  202. std::cout << std::endl;
  203. #endif
  204. }
  205. static inline void apply(Geometry1 const& geometry1,
  206. Geometry2 const& geometry2,
  207. MultiLineString const& mls_int,
  208. std::string const& case_id,
  209. double tolerance
  210. = std::numeric_limits<double>::epsilon())
  211. {
  212. apply(geometry1, geometry2, mls_int, mls_int, case_id, tolerance);
  213. }
  214. };
  215. #endif // BOOST_GEOMETRY_TEST_INTERSECTION_LINEAR_LINEAR_HPP