diff --git a/include/boost/geometry/algorithms/detail/overlay/get_turn_info.hpp b/include/boost/geometry/algorithms/detail/overlay/get_turn_info.hpp index 5192b3aac..c038eb00c 100644 --- a/include/boost/geometry/algorithms/detail/overlay/get_turn_info.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/get_turn_info.hpp @@ -821,15 +821,17 @@ public: IntersectionInfo const& intersection_info, DirInfo const& dir_info, SidePolicy const& side, - MethodAndOperationsReplacer method_and_operations_replacer) + MethodAndOperationsReplacer method_and_operations_replacer, + bool const is_pk_valid = true, bool const is_qk_valid = true) { TurnInfo tp = tp_model; tp.method = method_collinear; // If P arrives within Q, there is a turn dependent on P - if (dir_info.arrival[0] == 1 - && set_tp<0>(pi, pj, pk, side.pk_wrt_p1(), true, qi, qj, side.pk_wrt_q1(), tp, intersection_info)) + if ( dir_info.arrival[0] == 1 + && is_pk_valid + && set_tp<0>(pi, pj, pk, side.pk_wrt_p1(), true, qi, qj, side.pk_wrt_q1(), tp, intersection_info) ) { method_and_operations_replacer(tp.method, tp.operations[0].operation, tp.operations[1].operation); @@ -838,8 +840,9 @@ public: } // If Q arrives within P, there is a turn dependent on Q - if (dir_info.arrival[1] == 1 - && set_tp<1>(qi, qj, qk, side.qk_wrt_q1(), false, pi, pj, side.qk_wrt_p1(), tp, intersection_info)) + if ( dir_info.arrival[1] == 1 + && is_qk_valid + && set_tp<1>(qi, qj, qk, side.qk_wrt_q1(), false, pi, pj, side.qk_wrt_p1(), tp, intersection_info) ) { method_and_operations_replacer(tp.method, tp.operations[0].operation, tp.operations[1].operation); diff --git a/include/boost/geometry/algorithms/detail/overlay/get_turn_info_for_endpoint.hpp b/include/boost/geometry/algorithms/detail/overlay/get_turn_info_for_endpoint.hpp index d960dd0aa..43a324c4f 100644 --- a/include/boost/geometry/algorithms/detail/overlay/get_turn_info_for_endpoint.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/get_turn_info_for_endpoint.hpp @@ -184,10 +184,10 @@ struct get_turn_info_for_endpoint p_operation0, q_operation0, tp_model, result, out); - bool result_ignore_ip0 = !opposite ? // <=> ip_count == 1 || ip_count == 2 && !opposite - append0_last : - (append0_last && (p0j || (is_q_last && q0j && q1i))); - // NOTE: based on how collinear is calculated for opposite segments + // NOTE: opposite && ip_count == 1 may be true! + + // don't ignore only for collinear opposite + bool result_ignore_ip0 = append0_last && ( ip_count == 1 || !opposite ); if ( p_operation1 == operation_none ) return result_ignore_ip0; @@ -200,11 +200,8 @@ struct get_turn_info_for_endpoint p_operation1, q_operation1, tp_model, result, out); - bool result_ignore_ip1 = !opposite ? // <=> ip_count == 2 && !opposite - append1_last : - (append1_last && (q1j || (is_p_last && p1j && p0i))); - // NOTE: based on how collinear is calculated for opposite segments - // this condition is symmetric to the one above + // don't ignore only for collinear opposite + bool result_ignore_ip1 = append1_last && !opposite /*&& ip_count == 2*/; return result_ignore_ip0 || result_ignore_ip1; } diff --git a/include/boost/geometry/algorithms/detail/overlay/get_turn_info_la.hpp b/include/boost/geometry/algorithms/detail/overlay/get_turn_info_la.hpp index 73b811aea..161f9237f 100644 --- a/include/boost/geometry/algorithms/detail/overlay/get_turn_info_la.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/get_turn_info_la.hpp @@ -234,12 +234,13 @@ struct get_turn_info_linear_areal equal::apply(pi, pj, pk, qi, qj, qk, tp, result.template get<0>(), result.template get<1>(), side_calc); - spike_detector spike_detect(side_calc); + // TODO: This isn't correct handling, hence commented out + /*spike_detector spike_detect(side_calc); if ( tp.operations[0].operation == operation_union && spike_detect.is_spike_p()) { tp.operations[0].operation = operation_continue; - } + }*/ replacer_of_method_and_operations_ec replacer(method_touch); replacer(tp.method, tp.operations[0].operation, tp.operations[1].operation); @@ -506,9 +507,7 @@ struct get_turn_info_linear_areal // IP on the last point of Linear Geometry if ( EnableLast && is_p_last - && ( ip_count > 1 ? p1j : p0j ) - && (!q0i || (q0i && q1j)) // prevents duplication - && !q1i ) // prevents duplication + && ( ip_count > 1 ? (p1j && !q1i) : (p0j && !q0i) ) ) // prevents duplication { TurnInfo tp = tp_model; diff --git a/include/boost/geometry/algorithms/detail/overlay/get_turn_info_ll.hpp b/include/boost/geometry/algorithms/detail/overlay/get_turn_info_ll.hpp index 586bc3f91..dbb2c4a11 100644 --- a/include/boost/geometry/algorithms/detail/overlay/get_turn_info_ll.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/get_turn_info_ll.hpp @@ -351,7 +351,7 @@ struct get_turn_info_linear_linear AssignPolicy >::apply(pi, pj, pk, qi, qj, qk, tp, out, result.template get<0>(), result.template get<1>(), side_calc, - replacer); + replacer, !is_p_last, !is_q_last); } } } diff --git a/test/algorithms/overlay/get_turns_linear_linear.cpp b/test/algorithms/overlay/get_turns_linear_linear.cpp index 63dae1734..fdafbdae2 100644 --- a/test/algorithms/overlay/get_turns_linear_linear.cpp +++ b/test/algorithms/overlay/get_turns_linear_linear.cpp @@ -125,6 +125,10 @@ void test_all() test_geometry("MULTILINESTRING((0 0,10 0,30 0))", "MULTILINESTRING((0 10,5 0,20 0,20 0,30 0),(2 0,2 0),(3 0,3 0,3 0))", expected("mii")("ccc")("ccc")("txx")); + + test_geometry("LINESTRING(2 2,5 -1,15 2,18 0,20 0)", + "LINESTRING(30 0,19 0,18 0,0 0)", + expected("iuu")("iuu")("tiu")("mxi")); } int test_main(int, char* [])