diff options
Diffstat (limited to 'boost/geometry/algorithms/detail/overlay/linear_linear.hpp')
-rw-r--r-- | boost/geometry/algorithms/detail/overlay/linear_linear.hpp | 326 |
1 files changed, 326 insertions, 0 deletions
diff --git a/boost/geometry/algorithms/detail/overlay/linear_linear.hpp b/boost/geometry/algorithms/detail/overlay/linear_linear.hpp new file mode 100644 index 0000000000..3a7a7a7f3e --- /dev/null +++ b/boost/geometry/algorithms/detail/overlay/linear_linear.hpp @@ -0,0 +1,326 @@ +// 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 <algorithm> +#include <vector> + +#include <boost/range.hpp> + +#include <boost/geometry/core/tag.hpp> +#include <boost/geometry/core/tags.hpp> + +#include <boost/geometry/algorithms/detail/relate/turns.hpp> + +#include <boost/geometry/algorithms/detail/turns/compare_turns.hpp> +#include <boost/geometry/algorithms/detail/turns/filter_continue_turns.hpp> +#include <boost/geometry/algorithms/detail/turns/remove_duplicate_turns.hpp> + +#include <boost/geometry/algorithms/detail/overlay/overlay_type.hpp> +#include <boost/geometry/algorithms/detail/overlay/follow_linear_linear.hpp> + +#include <boost/geometry/algorithms/convert.hpp> + + + +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 <typename LineStringOut, typename LineString> +struct linear_linear_no_intersections + < + LineStringOut, overlay_difference, LineString, linestring_tag + > +{ + template <typename OutputIterator> + static inline OutputIterator apply(LineString const& linestring, + OutputIterator oit) + { + LineStringOut ls_out; + geometry::convert(linestring, ls_out); + *oit++ = ls_out; + return oit; + } +}; + + +template <typename LineStringOut, typename MultiLineString> +struct linear_linear_no_intersections + < + LineStringOut, + overlay_difference, + MultiLineString, + multi_linestring_tag + > +{ + template <typename OutputIterator> + static inline OutputIterator apply(MultiLineString const& multilinestring, + OutputIterator oit) + { + for (typename boost::range_iterator<MultiLineString const>::type + it = boost::begin(multilinestring); + it != boost::end(multilinestring); ++it) + { + LineStringOut ls_out; + geometry::convert(*it, ls_out); + *oit++ = ls_out; + } + return oit; + } +}; + + +template <typename LineStringOut, typename Geometry, typename GeometryTag> +struct linear_linear_no_intersections + < + LineStringOut, overlay_intersection, Geometry, GeometryTag + > +{ + template <typename OutputIterator> + 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<turn_info> 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<Linear1>::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<Linear1>::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 |