123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328 |
- // Boost.Geometry (aka GGL, Generic Geometry Library)
- // Copyright (c) 2014-2022, Oracle and/or its affiliates.
- // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
- // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
- // Licensed under the Boost Software License version 1.0.
- // http://www.boost.org/users/license.html
- #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/begin.hpp>
- #include <boost/range/end.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>
- #include <boost/geometry/geometries/helper_geometry.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 (auto 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;
- static bool const include_start_turn = false;
- };
- template
- <
- typename Turns,
- typename LinearGeometry1,
- typename LinearGeometry2,
- typename Strategy,
- typename RobustPolicy
- >
- static inline void compute_turns(Turns& turns,
- LinearGeometry1 const& linear1,
- LinearGeometry2 const& linear2,
- Strategy const& strategy,
- RobustPolicy const& robust_policy)
- {
- turns.clear();
- detail::get_turns::no_interrupt_policy interrupt_policy;
- geometry::detail::relate::turns::get_turns
- <
- LinearGeometry1,
- LinearGeometry2,
- detail::get_turns::get_turn_info_type
- <
- LinearGeometry1,
- LinearGeometry2,
- assign_policy
- >
- >::apply(turns, linear1, linear2, interrupt_policy, strategy, robust_policy);
- }
- template
- <
- overlay_type OverlayTypeForFollow,
- bool FollowIsolatedPoints,
- typename Turns,
- typename LinearGeometry1,
- typename LinearGeometry2,
- typename OutputIterator,
- typename Strategy
- >
- static inline OutputIterator
- sort_and_follow_turns(Turns& turns,
- LinearGeometry1 const& linear1,
- LinearGeometry2 const& linear2,
- OutputIterator oit,
- Strategy const& strategy)
- {
- // 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, strategy);
- 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, strategy);
- }
- public:
- 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)
- {
- typedef typename detail::relate::turns::get_turns
- <
- Linear1,
- Linear2,
- detail::get_turns::get_turn_info_type
- <
- Linear1,
- Linear2,
- assign_policy
- >
- >::template turn_info_type<Strategy, RobustPolicy>::type turn_info;
- typedef std::vector<turn_info> turns_container;
- turns_container turns;
- compute_turns(turns, linear1, linear2, strategy, robust_policy);
- 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, strategy);
- }
- };
- 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
|