// 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_OVERLAY_LINEAR_LINEAR_HPP #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_LINEAR_LINEAR_HPP #include #include #include #include #include #include #include #include #include #include #include #include namespace boost { namespace geometry { #ifndef DOXYGEN_NO_DETAIL namespace detail { namespace overlay { template < typename LineStringOut, overlay_type OverlayType, typename Geometry, typename GeometryTag > struct linear_linear_no_intersections; template struct linear_linear_no_intersections < LineStringOut, overlay_difference, LineString, linestring_tag > { template static inline OutputIterator apply(LineString const& linestring, OutputIterator oit) { LineStringOut ls_out; geometry::convert(linestring, ls_out); *oit++ = ls_out; return oit; } }; template struct linear_linear_no_intersections < LineStringOut, overlay_difference, MultiLineString, multi_linestring_tag > { template static inline OutputIterator apply(MultiLineString const& multilinestring, OutputIterator oit) { for (typename boost::range_iterator::type it = boost::begin(multilinestring); it != boost::end(multilinestring); ++it) { LineStringOut ls_out; geometry::convert(*it, ls_out); *oit++ = ls_out; } return oit; } }; template struct linear_linear_no_intersections < LineStringOut, overlay_intersection, Geometry, GeometryTag > { template static inline OutputIterator apply(Geometry const&, OutputIterator oit) { return oit; } }; template < typename Linear1, typename Linear2, typename LinestringOut, overlay_type OverlayType, bool EnableFilterContinueTurns = false, bool EnableRemoveDuplicateTurns = false, bool EnableDegenerateTurns = true, #ifdef BOOST_GEOMETRY_INTERSECTION_DO_NOT_INCLUDE_ISOLATED_POINTS bool EnableFollowIsolatedPoints = false #else bool EnableFollowIsolatedPoints = true #endif > class linear_linear_linestring { protected: struct assign_policy { static bool const include_no_turn = false; static bool const include_degenerate = EnableDegenerateTurns; static bool const include_opposite = false; template < typename Info, typename Point1, typename Point2, typename IntersectionInfo, typename DirInfo > static inline void apply(Info& , Point1 const& , Point2 const& , IntersectionInfo const& , DirInfo const& ) { } }; template < typename Turns, typename LinearGeometry1, typename LinearGeometry2 > static inline void compute_turns(Turns& turns, LinearGeometry1 const& linear1, LinearGeometry2 const& linear2) { turns.clear(); geometry::detail::relate::turns::get_turns < LinearGeometry1, LinearGeometry2, detail::get_turns::get_turn_info_type < LinearGeometry1, LinearGeometry2, assign_policy > >::apply(turns, linear1, linear2); } template < overlay_type OverlayTypeForFollow, bool FollowIsolatedPoints, typename Turns, typename LinearGeometry1, typename LinearGeometry2, typename OutputIterator > static inline OutputIterator sort_and_follow_turns(Turns& turns, LinearGeometry1 const& linear1, LinearGeometry2 const& linear2, OutputIterator oit) { // remove turns that have no added value turns::filter_continue_turns < Turns, EnableFilterContinueTurns && OverlayType != overlay_intersection >::apply(turns); // sort by seg_id, distance, and operation std::sort(boost::begin(turns), boost::end(turns), detail::turns::less_seg_fraction_other_op<>()); // remove duplicate turns turns::remove_duplicate_turns < Turns, EnableRemoveDuplicateTurns >::apply(turns); return detail::overlay::following::linear::follow < LinestringOut, LinearGeometry1, LinearGeometry2, OverlayTypeForFollow, FollowIsolatedPoints, !EnableFilterContinueTurns || OverlayType == overlay_intersection >::apply(linear1, linear2, boost::begin(turns), boost::end(turns), oit); } public: template < typename RobustPolicy, typename OutputIterator, typename Strategy > static inline OutputIterator apply(Linear1 const& linear1, Linear2 const& linear2, RobustPolicy const&, OutputIterator oit, Strategy const& ) { typedef typename detail::relate::turns::get_turns < Linear1, Linear2 >::turn_info turn_info; typedef std::vector turns_container; turns_container turns; compute_turns(turns, linear1, linear2); if ( turns.empty() ) { // the two linear geometries are disjoint return linear_linear_no_intersections < LinestringOut, OverlayType, Linear1, typename tag::type >::apply(linear1, oit); } return sort_and_follow_turns < OverlayType, EnableFollowIsolatedPoints && OverlayType == overlay_intersection >(turns, linear1, linear2, oit); } }; template < typename Linear1, typename Linear2, typename LinestringOut, bool EnableFilterContinueTurns, bool EnableRemoveDuplicateTurns, bool EnableDegenerateTurns, bool EnableFollowIsolatedPoints > struct linear_linear_linestring < Linear1, Linear2, LinestringOut, overlay_union, EnableFilterContinueTurns, EnableRemoveDuplicateTurns, EnableDegenerateTurns, EnableFollowIsolatedPoints > { template < typename RobustPolicy, typename OutputIterator, typename Strategy > static inline OutputIterator apply(Linear1 const& linear1, Linear2 const& linear2, RobustPolicy const& robust_policy, OutputIterator oit, Strategy const& strategy) { oit = linear_linear_no_intersections < LinestringOut, overlay_difference, Linear1, typename tag::type >::apply(linear1, oit); return linear_linear_linestring < Linear2, Linear1, LinestringOut, overlay_difference, EnableFilterContinueTurns, EnableRemoveDuplicateTurns, EnableDegenerateTurns, EnableFollowIsolatedPoints >::apply(linear2, linear1, robust_policy, oit, strategy); } }; }} // namespace detail::overlay #endif // DOXYGEN_NO_DETAIL }} // namespace boost::geometry #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_LINEAR_LINEAR_HPP