1 // Boost.Geometry (aka GGL, Generic Geometry Library) 2 3 // Copyright (c) 2014, 2019, Oracle and/or its affiliates. 4 5 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle 6 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle 7 8 // Licensed under the Boost Software License version 1.0. 9 // http://www.boost.org/users/license.html 10 11 #ifndef BOOST_GEOMETRY_TEST_GET_TURNS_LL_INVARIANCE_HPP 12 #define BOOST_GEOMETRY_TEST_GET_TURNS_LL_INVARIANCE_HPP 13 14 #include <vector> 15 16 #include <boost/geometry/algorithms/reverse.hpp> 17 18 #include <boost/geometry/algorithms/detail/signed_size_type.hpp> 19 20 #include <boost/geometry/algorithms/detail/relate/turns.hpp> 21 22 #include <boost/geometry/algorithms/detail/turns/compare_turns.hpp> 23 #include <boost/geometry/algorithms/detail/turns/print_turns.hpp> 24 #include <boost/geometry/algorithms/detail/turns/filter_continue_turns.hpp> 25 #include <boost/geometry/algorithms/detail/turns/remove_duplicate_turns.hpp> 26 27 #include <boost/geometry/io/wkt/write.hpp> 28 29 30 namespace bg = ::boost::geometry; 31 namespace bg_detail = ::boost::geometry::detail; 32 namespace bg_turns = bg_detail::turns; 33 34 template 35 < 36 bool Enable = true, 37 bool EnableRemoveDuplicateTurns = true, 38 bool EnableDegenerateTurns = true 39 > 40 class test_get_turns_ll_invariance 41 { 42 private: 43 struct assign_policy 44 { 45 static bool const include_no_turn = false; 46 static bool const include_degenerate = EnableDegenerateTurns; 47 static bool const include_opposite = false; 48 49 template 50 < 51 typename Info, 52 typename Point1, 53 typename Point2, 54 typename IntersectionInfo 55 > applytest_get_turns_ll_invariance::assign_policy56 static inline void apply(Info& , Point1 const& , Point2 const& , 57 IntersectionInfo const&) 58 { 59 } 60 }; 61 62 63 64 template 65 < 66 typename Turns, 67 typename LinearGeometry1, 68 typename LinearGeometry2 69 > compute_turns(Turns & turns,LinearGeometry1 const & linear1,LinearGeometry2 const & linear2)70 static inline void compute_turns(Turns& turns, 71 LinearGeometry1 const& linear1, 72 LinearGeometry2 const& linear2) 73 { 74 turns.clear(); 75 bg_detail::relate::turns::get_turns 76 < 77 LinearGeometry1, 78 LinearGeometry2, 79 bg_detail::get_turns::get_turn_info_type 80 < 81 LinearGeometry1, 82 LinearGeometry2, 83 assign_policy 84 > 85 >::apply(turns, linear1, linear2); 86 } 87 88 89 90 public: 91 template <typename Linear1, typename Linear2> apply(Linear1 const & lineargeometry1,Linear2 const & lineargeometry2)92 static inline void apply(Linear1 const& lineargeometry1, 93 Linear2 const& lineargeometry2) 94 { 95 typedef typename bg::strategy::relate::services::default_strategy 96 < 97 Linear1, Linear2 98 >::type strategy_type; 99 100 typedef typename bg_detail::relate::turns::get_turns 101 < 102 Linear1, Linear2 103 >::template turn_info_type<strategy_type>::type turn_info; 104 105 typedef std::vector<turn_info> turns_container; 106 107 typedef bg_turns::filter_continue_turns 108 < 109 turns_container, true 110 > filter_continue_turns; 111 112 typedef bg_turns::remove_duplicate_turns 113 < 114 turns_container, EnableRemoveDuplicateTurns 115 > remove_duplicate_turns; 116 117 turns_container turns; 118 119 Linear1 linear1(lineargeometry1); 120 Linear2 linear2(lineargeometry2); 121 122 Linear2 linear2_reverse(linear2); 123 boost::geometry::reverse(linear2_reverse); 124 125 turns_container turns_all, rturns_all; 126 compute_turns(turns_all, linear1, linear2); 127 compute_turns(rturns_all, linear1, linear2_reverse); 128 129 turns_container turns_wo_cont(turns_all); 130 turns_container rturns_wo_cont(rturns_all); 131 132 filter_continue_turns::apply(turns_wo_cont); 133 filter_continue_turns::apply(rturns_wo_cont); 134 135 std::sort(boost::begin(turns_all), boost::end(turns_all), 136 bg_turns::less_seg_fraction_other_op<>()); 137 138 std::sort(boost::begin(turns_wo_cont), boost::end(turns_wo_cont), 139 bg_turns::less_seg_fraction_other_op<>()); 140 141 std::sort(boost::begin(rturns_all), boost::end(rturns_all), 142 bg_turns::less_seg_fraction_other_op<std::greater<boost::geometry::signed_size_type> >()); 143 144 std::sort(boost::begin(rturns_wo_cont), boost::end(rturns_wo_cont), 145 bg_turns::less_seg_fraction_other_op<std::greater<boost::geometry::signed_size_type> >()); 146 147 remove_duplicate_turns::apply(turns_all); 148 remove_duplicate_turns::apply(turns_wo_cont); 149 remove_duplicate_turns::apply(rturns_all); 150 remove_duplicate_turns::apply(rturns_wo_cont); 151 152 #ifdef BOOST_GEOMETRY_TEST_DEBUG 153 std::cout << std::endl << std::endl; 154 std::cout << "### ORIGINAL TURNS ###" << std::endl; 155 bg_turns::print_turns(linear1, linear2, turns_all); 156 std::cout << std::endl << std::endl; 157 std::cout << "### ORIGINAL REVERSE TURNS ###" << std::endl; 158 bg_turns::print_turns(linear1, linear2_reverse, rturns_all); 159 std::cout << std::endl << std::endl; 160 std::cout << "### TURNS W/O CONTINUE TURNS ###" << std::endl; 161 bg_turns::print_turns(linear1, linear2, turns_wo_cont); 162 std::cout << std::endl << std::endl; 163 std::cout << "### REVERSE TURNS W/O CONTINUE TURNS ###" << std::endl; 164 bg_turns::print_turns(linear1, linear2_reverse, rturns_wo_cont); 165 std::cout << std::endl << std::endl; 166 #endif 167 168 BOOST_CHECK_MESSAGE(boost::size(turns_wo_cont) == boost::size(rturns_wo_cont), 169 "Incompatible turns count: " << boost::size(turns_wo_cont) << 170 " and " << boost::size(rturns_wo_cont) << 171 " for L1: " << bg::wkt(lineargeometry1) << 172 ", L2: " << bg::wkt(lineargeometry2)); 173 } 174 }; 175 176 template <bool EnableRemoveDuplicateTurns, bool EnableDegenerateTurns> 177 class test_get_turns_ll_invariance 178 < 179 false, EnableRemoveDuplicateTurns, EnableDegenerateTurns 180 > 181 { 182 public: 183 template <typename Linear1, typename Linear2> apply(Linear1 const &,Linear2 const &)184 static inline void apply(Linear1 const&, Linear2 const&) 185 { 186 } 187 }; 188 189 #endif // BOOST_GEOMETRY_TEST_GET_TURNS_LL_INVARIANCE_HPP 190