summaryrefslogtreecommitdiff
path: root/boost/geometry/algorithms/detail/overlay/linear_linear.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/geometry/algorithms/detail/overlay/linear_linear.hpp')
-rw-r--r--boost/geometry/algorithms/detail/overlay/linear_linear.hpp326
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