diff --git a/include/boost/geometry/algorithms/detail/overlay/linear_linear.hpp b/include/boost/geometry/algorithms/detail/overlay/linear_linear.hpp index 2c6161cd0..16b97cef7 100644 --- a/include/boost/geometry/algorithms/detail/overlay/linear_linear.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/linear_linear.hpp @@ -20,7 +20,14 @@ #include #include -#include +#ifndef BOOST_GEOMETRY_DIFFERENCE_DO_NOT_FILTER_CONTINUE_TURNS +#include +#endif + +#ifndef BOOST_GEOMETRY_DIFFERENCE_DO_NOT_REMOVE_DUPLICATE_TURNS +#include +#endif + namespace boost { namespace geometry { @@ -118,7 +125,10 @@ template typename Linear1, typename Linear2, typename LinestringOut, - overlay_type OverlayType + overlay_type OverlayType, + bool EnableFilterContinueTurns = true, + bool EnableRemoveDuplicateTurns = true, + bool EnableDegenerateTurns = true > class linear_linear_linestring { @@ -126,7 +136,11 @@ protected: struct AssignPolicy { static bool const include_no_turn = false; - static bool const include_degenerate = false; +#ifdef BOOST_GEOMETRY_DIFFERENCE_INCLUDE_DEGENERATE_TURNS + static bool const include_degenerate = true; +#else + static bool const include_degenerate = EnableDegenerateTurns; +#endif static bool const include_opposite = false; template @@ -145,68 +159,6 @@ protected: }; - 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 ) - { - return false; - } - - return is_continue_or_opposite(turn.operations[0].operation) - && is_continue_or_opposite(turn.operations[1].operation); - } - }; - - -#ifndef BOOST_GEOMETRY_DIFFERENCE_DO_NOT_REMOVE_DUPLICATE_TURNS - struct TurnEqualsTo - { - template - bool operator()(Turn const& t1, Turn const& t2) const - { - return geometry::equals(t1.point, t2.point) - && t1.operations[0].seg_id == t2.operations[0].seg_id - && t1.operations[0].other_id == t2.operations[0].other_id; - } - }; -#endif - - - template - static inline void filter_turns(Turns& turns) - { - turns.erase( std::remove_if(turns.begin(), turns.end(), - IsContinueTurn()), - turns.end() - ); - } - - -#ifndef BOOST_GEOMETRY_DIFFERENCE_DO_NOT_REMOVE_DUPLICATE_TURNS - template - static inline void remove_duplicates(Turns& turns) - { - turns.erase( std::unique(turns.begin(), turns.end(), - TurnEqualsTo()), - turns.end() - ); - } -#endif - - template < typename Turns, @@ -274,9 +226,17 @@ protected: LinearGeometry2 const& linear2, OutputIterator oit) { +#ifndef BOOST_GEOMETRY_DIFFERENCE_DO_NOT_FILTER_CONTINUE_TURNS // remove turns that have no added value - filter_turns(turns); - filter_turns(reverse_turns); + turns::filter_continue_turns + < + Turns, EnableFilterContinueTurns + >::apply(turns); + turns::filter_continue_turns + < + Turns, EnableFilterContinueTurns + >::apply(reverse_turns); +#endif // sort by seg_id, distance, and operation std::sort(boost::begin(turns), boost::end(turns), @@ -287,8 +247,14 @@ protected: #ifndef BOOST_GEOMETRY_DIFFERENCE_DO_NOT_REMOVE_DUPLICATE_TURNS // remove duplicate turns - remove_duplicates(turns); - remove_duplicates(reverse_turns); + turns::remove_duplicate_turns + < + Turns, EnableRemoveDuplicateTurns + >::apply(turns); + turns::remove_duplicate_turns + < + Turns, EnableRemoveDuplicateTurns + >::apply(reverse_turns); #endif #ifdef GEOMETRY_TEST_DEBUG diff --git a/include/boost/geometry/algorithms/detail/turns/filter_continue_turns.hpp b/include/boost/geometry/algorithms/detail/turns/filter_continue_turns.hpp new file mode 100644 index 000000000..4f38e3e73 --- /dev/null +++ b/include/boost/geometry/algorithms/detail/turns/filter_continue_turns.hpp @@ -0,0 +1,78 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2014, Oracle and/or its affiliates. + +// Licensed under the Boost Software License version 1.0. +// http://www.boost.org/users/license.html + +// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle + + +#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_TURNS_FILTER_CONTINUE_TURNS_HPP +#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_TURNS_FILTER_CONTINUE_TURNS_HPP + +#include +#include + +namespace boost { namespace geometry +{ + +namespace detail { namespace turns +{ + + +template +struct filter_continue_turns +{ + static inline void apply(Turns& turns) {} +}; + + +template +class filter_continue_turns +{ +private: + class IsContinueTurn + { + private: + template + inline bool is_continue_or_opposite(Operation const& operation) const + { + return operation == detail::overlay::operation_continue + || operation == detail::overlay::operation_opposite; + } + + public: + template + bool operator()(Turn const& turn) const + { + if ( turn.method != detail::overlay::method_collinear + && turn.method != detail::overlay::method_equal ) + { + return false; + } + + return is_continue_or_opposite(turn.operations[0].operation) + && is_continue_or_opposite(turn.operations[1].operation); + } + }; + + +public: + static inline void apply(Turns& turns) + { + turns.erase( std::remove_if(turns.begin(), turns.end(), + IsContinueTurn()), + turns.end() + ); + } +}; + + +}} // namespace detail::turns + +}} // namespect boost::geometry + + + +#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_TURNS_FILTER_CONTINUE_TURNS_HPP diff --git a/include/boost/geometry/algorithms/detail/turns/remove_duplicate_turns.hpp b/include/boost/geometry/algorithms/detail/turns/remove_duplicate_turns.hpp new file mode 100644 index 000000000..41f52c059 --- /dev/null +++ b/include/boost/geometry/algorithms/detail/turns/remove_duplicate_turns.hpp @@ -0,0 +1,62 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2014, Oracle and/or its affiliates. + +// Licensed under the Boost Software License version 1.0. +// http://www.boost.org/users/license.html + +// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle + + +#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_TURNS_REMOVE_DUPLICATE_TURNS_HPP +#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_TURNS_REMOVE_DUPLICATE_TURNS_HPP + +#include +#include + +namespace boost { namespace geometry +{ + +namespace detail { namespace turns +{ + +template +struct remove_duplicate_turns +{ + static inline void apply(Turns& turns) {} +}; + + + +template +class remove_duplicate_turns +{ +private: + struct TurnEqualsTo + { + template + bool operator()(Turn const& t1, Turn const& t2) const + { + return geometry::equals(t1.point, t2.point) + && t1.operations[0].seg_id == t2.operations[0].seg_id + && t1.operations[0].other_id == t2.operations[0].other_id; + } + }; + +public: + static inline void apply(Turns& turns) + { + turns.erase( std::unique(turns.begin(), turns.end(), + TurnEqualsTo()), + turns.end() + ); + } +}; + + + +}} // namespace detail::turns + +}} // namespect boost::geometry + +#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_TURNS_REMOVE_DUPLICATE_TURNS_HPP