diff --git a/include/boost/geometry/algorithms/detail/overlay/follow_linear_linear.hpp b/include/boost/geometry/algorithms/detail/overlay/follow_linear_linear.hpp index 3980709b9..a3b74967b 100644 --- a/include/boost/geometry/algorithms/detail/overlay/follow_linear_linear.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/follow_linear_linear.hpp @@ -29,19 +29,21 @@ namespace following { namespace linear // follower for linear/linear geometries set operations template -static inline bool is_entering(Turn const& turn, Operation const& op) +static inline bool is_entering(Turn const& turn, + Operation const& operation) { if ( turn.method != method_touch && turn.method != method_touch_interior ) { return false; } - return op.operation == operation_intersection; + return operation.operation == operation_intersection; } template -static inline bool is_staying_inside(Turn const& turn, Operation const& op, +static inline bool is_staying_inside(Turn const& turn, + Operation const& operation, bool entered) { if ( !entered ) @@ -53,14 +55,15 @@ static inline bool is_staying_inside(Turn const& turn, Operation const& op, { return false; } - return op.operation == operation_continue; + return operation.operation == operation_continue; } template -static inline bool is_leaving(Turn const& turn, Operation const& op, - Operation const& reverse_op, +static inline bool is_leaving(Turn const& turn, + Operation const& operation, + Operation const& reverse_operation, bool entered) { if ( !entered ) @@ -68,20 +71,20 @@ static inline bool is_leaving(Turn const& turn, Operation const& op, return false; } - if ( turn.method != method_touch && - turn.method != method_touch_interior && - turn.method != method_equal && - turn.method != method_collinear ) + if ( turn.method != method_touch + && turn.method != method_touch_interior + && turn.method != method_equal + && turn.method != method_collinear ) { return false; } - if ( op.operation == operation_blocked ) + if ( operation.operation == operation_blocked ) { return true; } - if ( op.operation != operation_union ) + if ( operation.operation != operation_union ) { return false; } @@ -91,16 +94,17 @@ static inline bool is_leaving(Turn const& turn, Operation const& op, return true; } - BOOST_ASSERT( turn.operations[1].operation == operation_union || - turn.operations[1].operation == operation_blocked ); + BOOST_ASSERT( turn.operations[1].operation == operation_union + || turn.operations[1].operation == operation_blocked ); - return reverse_op.operation == operation_intersection; + return reverse_operation.operation == operation_intersection; } template -static inline bool is_isolated_point(Turn const& turn, Operation const& op, - Operation const& reverse_op, +static inline bool is_isolated_point(Turn const& turn, + Operation const& operation, + Operation const& reverse_operation, bool entered) { if ( entered ) @@ -118,12 +122,12 @@ static inline bool is_isolated_point(Turn const& turn, Operation const& op, return false; } - if ( op.operation == operation_blocked ) + if ( operation.operation == operation_blocked ) { return true; } - if ( op.operation != operation_union ) + if ( operation.operation != operation_union ) { return false; } @@ -133,11 +137,11 @@ static inline bool is_isolated_point(Turn const& turn, Operation const& op, return false; } - BOOST_ASSERT( turn.operations[1].operation == operation_union || - turn.operations[1].operation == operation_blocked ); + BOOST_ASSERT( turn.operations[1].operation == operation_union + || turn.operations[1].operation == operation_blocked ); - return reverse_op.operation == operation_union - || reverse_op.operation == operation_blocked; + return reverse_operation.operation == operation_union + || reverse_operation.operation == operation_blocked; } @@ -152,82 +156,77 @@ template class follow_linestring_linestring_linestring { protected: - typedef typename point_type::type PointOut; - typedef traversal_turn_info turn_info; - - typedef typename boost::range_iterator - < - typename turn_info::container_type const - >::type turn_operation_iterator_type; - typedef following::action_selector action; template < - typename TurnIt, - typename TurnOpIt, + typename TurnIterator, + typename TurnOperationIterator, typename SegmentIdentifier, typename OutputIterator > static inline OutputIterator - process_turn(TurnIt it, TurnIt it_r, - TurnOpIt iit, TurnOpIt iit_r, + process_turn(TurnIterator it, TurnIterator it_r, + TurnOperationIterator op_it, TurnOperationIterator op_it_r, bool& first, bool& entered, std::size_t& enter_count, - LineString1 const& ls1, LineString2 const&, + LineString1 const& linestring1, LineString2 const&, LineStringOut& current_piece, SegmentIdentifier& current_segment_id, OutputIterator oit) { - if ( is_entering(*it, *iit) ) + if ( is_entering(*it, *op_it) ) { #ifdef GEOMETRY_TEST_DEBUG - detail::overlay::debug_traverse(*it, *iit, "-> Entering"); + detail::overlay::debug_traverse(*it, *op_it, "-> Entering"); #endif entered = true; if ( enter_count == 0 ) { - action::enter(current_piece, ls1, current_segment_id, - iit->seg_id.segment_index, - it->point, *iit, oit); + action::enter(current_piece, linestring1, + current_segment_id, + op_it->seg_id.segment_index, + it->point, *op_it, oit); } ++enter_count; } - else if ( is_staying_inside(*it, *iit, entered) ) + else if ( is_staying_inside(*it, *op_it, entered) ) { #ifdef GEOMETRY_TEST_DEBUG - detail::overlay::debug_traverse(*it, *iit, "-> Staying inside"); + detail::overlay::debug_traverse(*it, *op_it, "-> Staying inside"); #endif entered = true; } - else if ( is_leaving(*it, *iit, *iit_r, entered) ) + else if ( is_leaving(*it, *op_it, *op_it_r, entered) ) { #ifdef GEOMETRY_TEST_DEBUG - detail::overlay::debug_traverse(*it, *iit, "-> Leaving"); + detail::overlay::debug_traverse(*it, *op_it, "-> Leaving"); #endif --enter_count; if ( enter_count == 0 ) { entered = false; - action::leave(current_piece, ls1, current_segment_id, - iit->seg_id.segment_index, - it->point, *iit, oit); + action::leave(current_piece, linestring1, + current_segment_id, + op_it->seg_id.segment_index, + it->point, *op_it, oit); } } #ifndef BOOST_GEOMETRY_INTERSECTION_DO_NOT_INCLUDE_ISOLATED_POINTS else if ( FollowIsolatedPoints && - is_isolated_point(*it, *iit, *iit_r, entered) ) + is_isolated_point(*it, *op_it, *op_it_r, entered) ) { #ifdef GEOMETRY_TEST_DEBUG - detail::overlay::debug_traverse(*it, *iit, "-> Isolated point"); + detail::overlay::debug_traverse(*it, *op_it, "-> Isolated point"); #endif - action::isolated_point(current_piece, ls1, current_segment_id, - iit->seg_id.segment_index, - it->point, *iit, oit); + action::isolated_point(current_piece, linestring1, + current_segment_id, + op_it->seg_id.segment_index, + it->point, *op_it, oit); } #endif first = false; @@ -248,7 +247,8 @@ protected: { if ( action::is_entered(entered) ) { - geometry::copy_segments(linestring1, current_segment_id, + geometry::copy_segments(linestring1, + current_segment_id, boost::size(linestring1) - 1, current_piece); } @@ -272,7 +272,12 @@ public: { BOOST_ASSERT( boost::size(turns) == boost::size(reverse_turns) ); - typedef typename boost::range_iterator::type TurnIt; + typedef typename boost::range_iterator::type TurnIterator; + typedef typename boost::range_value::type TurnInfo; + typedef typename boost::range_iterator + < + typename TurnInfo::container_type const + >::type TurnOperationIterator; // Iterate through all intersection points (they are // ordered along the each line) @@ -284,15 +289,15 @@ public: bool first = true; std::size_t enter_count = 0; - TurnIt it = boost::begin(turns); - TurnIt it_r = boost::begin(reverse_turns); + TurnIterator it = boost::begin(turns); + TurnIterator it_r = boost::begin(reverse_turns); for (; it != boost::end(turns); ++it, ++it_r) { - turn_operation_iterator_type iit = boost::begin(it->operations); - turn_operation_iterator_type iit_r = boost::begin(it_r->operations); - ++iit_r; + TurnOperationIterator op_it = boost::begin(it->operations); + TurnOperationIterator op_it_r = boost::begin(it_r->operations); + ++op_it_r; - oit = process_turn(it, it_r, iit, iit_r, + oit = process_turn(it, it_r, op_it, op_it_r, first, entered, enter_count, linestring1, linestring2, current_piece, current_segment_id, @@ -336,14 +341,6 @@ protected: OverlayType, FollowIsolatedPoints > Base; - typedef typename point_type::type PointOut; - typedef traversal_turn_info turn_info; - - typedef typename boost::range_iterator - < - typename turn_info::container_type const - >::type turn_operation_iterator_type; - typedef following::action_selector action; public: @@ -356,7 +353,12 @@ public: { BOOST_ASSERT( boost::size(turns) == boost::size(reverse_turns) ); - typedef typename boost::range_iterator::type TurnIt; + typedef typename boost::range_iterator::type TurnIterator; + typedef typename boost::range_value::type TurnInfo; + typedef typename boost::range_iterator + < + typename TurnInfo::container_type const + >::type TurnOperationIterator; // Iterate through all intersection points (they are // ordered along the each line) @@ -368,20 +370,20 @@ public: bool first = true; std::size_t enter_count = 0; - TurnIt it = boost::begin(turns); - TurnIt it_r = boost::begin(reverse_turns); + TurnIterator it = boost::begin(turns); + TurnIterator it_r = boost::begin(reverse_turns); for (; it != boost::end(turns); ++it, ++it_r) { - turn_operation_iterator_type iit = boost::begin(it->operations); - turn_operation_iterator_type iit_r = boost::begin(it_r->operations); - ++iit_r; + TurnOperationIterator op_it = boost::begin(it->operations); + TurnOperationIterator op_it_r = boost::begin(it_r->operations); + ++op_it_r; - LineString2 const* ls2 = - &*(boost::begin(multilinestring) + iit->other_id.multi_index); + LineString2 const* linestring2 = + &*(boost::begin(multilinestring) + op_it->other_id.multi_index); - oit = Base::process_turn(it, it_r, iit, iit_r, + oit = Base::process_turn(it, it_r, op_it, op_it_r, first, entered, enter_count, - linestring, *ls2, + linestring, *linestring2, current_piece, current_segment_id, oit); } @@ -425,14 +427,6 @@ protected: OverlayType, FollowIsolatedPoints > Base; - typedef typename point_type::type PointOut; - typedef traversal_turn_info turn_info; - - typedef typename boost::range_iterator - < - typename turn_info::container_type const - >::type turn_operation_iterator_type; - typedef following::action_selector action; public: @@ -445,7 +439,12 @@ public: { BOOST_ASSERT( boost::size(turns) == boost::size(reverse_turns) ); - typedef typename boost::range_iterator::type TurnIt; + typedef typename boost::range_iterator::type TurnIterator; + typedef typename boost::range_value::type TurnInfo; + typedef typename boost::range_iterator + < + typename TurnInfo::container_type const + >::type TurnOperationIterator; // Iterate through all intersection points (they are // ordered along the each line) @@ -460,17 +459,17 @@ public: std::size_t enter_count = 0; // dummy initialization - LineString1 const* ls1 = &*boost::begin(multilinestring); + LineString1 const* linestring1 = &*boost::begin(multilinestring); - TurnIt it = boost::begin(turns); - TurnIt it_r = boost::begin(reverse_turns); + TurnIterator it = boost::begin(turns); + TurnIterator it_r = boost::begin(reverse_turns); for (; it != boost::end(turns); ++it, ++it_r) { - turn_operation_iterator_type iit = boost::begin(it->operations); - turn_operation_iterator_type iit_r = boost::begin(it_r->operations); - ++iit_r; + TurnOperationIterator op_it = boost::begin(it->operations); + TurnOperationIterator op_it_r = boost::begin(it_r->operations); + ++op_it_r; - if ( iit->seg_id.multi_index != current_multi_id ) + if ( op_it->seg_id.multi_index != current_multi_id ) { if ( first_turn ) { @@ -478,7 +477,7 @@ public: } else { - oit = Base::process_end(entered, *ls1, + oit = Base::process_end(entered, *linestring1, current_segment_id, current_piece, oit); @@ -490,20 +489,21 @@ public: = geometry::segment_identifier(0, -1, -1, -1); geometry::clear(current_piece); } - current_multi_id = iit->seg_id.multi_index; - ls1 = &*(boost::begin(multilinestring) + current_multi_id); + current_multi_id = op_it->seg_id.multi_index; + linestring1 = + &*(boost::begin(multilinestring) + current_multi_id); } - oit = Base::process_turn(it, it_r, iit, iit_r, + oit = Base::process_turn(it, it_r, op_it, op_it_r, first, entered, enter_count, - *ls1, linestring, + *linestring1, linestring, current_piece, current_segment_id, oit); } BOOST_ASSERT( enter_count == 0 ); - return Base::process_end(entered, *ls1, + return Base::process_end(entered, *linestring1, current_segment_id, current_piece, oit); } @@ -539,14 +539,6 @@ protected: OverlayType, FollowIsolatedPoints > Base; - typedef typename point_type::type PointOut; - typedef traversal_turn_info turn_info; - - typedef typename boost::range_iterator - < - typename turn_info::container_type const - >::type turn_operation_iterator_type; - typedef following::action_selector action; public: @@ -559,7 +551,12 @@ public: { BOOST_ASSERT( boost::size(turns) == boost::size(reverse_turns) ); - typedef typename boost::range_iterator::type TurnIt; + typedef typename boost::range_iterator::type TurnIterator; + typedef typename boost::range_value::type TurnInfo; + typedef typename boost::range_iterator + < + typename TurnInfo::container_type const + >::type TurnOperationIterator; // Iterate through all intersection points (they are // ordered along the each line) @@ -574,17 +571,17 @@ public: std::size_t enter_count = 0; // dummy initialization - LineString1 const* ls1 = &*boost::begin(multilinestring1); + LineString1 const* linestring1 = &*boost::begin(multilinestring1); - TurnIt it = boost::begin(turns); - TurnIt it_r = boost::begin(reverse_turns); + TurnIterator it = boost::begin(turns); + TurnIterator it_r = boost::begin(reverse_turns); for (; it != boost::end(turns); ++it, ++it_r) { - turn_operation_iterator_type iit = boost::begin(it->operations); - turn_operation_iterator_type iit_r = boost::begin(it_r->operations); - ++iit_r; + TurnOperationIterator op_it = boost::begin(it->operations); + TurnOperationIterator op_it_r = boost::begin(it_r->operations); + ++op_it_r; - if ( iit->seg_id.multi_index != current_multi_id ) + if ( op_it->seg_id.multi_index != current_multi_id ) { if ( first_turn ) { @@ -592,7 +589,7 @@ public: } else { - oit = Base::process_end(entered, *ls1, + oit = Base::process_end(entered, *linestring1, current_segment_id, current_piece, oit); @@ -604,23 +601,24 @@ public: = geometry::segment_identifier(0, -1, -1, -1); geometry::clear(current_piece); } - current_multi_id = iit->seg_id.multi_index; - ls1 = &*(boost::begin(multilinestring1) + current_multi_id); + current_multi_id = op_it->seg_id.multi_index; + linestring1 = + &*(boost::begin(multilinestring1) + current_multi_id); } - LineString2 const* ls2 = - &*(boost::begin(multilinestring2) + iit->other_id.multi_index); + LineString2 const* linestring2 = + &*(boost::begin(multilinestring2) + op_it->other_id.multi_index); - oit = Base::process_turn(it, it_r, iit, iit_r, + oit = Base::process_turn(it, it_r, op_it, op_it_r, first, entered, enter_count, - *ls1, *ls2, + *linestring1, *linestring2, current_piece, current_segment_id, oit); } BOOST_ASSERT( enter_count == 0 ); - return Base::process_end(entered, *ls1, + return Base::process_end(entered, *linestring1, current_segment_id, current_piece, oit); } @@ -636,8 +634,8 @@ template overlay_type OverlayType, bool FollowIsolatedPoints, typename TagOut = typename tag::type, - typename Tag1 = typename tag::type, - typename Tag2 = typename tag::type + typename TagIn1 = typename tag::type, + typename TagIn2 = typename tag::type > struct follow_dispatch : not_implemented 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 8b63fde9a..bbadaa8de 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 @@ -523,8 +523,8 @@ struct get_turn_info_for_endpoint tp.method = method; tp.operations[0].operation = op0; tp.operations[1].operation = op1; - tp.operations[0].position = pos0; - tp.operations[1].position = pos1; + // tp.operations[0].position = pos0; + // tp.operations[1].position = pos1; AssignPolicy::apply(tp, pi, qi, result.template get<0>(), result.template get<1>()); *out++ = tp; } diff --git a/include/boost/geometry/algorithms/detail/overlay/intersection_insert.hpp b/include/boost/geometry/algorithms/detail/overlay/intersection_insert.hpp index 3db6d6a72..9b3bbebdb 100644 --- a/include/boost/geometry/algorithms/detail/overlay/intersection_insert.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/intersection_insert.hpp @@ -513,12 +513,38 @@ struct intersection_insert_reversed }; +// dispatch for non-linear geometries +template +< + typename Geometry1, typename Geometry2, typename GeometryOut, + overlay_type OverlayType, + bool Reverse1, bool Reverse2, bool ReverseOut, + typename TagIn1, typename TagIn2, typename TagOut +> +struct intersection_insert + < + Geometry1, Geometry2, GeometryOut, + OverlayType, + Reverse1, Reverse2, ReverseOut, + TagIn1, TagIn2, TagOut, + false, false, false + > : intersection_insert + < + Geometry1, Geometry2, GeometryOut, + OverlayType, + Reverse1, Reverse2, ReverseOut, + typename tag_cast::type, + typename tag_cast::type, + TagOut, + false, false, false + > +{}; + // dispatch for difference of linear geometries template < - typename Linear1, typename Linear2, - typename LineStringOut, + typename Linear1, typename Linear2, typename LineStringOut, bool Reverse1, bool Reverse2, bool ReverseOut > struct intersection_insert @@ -526,9 +552,7 @@ struct intersection_insert Linear1, Linear2, LineStringOut, overlay_difference, Reverse1, Reverse2, ReverseOut, - typename geometry::tag::type, - typename geometry::tag::type, - linestring_tag, + linear_tag, linear_tag, linestring_tag, false, false, false > : detail::overlay::linear_linear_linestring < @@ -536,11 +560,12 @@ struct intersection_insert > {}; + + // dispatch for intersection of linear geometries template < - typename Linear1, typename Linear2, - typename LineStringOut, + typename Linear1, typename Linear2, typename LineStringOut, bool Reverse1, bool Reverse2, bool ReverseOut > struct intersection_insert @@ -548,9 +573,7 @@ struct intersection_insert Linear1, Linear2, LineStringOut, overlay_intersection, Reverse1, Reverse2, ReverseOut, - typename geometry::tag::type, - typename geometry::tag::type, - linestring_tag, + linear_tag, linear_tag, linestring_tag, false, false, false > : detail::overlay::linear_linear_linestring < @@ -559,9 +582,6 @@ struct intersection_insert {}; - - - } // namespace dispatch #endif // DOXYGEN_NO_DISPATCH diff --git a/include/boost/geometry/algorithms/detail/overlay/linear_linear.hpp b/include/boost/geometry/algorithms/detail/overlay/linear_linear.hpp index f13ed9c43..36f1dbfed 100644 --- a/include/boost/geometry/algorithms/detail/overlay/linear_linear.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/linear_linear.hpp @@ -13,6 +13,7 @@ #include +#include #include #include @@ -30,37 +31,6 @@ namespace detail { namespace overlay { -namespace core -{ - -template -struct is_linear : not_implemented -{}; - -template <> -struct is_linear -{}; - -template <> -struct is_linear -{}; - - -template -struct are_linear - : is_linear, is_linear -{}; - -template -struct are_linear - : is_linear -{}; - - -} // namespace core - - - //=========================================================================== //=========================================================================== //=========================================================================== @@ -151,19 +121,8 @@ template overlay_type OverlayType > class linear_linear_linestring - : core::are_linear - < - typename tag::type, typename tag::type - > { protected: - typedef typename point_type::type PointOut; - typedef traversal_turn_info turn_info; - typedef std::vector Turns; - typedef typename Turns::iterator TurnIt; - typedef detail::get_turns::no_interrupt_policy InterruptPolicy; - - struct AssignPolicy { static bool const include_no_turn = false; @@ -186,25 +145,28 @@ protected: }; - struct IsContinueTurn + class IsContinueTurn { + private: + template + inline bool is_continue_or_opposite(Operation const& operation) const + { + return operation == operation_continue + || operation == operation_opposite; + } + + public: template bool operator()(Turn const& turn) const { - if ( turn.method != method_collinear && - turn.method != method_equal ) + if ( turn.method != method_collinear + && turn.method != method_equal ) { return false; } - operation_type op[2]; - op[0] = turn.operations[0].operation; - op[1] = turn.operations[1].operation; - return - (op[0] == operation_continue || - op[0] == operation_opposite) && - (op[1] == operation_continue || - op[1] == operation_opposite); + return is_continue_or_opposite(turn.operations[0].operation) + && is_continue_or_opposite(turn.operations[1].operation); } }; @@ -319,13 +281,11 @@ protected: filter_turns(reverse_turns); // sort by seg_id, distance, and operation - typedef detail::turns::less_seg_dist_other_op<> less; - std::sort(boost::begin(turns), boost::end(turns), less()); + std::sort(boost::begin(turns), boost::end(turns), + detail::turns::less_seg_dist_other_op<>()); - typedef - detail::turns::less_seg_dist_other_op > rev_less; std::sort(boost::begin(reverse_turns), boost::end(reverse_turns), - rev_less()); + detail::turns::less_seg_dist_other_op >()); #ifndef BOOST_GEOMETRY_DIFFERENCE_DO_NOT_REMOVE_DUPLICATE_TURNS // remove duplicate turns @@ -357,32 +317,12 @@ public: OutputIterator oit, Strategy const& ) { - typedef geometry::model::multi_linestring + typedef traversal_turn_info < - LinestringOut - > MultiLinestringOut; + typename point_type::type + > turn_info; - // MultiLinestringOut mls1, mls2; - // geometry::convert(multilinestring1, mls1); - // geometry::convert(multilinestring2, mls2); - - // assert( boost::size(mls1) > 0 ); - // assert( boost::size(mls2) > 0 ); - - - // canonical::apply(ls1); - // canonical::apply(ls2); - - // typedef typename point_type::type PointOut; - -#if 0 - typedef //overlay::assign_null_policy - overlay::calculate_distance_policy AssignPolicy; -#endif - // typedef //overlay::assign_null_policy - // detail::union_::assign_union_policy AssignPolicy; - - // typedef detail::disjoint::disjoint_interrupt_policy InterruptPolicy; + typedef std::vector Turns; Turns turns; compute_turns(turns, linear1, linear2); @@ -425,20 +365,7 @@ template typename LinestringOut > struct linear_linear_linestring - : linear_linear_linestring - < - Linear1, Linear2, LinestringOut, overlay_difference - > { -protected: - typedef linear_linear_linestring - < - Linear1, Linear2, LinestringOut, overlay_difference - > Base; - - typedef typename Base::Turns Turns; - -public: template < typename OutputIterator, typename Strategy diff --git a/include/boost/geometry/algorithms/detail/turns/compare_turns.hpp b/include/boost/geometry/algorithms/detail/turns/compare_turns.hpp index a0c4c1c01..9d2f6f2cd 100644 --- a/include/boost/geometry/algorithms/detail/turns/compare_turns.hpp +++ b/include/boost/geometry/algorithms/detail/turns/compare_turns.hpp @@ -36,10 +36,10 @@ struct less_seg_dist_other_op { BOOST_STATIC_ASSERT(OpId < 2); - template static inline - int order_op(Op const& op) + template + static inline int order_op(Op const& op) { - switch(op.operation) + switch (op.operation) { case detail::overlay::operation_none : return N; case detail::overlay::operation_union : return U; @@ -51,14 +51,14 @@ struct less_seg_dist_other_op return -1; } - template static inline - bool use_operation(Op const& left, Op const& right) + template + static inline bool use_operation(Op const& left, Op const& right) { return order_op(left) < order_op(right); } - template static inline - bool use_other_multi_ring_id(Op const& left, Op const& right) + template + static inline bool use_other_id(Op const& left, Op const& right) { if ( left.other_id.multi_index != right.other_id.multi_index ) { @@ -76,13 +76,14 @@ struct less_seg_dist_other_op return use_operation(left, right); } - template static inline - bool use_distance(Op const& left, Op const& right) + template + static inline bool use_distance(Op const& left, Op const& right) { - return left.enriched.distance < right.enriched.distance || ( - geometry::math::equals(left.enriched.distance, right.enriched.distance) && - use_other_multi_ring_id(left, right) - ); + return left.enriched.distance < right.enriched.distance + || ( geometry::math::equals(left.enriched.distance, + right.enriched.distance) + && use_other_id(left, right) + ); } template diff --git a/include/boost/geometry/algorithms/union.hpp b/include/boost/geometry/algorithms/union.hpp index ef8b4c5be..6421eebe5 100644 --- a/include/boost/geometry/algorithms/union.hpp +++ b/include/boost/geometry/algorithms/union.hpp @@ -22,7 +22,7 @@ #include #include #include -#include \ +#include #include @@ -100,17 +100,43 @@ struct union_insert {}; +// dispatch for union of non-areal geometries +template +< + typename Geometry1, typename Geometry2, typename GeometryOut, + typename TagIn1, typename TagIn2, typename TagOut, + bool Reverse1, bool Reverse2, bool ReverseOut +> +struct union_insert + < + Geometry1, Geometry2, GeometryOut, + TagIn1, TagIn2, TagOut, + false, false, false, + Reverse1, Reverse2, ReverseOut, + false + > : union_insert + < + Geometry1, Geometry2, GeometryOut, + typename tag_cast::type, + typename tag_cast::type, + TagOut, + false, false, false, + Reverse1, Reverse2, ReverseOut, + false + > +{}; + + // dispatch for union of linear geometries template < typename Linear1, typename Linear2, typename LineStringOut, - typename TagIn1, typename TagIn2, bool Reverse1, bool Reverse2, bool ReverseOut > struct union_insert < Linear1, Linear2, LineStringOut, - TagIn1, TagIn2, linestring_tag, + linear_tag, linear_tag, linestring_tag, false, false, false, Reverse1, Reverse2, ReverseOut, false @@ -121,6 +147,23 @@ struct union_insert {}; +// dispatch for point-like geometries +template +< + typename PointLike1, typename PointLike2, typename PointOut, + bool Reverse1, bool Reverse2, bool ReverseOut +> +struct union_insert + < + PointLike1, PointLike2, PointOut, + pointlike_tag, pointlike_tag, point_tag, + false, false, false, + Reverse1, Reverse2, ReverseOut, + false + > : not_implemented +{}; + + } // namespace dispatch #endif // DOXYGEN_NO_DISPATCH