1 // Boost.Geometry (aka GGL, Generic Geometry Library)
3 // Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
5 // This file was modified by Oracle on 2014, 2015, 2017, 2019.
6 // Modifications copyright (c) 2014-2019 Oracle and/or its affiliates.
8 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
9 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
11 // Use, modification and distribution is subject to the Boost Software License,
12 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
13 // http://www.boost.org/LICENSE_1_0.txt)
15 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_INTERSECTION_INSERT_HPP
16 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_INTERSECTION_INSERT_HPP
21 #include <boost/mpl/if.hpp>
22 #include <boost/mpl/assert.hpp>
23 #include <boost/range/metafunctions.hpp>
26 #include <boost/geometry/core/is_areal.hpp>
27 #include <boost/geometry/core/point_order.hpp>
28 #include <boost/geometry/core/reverse_dispatch.hpp>
29 #include <boost/geometry/geometries/concepts/check.hpp>
30 #include <boost/geometry/algorithms/convert.hpp>
31 #include <boost/geometry/algorithms/detail/point_on_border.hpp>
32 #include <boost/geometry/algorithms/detail/overlay/clip_linestring.hpp>
33 #include <boost/geometry/algorithms/detail/overlay/follow.hpp>
34 #include <boost/geometry/algorithms/detail/overlay/get_intersection_points.hpp>
35 #include <boost/geometry/algorithms/detail/overlay/overlay.hpp>
36 #include <boost/geometry/algorithms/detail/overlay/overlay_type.hpp>
37 #include <boost/geometry/algorithms/detail/overlay/range_in_geometry.hpp>
38 #include <boost/geometry/algorithms/detail/overlay/segment_as_subrange.hpp>
40 #include <boost/geometry/policies/robustness/rescale_policy_tags.hpp>
41 #include <boost/geometry/policies/robustness/segment_ratio_type.hpp>
42 #include <boost/geometry/policies/robustness/get_rescale_policy.hpp>
44 #include <boost/geometry/views/segment_view.hpp>
45 #include <boost/geometry/views/detail/boundary_view.hpp>
47 #include <boost/geometry/algorithms/detail/check_iterator_range.hpp>
48 #include <boost/geometry/algorithms/detail/overlay/linear_linear.hpp>
49 #include <boost/geometry/algorithms/detail/overlay/pointlike_pointlike.hpp>
50 #include <boost/geometry/algorithms/detail/overlay/pointlike_linear.hpp>
52 #if defined(BOOST_GEOMETRY_DEBUG_FOLLOW)
53 #include <boost/geometry/algorithms/detail/overlay/debug_turn_info.hpp>
54 #include <boost/geometry/io/wkt/wkt.hpp>
57 namespace boost { namespace geometry
60 #ifndef DOXYGEN_NO_DETAIL
61 namespace detail { namespace intersection
64 template <typename PointOut>
65 struct intersection_segment_segment_point
69 typename Segment1, typename Segment2,
70 typename RobustPolicy,
71 typename OutputIterator, typename Strategy
73 static inline OutputIterator apply(Segment1 const& segment1,
74 Segment2 const& segment2,
77 Strategy const& strategy)
79 // Make sure this is only called with no rescaling
80 BOOST_STATIC_ASSERT((boost::is_same
82 no_rescale_policy_tag,
83 typename rescale_policy_type<RobustPolicy>::type
86 typedef typename point_type<PointOut>::type point_type;
88 // Get the intersection point (or two points)
89 typedef segment_intersection_points<point_type> intersection_return_type;
91 typedef policies::relate::segments_intersection_points
93 intersection_return_type
96 detail::segment_as_subrange<Segment1> sub_range1(segment1);
97 detail::segment_as_subrange<Segment2> sub_range2(segment2);
99 intersection_return_type
100 is = strategy.apply(sub_range1, sub_range2, policy_type());
102 for (std::size_t i = 0; i < is.count; i++)
105 geometry::convert(is.intersections[i], p);
112 template <typename PointOut>
113 struct intersection_linestring_linestring_point
117 typename Linestring1, typename Linestring2,
118 typename RobustPolicy,
119 typename OutputIterator,
122 static inline OutputIterator apply(Linestring1 const& linestring1,
123 Linestring2 const& linestring2,
124 RobustPolicy const& robust_policy,
126 Strategy const& strategy)
128 // Make sure this is only called with no rescaling
129 BOOST_STATIC_ASSERT((boost::is_same
131 no_rescale_policy_tag,
132 typename rescale_policy_type<RobustPolicy>::type
135 typedef detail::overlay::turn_info<PointOut> turn_info;
136 std::deque<turn_info> turns;
138 geometry::get_intersection_points(linestring1, linestring2,
139 robust_policy, turns, strategy);
141 for (typename boost::range_iterator<std::deque<turn_info> const>::type
142 it = boost::begin(turns); it != boost::end(turns); ++it)
145 geometry::convert(it->point, p);
153 \brief Version of linestring with an areal feature (polygon or multipolygon)
158 typename LineStringOut,
159 overlay_type OverlayType
161 struct intersection_of_linestring_with_areal
163 #if defined(BOOST_GEOMETRY_DEBUG_FOLLOW)
164 template <typename Turn, typename Operation>
165 static inline void debug_follow(Turn const& turn, Operation op,
169 << " at " << op.seg_id
170 << " meth: " << method_char(turn.method)
171 << " op: " << operation_char(op.operation)
172 << " vis: " << visited_char(op.visited)
173 << " of: " << operation_char(turn.operations[0].operation)
174 << operation_char(turn.operations[1].operation)
175 << " " << geometry::wkt(turn.point)
179 template <typename Turn>
180 static inline void debug_turn(Turn const& t, bool non_crossing)
182 std::cout << "checking turn @"
183 << geometry::wkt(t.point)
184 << "; " << method_char(t.method)
185 << ":" << operation_char(t.operations[0].operation)
186 << "/" << operation_char(t.operations[1].operation)
187 << "; non-crossing? "
188 << std::boolalpha << non_crossing << std::noboolalpha
193 #ifdef BOOST_GEOMETRY_SETOPS_LA_OLD_BEHAVIOR
195 class is_crossing_turn
197 // return true is the operation is intersection or blocked
198 template <std::size_t Index, typename Turn>
199 static inline bool has_op_i_or_b(Turn const& t)
202 t.operations[Index].operation == overlay::operation_intersection
204 t.operations[Index].operation == overlay::operation_blocked;
207 template <typename Turn>
208 static inline bool has_method_crosses(Turn const& t)
210 return t.method == overlay::method_crosses;
213 template <typename Turn>
214 static inline bool is_cc(Turn const& t)
217 (t.method == overlay::method_touch_interior
219 t.method == overlay::method_equal
221 t.method == overlay::method_collinear)
223 t.operations[0].operation == t.operations[1].operation
225 t.operations[0].operation == overlay::operation_continue
229 template <typename Turn>
230 static inline bool has_i_or_b_ops(Turn const& t)
233 (t.method == overlay::method_touch
235 t.method == overlay::method_touch_interior
237 t.method == overlay::method_collinear)
239 t.operations[1].operation != t.operations[0].operation
241 (has_op_i_or_b<0>(t) || has_op_i_or_b<1>(t));
245 template <typename Turn>
246 static inline bool apply(Turn const& t)
248 bool const is_crossing
249 = has_method_crosses(t) || is_cc(t) || has_i_or_b_ops(t);
250 #if defined(BOOST_GEOMETRY_DEBUG_FOLLOW)
251 debug_turn(t, ! is_crossing);
257 struct is_non_crossing_turn
259 template <typename Turn>
260 static inline bool apply(Turn const& t)
262 return ! is_crossing_turn::apply(t);
266 template <typename Turns>
267 static inline bool no_crossing_turns_or_empty(Turns const& turns)
269 return detail::check_iterator_range
271 is_non_crossing_turn,
272 true // allow an empty turns range
273 >::apply(boost::begin(turns), boost::end(turns));
276 template <typename Turns>
277 static inline int inside_or_outside_turn(Turns const& turns)
279 using namespace overlay;
280 for (typename Turns::const_iterator it = turns.begin();
281 it != turns.end(); ++it)
283 operation_type op0 = it->operations[0].operation;
284 operation_type op1 = it->operations[1].operation;
285 if (op0 == operation_intersection && op1 == operation_intersection)
289 else if (op0 == operation_union && op1 == operation_union)
291 return -1; // outside
297 #else // BOOST_GEOMETRY_SETOPS_LA_OLD_BEHAVIOR
299 template <typename Linestring, typename Areal, typename Strategy, typename Turns>
300 static inline bool simple_turns_analysis(Linestring const& linestring,
302 Strategy const& strategy,
306 using namespace overlay;
308 bool found_continue = false;
309 bool found_intersection = false;
310 bool found_union = false;
311 bool found_front = false;
313 for (typename Turns::const_iterator it = turns.begin();
314 it != turns.end(); ++it)
316 method_type const method = it->method;
317 operation_type const op = it->operations[0].operation;
319 if (method == method_crosses)
323 else if (op == operation_intersection)
325 found_intersection = true;
327 else if (op == operation_union)
331 else if (op == operation_continue)
333 found_continue = true;
336 if ((found_intersection || found_continue) && found_union)
341 if (it->operations[0].position == position_front)
349 if (found_intersection)
351 inside_value = 1; // inside
353 else if (found_union)
355 inside_value = -1; // outside
357 else // continue and blocked
364 // if needed analyse points of a linestring
365 // NOTE: range_in_geometry checks points of a linestring
366 // until a point inside/outside areal is found
367 // TODO: Could be replaced with point_in_geometry() because found_front is false
368 inside_value = range_in_geometry(linestring, areal, strategy);
370 if ( (found_intersection && inside_value == -1) // going in from outside
371 || (found_continue && inside_value == -1) // going on boundary from outside
372 || (found_union && inside_value == 1) ) // going out from inside
380 #endif // BOOST_GEOMETRY_SETOPS_LA_OLD_BEHAVIOR
384 typename LineString, typename Areal,
385 typename RobustPolicy,
386 typename OutputIterator, typename Strategy
388 static inline OutputIterator apply(LineString const& linestring, Areal const& areal,
389 RobustPolicy const& robust_policy,
391 Strategy const& strategy)
393 // Make sure this is only called with no rescaling
394 BOOST_STATIC_ASSERT((boost::is_same
396 no_rescale_policy_tag,
397 typename rescale_policy_type<RobustPolicy>::type
400 if (boost::size(linestring) == 0)
405 typedef detail::overlay::follow
411 false // do not remove spikes for linear geometries
414 typedef typename point_type<LineStringOut>::type point_type;
416 typedef geometry::segment_ratio
418 typename coordinate_type<point_type>::type
421 #ifdef BOOST_GEOMETRY_SETOPS_LA_OLD_BEHAVIOR
422 typedef detail::overlay::traversal_turn_info
424 point_type, ratio_type
427 typedef detail::overlay::turn_info
431 detail::overlay::turn_operation_linear
438 std::deque<turn_info> turns;
440 detail::get_turns::no_interrupt_policy policy;
442 #ifdef BOOST_GEOMETRY_SETOPS_LA_OLD_BEHAVIOR
447 (OverlayType == overlay_intersection ? ReverseAreal : !ReverseAreal),
448 detail::overlay::assign_null_policy
449 >(linestring, areal, strategy, robust_policy, turns, policy);
451 if (no_crossing_turns_or_empty(turns))
453 // No intersection points, it is either
454 // inside (interior + borders)
455 // or outside (exterior + borders)
458 int inside_value = inside_or_outside_turn(turns);
459 if (inside_value == 0)
461 // if needed analyse points of a linestring
462 // NOTE: range_in_geometry checks points of a linestring
463 // until a point inside/outside areal is found
464 inside_value = overlay::range_in_geometry(linestring, areal, strategy);
466 // add linestring to the output if conditions are met
467 if (inside_value != 0 && follower::included(inside_value))
470 geometry::convert(linestring, copy);
476 #else // BOOST_GEOMETRY_SETOPS_LA_OLD_BEHAVIOR
478 typedef detail::overlay::get_turn_info_linear_areal
480 detail::overlay::assign_null_policy
485 typename geometry::tag<LineString>::type,
486 typename geometry::tag<Areal>::type,
490 (OverlayType == overlay_intersection ? ReverseAreal : !ReverseAreal),
492 >::apply(0, linestring, 1, areal,
493 strategy, robust_policy,
496 int inside_value = 0;
497 if (simple_turns_analysis(linestring, areal, strategy, turns, inside_value))
499 // No crossing the boundary, it is either
500 // inside (interior + borders)
501 // or outside (exterior + borders)
504 // add linestring to the output if conditions are met
505 if (follower::included(inside_value))
508 geometry::convert(linestring, copy);
515 #endif // BOOST_GEOMETRY_SETOPS_LA_OLD_BEHAVIOR
517 #if defined(BOOST_GEOMETRY_DEBUG_FOLLOW)
519 for(typename std::deque<turn_info>::const_iterator
520 it = turns.begin(); it != turns.end(); ++it)
522 debug_follow(*it, it->operations[0], index++);
526 return follower::apply
529 geometry::detail::overlay::operation_intersection,
530 turns, robust_policy, out, strategy
536 template <typename Turns, typename OutputIterator>
537 inline OutputIterator intersection_output_turn_points(Turns const& turns,
540 for (typename Turns::const_iterator
541 it = turns.begin(); it != turns.end(); ++it)
549 template <typename PointOut>
550 struct intersection_areal_areal_point
554 typename Geometry1, typename Geometry2,
555 typename RobustPolicy,
556 typename OutputIterator,
559 static inline OutputIterator apply(Geometry1 const& geometry1,
560 Geometry2 const& geometry2,
561 RobustPolicy const& robust_policy,
563 Strategy const& strategy)
565 typedef detail::overlay::turn_info
568 typename segment_ratio_type<PointOut, RobustPolicy>::type
570 std::vector<turn_info> turns;
572 detail::get_turns::no_interrupt_policy policy;
576 false, false, detail::overlay::assign_null_policy
577 >(geometry1, geometry2, strategy, robust_policy, turns, policy);
579 return intersection_output_turn_points(turns, out);
583 template <typename PointOut>
584 struct intersection_linear_areal_point
588 typename Geometry1, typename Geometry2,
589 typename RobustPolicy,
590 typename OutputIterator,
593 static inline OutputIterator apply(Geometry1 const& geometry1,
594 Geometry2 const& geometry2,
595 RobustPolicy const& robust_policy,
597 Strategy const& strategy)
599 // Make sure this is only called with no rescaling
600 BOOST_STATIC_ASSERT((boost::is_same
602 no_rescale_policy_tag,
603 typename rescale_policy_type<RobustPolicy>::type
606 typedef geometry::segment_ratio<typename geometry::coordinate_type<PointOut>::type> ratio_type;
608 typedef detail::overlay::turn_info
612 detail::overlay::turn_operation_linear
619 typedef detail::overlay::get_turn_info_linear_areal
621 detail::overlay::assign_null_policy
624 std::vector<turn_info> turns;
626 detail::get_turns::no_interrupt_policy interrupt_policy;
630 typename geometry::tag<Geometry1>::type,
631 typename geometry::tag<Geometry2>::type,
637 >::apply(0, geometry1, 1, geometry2,
638 strategy, robust_policy,
639 turns, interrupt_policy);
641 return intersection_output_turn_points(turns, out);
645 template <typename PointOut>
646 struct intersection_areal_linear_point
650 typename Geometry1, typename Geometry2,
651 typename RobustPolicy,
652 typename OutputIterator,
655 static inline OutputIterator apply(Geometry1 const& geometry1,
656 Geometry2 const& geometry2,
657 RobustPolicy const& robust_policy,
659 Strategy const& strategy)
661 return intersection_linear_areal_point
664 >::apply(geometry2, geometry1, robust_policy, out, strategy);
669 }} // namespace detail::intersection
670 #endif // DOXYGEN_NO_DETAIL
674 #ifndef DOXYGEN_NO_DISPATCH
683 typename GeometryOut,
684 overlay_type OverlayType,
686 bool Reverse1 = detail::overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
687 bool Reverse2 = detail::overlay::do_reverse<geometry::point_order<Geometry2>::value>::value,
688 bool ReverseOut = detail::overlay::do_reverse<geometry::point_order<GeometryOut>::value>::value,
690 typename TagIn1 = typename geometry::tag<Geometry1>::type,
691 typename TagIn2 = typename geometry::tag<Geometry2>::type,
692 typename TagOut = typename geometry::tag<GeometryOut>::type,
693 // metafunction finetuning helpers:
694 typename CastedTagIn1 = typename geometry::tag_cast<TagIn1, areal_tag, linear_tag, pointlike_tag>::type,
695 typename CastedTagIn2 = typename geometry::tag_cast<TagIn2, areal_tag, linear_tag, pointlike_tag>::type,
696 typename CastedTagOut = typename geometry::tag_cast<TagOut, areal_tag, linear_tag, pointlike_tag>::type
698 struct intersection_insert
702 false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPES_OR_ORIENTATIONS
703 , (types<Geometry1, Geometry2, GeometryOut>)
710 typename Geometry1, typename Geometry2,
711 typename GeometryOut,
712 overlay_type OverlayType,
713 bool Reverse1, bool Reverse2, bool ReverseOut,
714 typename TagIn1, typename TagIn2, typename TagOut
716 struct intersection_insert
718 Geometry1, Geometry2,
721 Reverse1, Reverse2, ReverseOut,
722 TagIn1, TagIn2, TagOut,
723 areal_tag, areal_tag, areal_tag
724 > : detail::overlay::overlay
725 <Geometry1, Geometry2, Reverse1, Reverse2, ReverseOut, GeometryOut, OverlayType>
729 // Any areal type with box:
732 typename Geometry, typename Box,
733 typename GeometryOut,
734 overlay_type OverlayType,
735 bool Reverse1, bool Reverse2, bool ReverseOut,
736 typename TagIn, typename TagOut
738 struct intersection_insert
743 Reverse1, Reverse2, ReverseOut,
744 TagIn, box_tag, TagOut,
745 areal_tag, areal_tag, areal_tag
746 > : detail::overlay::overlay
747 <Geometry, Box, Reverse1, Reverse2, ReverseOut, GeometryOut, OverlayType>
753 typename Segment1, typename Segment2,
754 typename GeometryOut,
755 overlay_type OverlayType,
756 bool Reverse1, bool Reverse2, bool ReverseOut
758 struct intersection_insert
763 Reverse1, Reverse2, ReverseOut,
764 segment_tag, segment_tag, point_tag,
765 linear_tag, linear_tag, pointlike_tag
766 > : detail::intersection::intersection_segment_segment_point<GeometryOut>
772 typename Linestring1, typename Linestring2,
773 typename GeometryOut,
774 overlay_type OverlayType,
775 bool Reverse1, bool Reverse2, bool ReverseOut
777 struct intersection_insert
779 Linestring1, Linestring2,
782 Reverse1, Reverse2, ReverseOut,
783 linestring_tag, linestring_tag, point_tag,
784 linear_tag, linear_tag, pointlike_tag
785 > : detail::intersection::intersection_linestring_linestring_point<GeometryOut>
791 typename Linestring, typename Box,
792 typename GeometryOut,
793 bool Reverse1, bool Reverse2, bool ReverseOut
795 struct intersection_insert
799 overlay_intersection,
800 Reverse1, Reverse2, ReverseOut,
801 linestring_tag, box_tag, linestring_tag,
802 linear_tag, areal_tag, linear_tag
805 template <typename RobustPolicy, typename OutputIterator, typename Strategy>
806 static inline OutputIterator apply(Linestring const& linestring,
808 RobustPolicy const& robust_policy,
809 OutputIterator out, Strategy const& )
811 typedef typename point_type<GeometryOut>::type point_type;
812 strategy::intersection::liang_barsky<Box, point_type> lb_strategy;
813 return detail::intersection::clip_range_with_box
814 <GeometryOut>(box, linestring, robust_policy, out, lb_strategy);
821 typename Linestring, typename Polygon,
822 typename GeometryOut,
823 overlay_type OverlayType,
824 bool ReverseLinestring, bool ReversePolygon, bool ReverseOut
826 struct intersection_insert
831 ReverseLinestring, ReversePolygon, ReverseOut,
832 linestring_tag, polygon_tag, linestring_tag,
833 linear_tag, areal_tag, linear_tag
834 > : detail::intersection::intersection_of_linestring_with_areal
845 typename Linestring, typename Ring,
846 typename GeometryOut,
847 overlay_type OverlayType,
848 bool ReverseLinestring, bool ReverseRing, bool ReverseOut
850 struct intersection_insert
855 ReverseLinestring, ReverseRing, ReverseOut,
856 linestring_tag, ring_tag, linestring_tag,
857 linear_tag, areal_tag, linear_tag
858 > : detail::intersection::intersection_of_linestring_with_areal
868 typename Segment, typename Box,
869 typename GeometryOut,
870 overlay_type OverlayType,
871 bool Reverse1, bool Reverse2, bool ReverseOut
873 struct intersection_insert
878 Reverse1, Reverse2, ReverseOut,
879 segment_tag, box_tag, linestring_tag,
880 linear_tag, areal_tag, linear_tag
883 template <typename RobustPolicy, typename OutputIterator, typename Strategy>
884 static inline OutputIterator apply(Segment const& segment,
886 RobustPolicy const& robust_policy,
887 OutputIterator out, Strategy const& )
889 geometry::segment_view<Segment> range(segment);
891 typedef typename point_type<GeometryOut>::type point_type;
892 strategy::intersection::liang_barsky<Box, point_type> lb_strategy;
893 return detail::intersection::clip_range_with_box
894 <GeometryOut>(box, range, robust_policy, out, lb_strategy);
900 typename Geometry1, typename Geometry2,
902 overlay_type OverlayType,
903 bool Reverse1, bool Reverse2, bool ReverseOut,
904 typename Tag1, typename Tag2
906 struct intersection_insert
908 Geometry1, Geometry2,
911 Reverse1, Reverse2, ReverseOut,
912 Tag1, Tag2, point_tag,
913 areal_tag, areal_tag, pointlike_tag
915 : public detail::intersection::intersection_areal_areal_point
923 typename Geometry1, typename Geometry2,
925 overlay_type OverlayType,
926 bool Reverse1, bool Reverse2, bool ReverseOut,
927 typename Tag1, typename Tag2
929 struct intersection_insert
931 Geometry1, Geometry2,
934 Reverse1, Reverse2, ReverseOut,
935 Tag1, Tag2, point_tag,
936 linear_tag, areal_tag, pointlike_tag
938 : public detail::intersection::intersection_linear_areal_point
946 typename Geometry1, typename Geometry2,
948 overlay_type OverlayType,
949 bool Reverse1, bool Reverse2, bool ReverseOut,
950 typename Tag1, typename Tag2
952 struct intersection_insert
954 Geometry1, Geometry2,
957 Reverse1, Reverse2, ReverseOut,
958 Tag1, Tag2, point_tag,
959 areal_tag, linear_tag, pointlike_tag
961 : public detail::intersection::intersection_areal_linear_point
969 typename Geometry1, typename Geometry2, typename GeometryOut,
970 overlay_type OverlayType,
971 bool Reverse1, bool Reverse2, bool ReverseOut
973 struct intersection_insert_reversed
975 template <typename RobustPolicy, typename OutputIterator, typename Strategy>
976 static inline OutputIterator apply(Geometry1 const& g1,
978 RobustPolicy const& robust_policy,
980 Strategy const& strategy)
982 return intersection_insert
984 Geometry2, Geometry1, GeometryOut,
986 Reverse2, Reverse1, ReverseOut
987 >::apply(g2, g1, robust_policy, out, strategy);
992 // dispatch for intersection(areal, areal, linear)
995 typename Geometry1, typename Geometry2,
996 typename LinestringOut,
997 bool Reverse1, bool Reverse2, bool ReverseOut,
998 typename Tag1, typename Tag2
1000 struct intersection_insert
1002 Geometry1, Geometry2,
1004 overlay_intersection,
1005 Reverse1, Reverse2, ReverseOut,
1006 Tag1, Tag2, linestring_tag,
1007 areal_tag, areal_tag, linear_tag
1012 typename RobustPolicy, typename OutputIterator, typename Strategy
1014 static inline OutputIterator apply(Geometry1 const& geometry1,
1015 Geometry2 const& geometry2,
1016 RobustPolicy const& robust_policy,
1018 Strategy const& strategy)
1020 detail::boundary_view<Geometry1 const> view1(geometry1);
1021 detail::boundary_view<Geometry2 const> view2(geometry2);
1023 return detail::overlay::linear_linear_linestring
1025 detail::boundary_view<Geometry1 const>,
1026 detail::boundary_view<Geometry2 const>,
1028 overlay_intersection
1029 >::apply(view1, view2, robust_policy, oit, strategy);
1033 // dispatch for difference/intersection of linear geometries
1036 typename Linear1, typename Linear2, typename LineStringOut,
1037 overlay_type OverlayType,
1038 bool Reverse1, bool Reverse2, bool ReverseOut,
1039 typename TagIn1, typename TagIn2
1041 struct intersection_insert
1043 Linear1, Linear2, LineStringOut, OverlayType,
1044 Reverse1, Reverse2, ReverseOut,
1045 TagIn1, TagIn2, linestring_tag,
1046 linear_tag, linear_tag, linear_tag
1047 > : detail::overlay::linear_linear_linestring
1049 Linear1, Linear2, LineStringOut, OverlayType
1054 // dispatch for difference/intersection of point-like geometries
1058 typename Point1, typename Point2, typename PointOut,
1059 overlay_type OverlayType,
1060 bool Reverse1, bool Reverse2, bool ReverseOut
1062 struct intersection_insert
1064 Point1, Point2, PointOut, OverlayType,
1065 Reverse1, Reverse2, ReverseOut,
1066 point_tag, point_tag, point_tag,
1067 pointlike_tag, pointlike_tag, pointlike_tag
1068 > : detail::overlay::point_point_point
1070 Point1, Point2, PointOut, OverlayType
1077 typename MultiPoint, typename Point, typename PointOut,
1078 overlay_type OverlayType,
1079 bool Reverse1, bool Reverse2, bool ReverseOut
1081 struct intersection_insert
1083 MultiPoint, Point, PointOut, OverlayType,
1084 Reverse1, Reverse2, ReverseOut,
1085 multi_point_tag, point_tag, point_tag,
1086 pointlike_tag, pointlike_tag, pointlike_tag
1087 > : detail::overlay::multipoint_point_point
1089 MultiPoint, Point, PointOut, OverlayType
1096 typename Point, typename MultiPoint, typename PointOut,
1097 overlay_type OverlayType,
1098 bool Reverse1, bool Reverse2, bool ReverseOut
1100 struct intersection_insert
1102 Point, MultiPoint, PointOut, OverlayType,
1103 Reverse1, Reverse2, ReverseOut,
1104 point_tag, multi_point_tag, point_tag,
1105 pointlike_tag, pointlike_tag, pointlike_tag
1106 > : detail::overlay::point_multipoint_point
1108 Point, MultiPoint, PointOut, OverlayType
1115 typename MultiPoint1, typename MultiPoint2, typename PointOut,
1116 overlay_type OverlayType,
1117 bool Reverse1, bool Reverse2, bool ReverseOut
1119 struct intersection_insert
1121 MultiPoint1, MultiPoint2, PointOut, OverlayType,
1122 Reverse1, Reverse2, ReverseOut,
1123 multi_point_tag, multi_point_tag, point_tag,
1124 pointlike_tag, pointlike_tag, pointlike_tag
1125 > : detail::overlay::multipoint_multipoint_point
1127 MultiPoint1, MultiPoint2, PointOut, OverlayType
1132 // dispatch for difference/intersection of pointlike-linear geometries
1135 typename Point, typename Linear, typename PointOut,
1136 overlay_type OverlayType,
1137 bool Reverse1, bool Reverse2, bool ReverseOut,
1140 struct intersection_insert
1142 Point, Linear, PointOut, OverlayType,
1143 Reverse1, Reverse2, ReverseOut,
1144 point_tag, Tag, point_tag,
1145 pointlike_tag, linear_tag, pointlike_tag
1146 > : detail_dispatch::overlay::pointlike_linear_point
1148 Point, Linear, PointOut, OverlayType,
1149 point_tag, typename tag_cast<Tag, segment_tag, linear_tag>::type
1156 typename MultiPoint, typename Linear, typename PointOut,
1157 overlay_type OverlayType,
1158 bool Reverse1, bool Reverse2, bool ReverseOut,
1161 struct intersection_insert
1163 MultiPoint, Linear, PointOut, OverlayType,
1164 Reverse1, Reverse2, ReverseOut,
1165 multi_point_tag, Tag, point_tag,
1166 pointlike_tag, linear_tag, pointlike_tag
1167 > : detail_dispatch::overlay::pointlike_linear_point
1169 MultiPoint, Linear, PointOut, OverlayType,
1171 typename tag_cast<Tag, segment_tag, linear_tag>::type
1178 typename Linestring, typename MultiPoint, typename PointOut,
1179 bool Reverse1, bool Reverse2, bool ReverseOut
1181 struct intersection_insert
1183 Linestring, MultiPoint, PointOut, overlay_intersection,
1184 Reverse1, Reverse2, ReverseOut,
1185 linestring_tag, multi_point_tag, point_tag,
1186 linear_tag, pointlike_tag, pointlike_tag
1189 template <typename RobustPolicy, typename OutputIterator, typename Strategy>
1190 static inline OutputIterator apply(Linestring const& linestring,
1191 MultiPoint const& multipoint,
1192 RobustPolicy const& robust_policy,
1194 Strategy const& strategy)
1196 return detail_dispatch::overlay::pointlike_linear_point
1198 MultiPoint, Linestring, PointOut, overlay_intersection,
1199 multi_point_tag, linear_tag
1200 >::apply(multipoint, linestring, robust_policy, out, strategy);
1205 } // namespace dispatch
1206 #endif // DOXYGEN_NO_DISPATCH
1209 #ifndef DOXYGEN_NO_DETAIL
1210 namespace detail { namespace intersection
1216 typename GeometryOut,
1218 overlay_type OverlayType,
1219 typename Geometry1, typename Geometry2,
1220 typename RobustPolicy,
1221 typename OutputIterator,
1224 inline OutputIterator insert(Geometry1 const& geometry1,
1225 Geometry2 const& geometry2,
1226 RobustPolicy robust_policy,
1228 Strategy const& strategy)
1230 return boost::mpl::if_c
1232 geometry::reverse_dispatch<Geometry1, Geometry2>::type::value,
1233 geometry::dispatch::intersection_insert_reversed
1235 Geometry1, Geometry2,
1238 overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
1239 overlay::do_reverse<geometry::point_order<Geometry2>::value, ReverseSecond>::value,
1240 overlay::do_reverse<geometry::point_order<GeometryOut>::value>::value
1242 geometry::dispatch::intersection_insert
1244 Geometry1, Geometry2,
1247 geometry::detail::overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
1248 geometry::detail::overlay::do_reverse<geometry::point_order<Geometry2>::value, ReverseSecond>::value
1250 >::type::apply(geometry1, geometry2, robust_policy, out, strategy);
1255 \brief \brief_calc2{intersection} \brief_strategy
1256 \ingroup intersection
1257 \details \details_calc2{intersection_insert, spatial set theoretic intersection}
1258 \brief_strategy. \details_insert{intersection}
1259 \tparam GeometryOut \tparam_geometry{\p_l_or_c}
1260 \tparam Geometry1 \tparam_geometry
1261 \tparam Geometry2 \tparam_geometry
1262 \tparam OutputIterator \tparam_out{\p_l_or_c}
1263 \tparam Strategy \tparam_strategy_overlay
1264 \param geometry1 \param_geometry
1265 \param geometry2 \param_geometry
1266 \param out \param_out{intersection}
1267 \param strategy \param_strategy{intersection}
1270 \qbk{distinguish,with strategy}
1271 \qbk{[include reference/algorithms/intersection.qbk]}
1275 typename GeometryOut,
1278 typename OutputIterator,
1281 inline OutputIterator intersection_insert(Geometry1 const& geometry1,
1282 Geometry2 const& geometry2,
1284 Strategy const& strategy)
1286 concepts::check<Geometry1 const>();
1287 concepts::check<Geometry2 const>();
1289 typedef typename geometry::rescale_overlay_policy_type
1293 typename Strategy::cs_tag
1294 >::type rescale_policy_type;
1296 rescale_policy_type robust_policy
1297 = geometry::get_rescale_policy<rescale_policy_type>(
1298 geometry1, geometry2, strategy);
1300 return detail::intersection::insert
1302 GeometryOut, false, overlay_intersection
1303 >(geometry1, geometry2, robust_policy, out, strategy);
1308 \brief \brief_calc2{intersection}
1309 \ingroup intersection
1310 \details \details_calc2{intersection_insert, spatial set theoretic intersection}.
1311 \details_insert{intersection}
1312 \tparam GeometryOut \tparam_geometry{\p_l_or_c}
1313 \tparam Geometry1 \tparam_geometry
1314 \tparam Geometry2 \tparam_geometry
1315 \tparam OutputIterator \tparam_out{\p_l_or_c}
1316 \param geometry1 \param_geometry
1317 \param geometry2 \param_geometry
1318 \param out \param_out{intersection}
1321 \qbk{[include reference/algorithms/intersection.qbk]}
1325 typename GeometryOut,
1328 typename OutputIterator
1330 inline OutputIterator intersection_insert(Geometry1 const& geometry1,
1331 Geometry2 const& geometry2,
1334 concepts::check<Geometry1 const>();
1335 concepts::check<Geometry2 const>();
1337 typedef typename strategy::intersection::services::default_strategy
1339 typename cs_tag<GeometryOut>::type
1340 >::type strategy_type;
1342 return intersection_insert<GeometryOut>(geometry1, geometry2, out,
1346 }} // namespace detail::intersection
1347 #endif // DOXYGEN_NO_DETAIL
1351 }} // namespace boost::geometry
1354 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_INTERSECTION_INSERT_HPP