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.
6 // Modifications copyright (c) 2014-2017 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>
39 #include <boost/geometry/policies/robustness/robust_point_type.hpp>
40 #include <boost/geometry/policies/robustness/segment_ratio_type.hpp>
41 #include <boost/geometry/policies/robustness/get_rescale_policy.hpp>
43 #include <boost/geometry/views/segment_view.hpp>
44 #include <boost/geometry/views/detail/boundary_view.hpp>
46 #include <boost/geometry/algorithms/detail/check_iterator_range.hpp>
47 #include <boost/geometry/algorithms/detail/overlay/linear_linear.hpp>
48 #include <boost/geometry/algorithms/detail/overlay/pointlike_pointlike.hpp>
49 #include <boost/geometry/algorithms/detail/overlay/pointlike_linear.hpp>
51 #if defined(BOOST_GEOMETRY_DEBUG_FOLLOW)
52 #include <boost/geometry/algorithms/detail/overlay/debug_turn_info.hpp>
53 #include <boost/geometry/io/wkt/wkt.hpp>
56 namespace boost { namespace geometry
59 #ifndef DOXYGEN_NO_DETAIL
60 namespace detail { namespace intersection
63 template <typename PointOut>
64 struct intersection_segment_segment_point
68 typename Segment1, typename Segment2,
69 typename RobustPolicy,
70 typename OutputIterator, typename Strategy
72 static inline OutputIterator apply(Segment1 const& segment1,
73 Segment2 const& segment2,
74 RobustPolicy const& robust_policy,
76 Strategy const& strategy)
78 typedef typename point_type<PointOut>::type point_type;
80 typedef typename geometry::robust_point_type
82 typename geometry::point_type<Segment1>::type,
84 >::type robust_point_type;
86 // TODO: rescale segment -> robust points
87 robust_point_type pi_rob, pj_rob, qi_rob, qj_rob;
90 point_type pi, pj, qi, qj;
91 assign_point_from_index<0>(segment1, pi);
92 assign_point_from_index<1>(segment1, pj);
93 assign_point_from_index<0>(segment2, qi);
94 assign_point_from_index<1>(segment2, qj);
95 geometry::recalculate(pi_rob, pi, robust_policy);
96 geometry::recalculate(pj_rob, pj, robust_policy);
97 geometry::recalculate(qi_rob, qi, robust_policy);
98 geometry::recalculate(qj_rob, qj, robust_policy);
101 // Get the intersection point (or two points)
102 typedef segment_intersection_points
105 typename segment_ratio_type
107 point_type, RobustPolicy
109 > intersection_return_type;
111 typedef policies::relate::segments_intersection_points
113 intersection_return_type
116 intersection_return_type
117 is = strategy.apply(segment1, segment2,
118 policy_type(), robust_policy,
119 pi_rob, pj_rob, qi_rob, qj_rob);
121 for (std::size_t i = 0; i < is.count; i++)
124 geometry::convert(is.intersections[i], p);
131 template <typename PointOut>
132 struct intersection_linestring_linestring_point
136 typename Linestring1, typename Linestring2,
137 typename RobustPolicy,
138 typename OutputIterator,
141 static inline OutputIterator apply(Linestring1 const& linestring1,
142 Linestring2 const& linestring2,
143 RobustPolicy const& robust_policy,
145 Strategy const& strategy)
147 typedef typename point_type<PointOut>::type point_type;
149 typedef detail::overlay::turn_info
152 typename segment_ratio_type<point_type, RobustPolicy>::type
154 std::deque<turn_info> turns;
156 geometry::get_intersection_points(linestring1, linestring2,
157 robust_policy, turns, strategy);
159 for (typename boost::range_iterator<std::deque<turn_info> const>::type
160 it = boost::begin(turns); it != boost::end(turns); ++it)
163 geometry::convert(it->point, p);
171 \brief Version of linestring with an areal feature (polygon or multipolygon)
176 typename LineStringOut,
177 overlay_type OverlayType
179 struct intersection_of_linestring_with_areal
181 #if defined(BOOST_GEOMETRY_DEBUG_FOLLOW)
182 template <typename Turn, typename Operation>
183 static inline void debug_follow(Turn const& turn, Operation op,
187 << " at " << op.seg_id
188 << " meth: " << method_char(turn.method)
189 << " op: " << operation_char(op.operation)
190 << " vis: " << visited_char(op.visited)
191 << " of: " << operation_char(turn.operations[0].operation)
192 << operation_char(turn.operations[1].operation)
193 << " " << geometry::wkt(turn.point)
197 template <typename Turn>
198 static inline void debug_turn(Turn const& t, bool non_crossing)
200 std::cout << "checking turn @"
201 << geometry::wkt(t.point)
202 << "; " << method_char(t.method)
203 << ":" << operation_char(t.operations[0].operation)
204 << "/" << operation_char(t.operations[1].operation)
205 << "; non-crossing? "
206 << std::boolalpha << non_crossing << std::noboolalpha
211 #ifdef BOOST_GEOMETRY_SETOPS_LA_OLD_BEHAVIOR
213 class is_crossing_turn
215 // return true is the operation is intersection or blocked
216 template <std::size_t Index, typename Turn>
217 static inline bool has_op_i_or_b(Turn const& t)
220 t.operations[Index].operation == overlay::operation_intersection
222 t.operations[Index].operation == overlay::operation_blocked;
225 template <typename Turn>
226 static inline bool has_method_crosses(Turn const& t)
228 return t.method == overlay::method_crosses;
231 template <typename Turn>
232 static inline bool is_cc(Turn const& t)
235 (t.method == overlay::method_touch_interior
237 t.method == overlay::method_equal
239 t.method == overlay::method_collinear)
241 t.operations[0].operation == t.operations[1].operation
243 t.operations[0].operation == overlay::operation_continue
247 template <typename Turn>
248 static inline bool has_i_or_b_ops(Turn const& t)
251 (t.method == overlay::method_touch
253 t.method == overlay::method_touch_interior
255 t.method == overlay::method_collinear)
257 t.operations[1].operation != t.operations[0].operation
259 (has_op_i_or_b<0>(t) || has_op_i_or_b<1>(t));
263 template <typename Turn>
264 static inline bool apply(Turn const& t)
266 bool const is_crossing
267 = has_method_crosses(t) || is_cc(t) || has_i_or_b_ops(t);
268 #if defined(BOOST_GEOMETRY_DEBUG_FOLLOW)
269 debug_turn(t, ! is_crossing);
275 struct is_non_crossing_turn
277 template <typename Turn>
278 static inline bool apply(Turn const& t)
280 return ! is_crossing_turn::apply(t);
284 template <typename Turns>
285 static inline bool no_crossing_turns_or_empty(Turns const& turns)
287 return detail::check_iterator_range
289 is_non_crossing_turn,
290 true // allow an empty turns range
291 >::apply(boost::begin(turns), boost::end(turns));
294 template <typename Turns>
295 static inline int inside_or_outside_turn(Turns const& turns)
297 using namespace overlay;
298 for (typename Turns::const_iterator it = turns.begin();
299 it != turns.end(); ++it)
301 operation_type op0 = it->operations[0].operation;
302 operation_type op1 = it->operations[1].operation;
303 if (op0 == operation_intersection && op1 == operation_intersection)
307 else if (op0 == operation_union && op1 == operation_union)
309 return -1; // outside
315 #else // BOOST_GEOMETRY_SETOPS_LA_OLD_BEHAVIOR
317 template <typename Linestring, typename Areal, typename Strategy, typename Turns>
318 static inline bool simple_turns_analysis(Linestring const& linestring,
320 Strategy const& strategy,
324 using namespace overlay;
326 bool found_continue = false;
327 bool found_intersection = false;
328 bool found_union = false;
329 bool found_front = false;
331 for (typename Turns::const_iterator it = turns.begin();
332 it != turns.end(); ++it)
334 method_type const method = it->method;
335 operation_type const op = it->operations[0].operation;
337 if (method == method_crosses)
341 else if (op == operation_intersection)
343 found_intersection = true;
345 else if (op == operation_union)
349 else if (op == operation_continue)
351 found_continue = true;
354 if ((found_intersection || found_continue) && found_union)
359 if (it->operations[0].position == position_front)
367 if (found_intersection)
369 inside_value = 1; // inside
371 else if (found_union)
373 inside_value = -1; // outside
375 else // continue and blocked
382 // if needed analyse points of a linestring
383 // NOTE: range_in_geometry checks points of a linestring
384 // until a point inside/outside areal is found
385 // TODO: Could be replaced with point_in_geometry() because found_front is false
386 inside_value = range_in_geometry(linestring, areal, strategy);
388 if ( (found_intersection && inside_value == -1) // going in from outside
389 || (found_continue && inside_value == -1) // going on boundary from outside
390 || (found_union && inside_value == 1) ) // going out from inside
398 #endif // BOOST_GEOMETRY_SETOPS_LA_OLD_BEHAVIOR
402 typename LineString, typename Areal,
403 typename RobustPolicy,
404 typename OutputIterator, typename Strategy
406 static inline OutputIterator apply(LineString const& linestring, Areal const& areal,
407 RobustPolicy const& robust_policy,
409 Strategy const& strategy)
411 if (boost::size(linestring) == 0)
416 typedef detail::overlay::follow
422 false // do not remove spikes for linear geometries
425 typedef typename point_type<LineStringOut>::type point_type;
426 #ifdef BOOST_GEOMETRY_SETOPS_LA_OLD_BEHAVIOR
427 typedef detail::overlay::traversal_turn_info
430 typename geometry::segment_ratio_type<point_type, RobustPolicy>::type
433 typedef detail::overlay::turn_info
436 typename geometry::segment_ratio_type<point_type, RobustPolicy>::type,
437 detail::overlay::turn_operation_linear
440 typename geometry::segment_ratio_type<point_type, RobustPolicy>::type
444 std::deque<turn_info> turns;
446 detail::get_turns::no_interrupt_policy policy;
448 #ifdef BOOST_GEOMETRY_SETOPS_LA_OLD_BEHAVIOR
453 (OverlayType == overlay_intersection ? ReverseAreal : !ReverseAreal),
454 detail::overlay::assign_null_policy
455 >(linestring, areal, strategy, robust_policy, turns, policy);
457 if (no_crossing_turns_or_empty(turns))
459 // No intersection points, it is either
460 // inside (interior + borders)
461 // or outside (exterior + borders)
464 int inside_value = inside_or_outside_turn(turns);
465 if (inside_value == 0)
467 // if needed analyse points of a linestring
468 // NOTE: range_in_geometry checks points of a linestring
469 // until a point inside/outside areal is found
470 inside_value = overlay::range_in_geometry(linestring, areal, strategy);
472 // add linestring to the output if conditions are met
473 if (inside_value != 0 && follower::included(inside_value))
476 geometry::convert(linestring, copy);
482 #else // BOOST_GEOMETRY_SETOPS_LA_OLD_BEHAVIOR
484 typedef detail::overlay::get_turn_info_linear_areal
486 detail::overlay::assign_null_policy
491 typename geometry::tag<LineString>::type,
492 typename geometry::tag<Areal>::type,
496 (OverlayType == overlay_intersection ? ReverseAreal : !ReverseAreal),
498 >::apply(0, linestring, 1, areal,
499 strategy, robust_policy,
502 int inside_value = 0;
503 if (simple_turns_analysis(linestring, areal, strategy, turns, inside_value))
505 // No crossing the boundary, it is either
506 // inside (interior + borders)
507 // or outside (exterior + borders)
510 // add linestring to the output if conditions are met
511 if (follower::included(inside_value))
514 geometry::convert(linestring, copy);
521 #endif // BOOST_GEOMETRY_SETOPS_LA_OLD_BEHAVIOR
523 #if defined(BOOST_GEOMETRY_DEBUG_FOLLOW)
525 for(typename std::deque<turn_info>::const_iterator
526 it = turns.begin(); it != turns.end(); ++it)
528 debug_follow(*it, it->operations[0], index++);
532 return follower::apply
535 geometry::detail::overlay::operation_intersection,
536 turns, robust_policy, out, strategy
542 template <typename Turns, typename OutputIterator>
543 inline OutputIterator intersection_output_turn_points(Turns const& turns,
546 for (typename Turns::const_iterator
547 it = turns.begin(); it != turns.end(); ++it)
555 template <typename PointOut>
556 struct intersection_areal_areal_point
560 typename Geometry1, typename Geometry2,
561 typename RobustPolicy,
562 typename OutputIterator,
565 static inline OutputIterator apply(Geometry1 const& geometry1,
566 Geometry2 const& geometry2,
567 RobustPolicy const& robust_policy,
569 Strategy const& strategy)
571 typedef detail::overlay::turn_info
574 typename segment_ratio_type<PointOut, RobustPolicy>::type
576 std::vector<turn_info> turns;
578 detail::get_turns::no_interrupt_policy policy;
582 false, false, detail::overlay::assign_null_policy
583 >(geometry1, geometry2, strategy, robust_policy, turns, policy);
585 return intersection_output_turn_points(turns, out);
589 template <typename PointOut>
590 struct intersection_linear_areal_point
594 typename Geometry1, typename Geometry2,
595 typename RobustPolicy,
596 typename OutputIterator,
599 static inline OutputIterator apply(Geometry1 const& geometry1,
600 Geometry2 const& geometry2,
601 RobustPolicy const& robust_policy,
603 Strategy const& strategy)
605 typedef typename geometry::segment_ratio_type
607 PointOut, RobustPolicy
608 >::type segment_ratio_type;
610 typedef detail::overlay::turn_info
614 detail::overlay::turn_operation_linear
621 typedef detail::overlay::get_turn_info_linear_areal
623 detail::overlay::assign_null_policy
626 std::vector<turn_info> turns;
628 detail::get_turns::no_interrupt_policy interrupt_policy;
632 typename geometry::tag<Geometry1>::type,
633 typename geometry::tag<Geometry2>::type,
639 >::apply(0, geometry1, 1, geometry2,
640 strategy, robust_policy,
641 turns, interrupt_policy);
643 return intersection_output_turn_points(turns, out);
647 template <typename PointOut>
648 struct intersection_areal_linear_point
652 typename Geometry1, typename Geometry2,
653 typename RobustPolicy,
654 typename OutputIterator,
657 static inline OutputIterator apply(Geometry1 const& geometry1,
658 Geometry2 const& geometry2,
659 RobustPolicy const& robust_policy,
661 Strategy const& strategy)
663 return intersection_linear_areal_point
666 >::apply(geometry2, geometry1, robust_policy, out, strategy);
671 }} // namespace detail::intersection
672 #endif // DOXYGEN_NO_DETAIL
676 #ifndef DOXYGEN_NO_DISPATCH
685 typename GeometryOut,
686 overlay_type OverlayType,
688 bool Reverse1 = detail::overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
689 bool Reverse2 = detail::overlay::do_reverse<geometry::point_order<Geometry2>::value>::value,
690 bool ReverseOut = detail::overlay::do_reverse<geometry::point_order<GeometryOut>::value>::value,
692 typename TagIn1 = typename geometry::tag<Geometry1>::type,
693 typename TagIn2 = typename geometry::tag<Geometry2>::type,
694 typename TagOut = typename geometry::tag<GeometryOut>::type,
695 // metafunction finetuning helpers:
696 typename CastedTagIn1 = typename geometry::tag_cast<TagIn1, areal_tag, linear_tag, pointlike_tag>::type,
697 typename CastedTagIn2 = typename geometry::tag_cast<TagIn2, areal_tag, linear_tag, pointlike_tag>::type,
698 typename CastedTagOut = typename geometry::tag_cast<TagOut, areal_tag, linear_tag, pointlike_tag>::type
700 struct intersection_insert
704 false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPES_OR_ORIENTATIONS
705 , (types<Geometry1, Geometry2, GeometryOut>)
712 typename Geometry1, typename Geometry2,
713 typename GeometryOut,
714 overlay_type OverlayType,
715 bool Reverse1, bool Reverse2, bool ReverseOut,
716 typename TagIn1, typename TagIn2, typename TagOut
718 struct intersection_insert
720 Geometry1, Geometry2,
723 Reverse1, Reverse2, ReverseOut,
724 TagIn1, TagIn2, TagOut,
725 areal_tag, areal_tag, areal_tag
726 > : detail::overlay::overlay
727 <Geometry1, Geometry2, Reverse1, Reverse2, ReverseOut, GeometryOut, OverlayType>
731 // Any areal type with box:
734 typename Geometry, typename Box,
735 typename GeometryOut,
736 overlay_type OverlayType,
737 bool Reverse1, bool Reverse2, bool ReverseOut,
738 typename TagIn, typename TagOut
740 struct intersection_insert
745 Reverse1, Reverse2, ReverseOut,
746 TagIn, box_tag, TagOut,
747 areal_tag, areal_tag, areal_tag
748 > : detail::overlay::overlay
749 <Geometry, Box, Reverse1, Reverse2, ReverseOut, GeometryOut, OverlayType>
755 typename Segment1, typename Segment2,
756 typename GeometryOut,
757 overlay_type OverlayType,
758 bool Reverse1, bool Reverse2, bool ReverseOut
760 struct intersection_insert
765 Reverse1, Reverse2, ReverseOut,
766 segment_tag, segment_tag, point_tag,
767 linear_tag, linear_tag, pointlike_tag
768 > : detail::intersection::intersection_segment_segment_point<GeometryOut>
774 typename Linestring1, typename Linestring2,
775 typename GeometryOut,
776 overlay_type OverlayType,
777 bool Reverse1, bool Reverse2, bool ReverseOut
779 struct intersection_insert
781 Linestring1, Linestring2,
784 Reverse1, Reverse2, ReverseOut,
785 linestring_tag, linestring_tag, point_tag,
786 linear_tag, linear_tag, pointlike_tag
787 > : detail::intersection::intersection_linestring_linestring_point<GeometryOut>
793 typename Linestring, typename Box,
794 typename GeometryOut,
795 bool Reverse1, bool Reverse2, bool ReverseOut
797 struct intersection_insert
801 overlay_intersection,
802 Reverse1, Reverse2, ReverseOut,
803 linestring_tag, box_tag, linestring_tag,
804 linear_tag, areal_tag, linear_tag
807 template <typename RobustPolicy, typename OutputIterator, typename Strategy>
808 static inline OutputIterator apply(Linestring const& linestring,
810 RobustPolicy const& robust_policy,
811 OutputIterator out, Strategy const& )
813 typedef typename point_type<GeometryOut>::type point_type;
814 strategy::intersection::liang_barsky<Box, point_type> lb_strategy;
815 return detail::intersection::clip_range_with_box
816 <GeometryOut>(box, linestring, robust_policy, out, lb_strategy);
823 typename Linestring, typename Polygon,
824 typename GeometryOut,
825 overlay_type OverlayType,
826 bool ReverseLinestring, bool ReversePolygon, bool ReverseOut
828 struct intersection_insert
833 ReverseLinestring, ReversePolygon, ReverseOut,
834 linestring_tag, polygon_tag, linestring_tag,
835 linear_tag, areal_tag, linear_tag
836 > : detail::intersection::intersection_of_linestring_with_areal
847 typename Linestring, typename Ring,
848 typename GeometryOut,
849 overlay_type OverlayType,
850 bool ReverseLinestring, bool ReverseRing, bool ReverseOut
852 struct intersection_insert
857 ReverseLinestring, ReverseRing, ReverseOut,
858 linestring_tag, ring_tag, linestring_tag,
859 linear_tag, areal_tag, linear_tag
860 > : detail::intersection::intersection_of_linestring_with_areal
870 typename Segment, typename Box,
871 typename GeometryOut,
872 overlay_type OverlayType,
873 bool Reverse1, bool Reverse2, bool ReverseOut
875 struct intersection_insert
880 Reverse1, Reverse2, ReverseOut,
881 segment_tag, box_tag, linestring_tag,
882 linear_tag, areal_tag, linear_tag
885 template <typename RobustPolicy, typename OutputIterator, typename Strategy>
886 static inline OutputIterator apply(Segment const& segment,
888 RobustPolicy const& robust_policy,
889 OutputIterator out, Strategy const& )
891 geometry::segment_view<Segment> range(segment);
893 typedef typename point_type<GeometryOut>::type point_type;
894 strategy::intersection::liang_barsky<Box, point_type> lb_strategy;
895 return detail::intersection::clip_range_with_box
896 <GeometryOut>(box, range, robust_policy, out, lb_strategy);
902 typename Geometry1, typename Geometry2,
904 overlay_type OverlayType,
905 bool Reverse1, bool Reverse2, bool ReverseOut,
906 typename Tag1, typename Tag2
908 struct intersection_insert
910 Geometry1, Geometry2,
913 Reverse1, Reverse2, ReverseOut,
914 Tag1, Tag2, point_tag,
915 areal_tag, areal_tag, pointlike_tag
917 : public detail::intersection::intersection_areal_areal_point
925 typename Geometry1, typename Geometry2,
927 overlay_type OverlayType,
928 bool Reverse1, bool Reverse2, bool ReverseOut,
929 typename Tag1, typename Tag2
931 struct intersection_insert
933 Geometry1, Geometry2,
936 Reverse1, Reverse2, ReverseOut,
937 Tag1, Tag2, point_tag,
938 linear_tag, areal_tag, pointlike_tag
940 : public detail::intersection::intersection_linear_areal_point
948 typename Geometry1, typename Geometry2,
950 overlay_type OverlayType,
951 bool Reverse1, bool Reverse2, bool ReverseOut,
952 typename Tag1, typename Tag2
954 struct intersection_insert
956 Geometry1, Geometry2,
959 Reverse1, Reverse2, ReverseOut,
960 Tag1, Tag2, point_tag,
961 areal_tag, linear_tag, pointlike_tag
963 : public detail::intersection::intersection_areal_linear_point
971 typename Geometry1, typename Geometry2, typename GeometryOut,
972 overlay_type OverlayType,
973 bool Reverse1, bool Reverse2, bool ReverseOut
975 struct intersection_insert_reversed
977 template <typename RobustPolicy, typename OutputIterator, typename Strategy>
978 static inline OutputIterator apply(Geometry1 const& g1,
980 RobustPolicy const& robust_policy,
982 Strategy const& strategy)
984 return intersection_insert
986 Geometry2, Geometry1, GeometryOut,
988 Reverse2, Reverse1, ReverseOut
989 >::apply(g2, g1, robust_policy, out, strategy);
994 // dispatch for intersection(areal, areal, linear)
997 typename Geometry1, typename Geometry2,
998 typename LinestringOut,
999 bool Reverse1, bool Reverse2, bool ReverseOut,
1000 typename Tag1, typename Tag2
1002 struct intersection_insert
1004 Geometry1, Geometry2,
1006 overlay_intersection,
1007 Reverse1, Reverse2, ReverseOut,
1008 Tag1, Tag2, linestring_tag,
1009 areal_tag, areal_tag, linear_tag
1014 typename RobustPolicy, typename OutputIterator, typename Strategy
1016 static inline OutputIterator apply(Geometry1 const& geometry1,
1017 Geometry2 const& geometry2,
1018 RobustPolicy const& robust_policy,
1020 Strategy const& strategy)
1022 detail::boundary_view<Geometry1 const> view1(geometry1);
1023 detail::boundary_view<Geometry2 const> view2(geometry2);
1025 return detail::overlay::linear_linear_linestring
1027 detail::boundary_view<Geometry1 const>,
1028 detail::boundary_view<Geometry2 const>,
1030 overlay_intersection
1031 >::apply(view1, view2, robust_policy, oit, strategy);
1035 // dispatch for difference/intersection of linear geometries
1038 typename Linear1, typename Linear2, typename LineStringOut,
1039 overlay_type OverlayType,
1040 bool Reverse1, bool Reverse2, bool ReverseOut,
1041 typename TagIn1, typename TagIn2
1043 struct intersection_insert
1045 Linear1, Linear2, LineStringOut, OverlayType,
1046 Reverse1, Reverse2, ReverseOut,
1047 TagIn1, TagIn2, linestring_tag,
1048 linear_tag, linear_tag, linear_tag
1049 > : detail::overlay::linear_linear_linestring
1051 Linear1, Linear2, LineStringOut, OverlayType
1056 // dispatch for difference/intersection of point-like geometries
1060 typename Point1, typename Point2, typename PointOut,
1061 overlay_type OverlayType,
1062 bool Reverse1, bool Reverse2, bool ReverseOut
1064 struct intersection_insert
1066 Point1, Point2, PointOut, OverlayType,
1067 Reverse1, Reverse2, ReverseOut,
1068 point_tag, point_tag, point_tag,
1069 pointlike_tag, pointlike_tag, pointlike_tag
1070 > : detail::overlay::point_point_point
1072 Point1, Point2, PointOut, OverlayType
1079 typename MultiPoint, typename Point, typename PointOut,
1080 overlay_type OverlayType,
1081 bool Reverse1, bool Reverse2, bool ReverseOut
1083 struct intersection_insert
1085 MultiPoint, Point, PointOut, OverlayType,
1086 Reverse1, Reverse2, ReverseOut,
1087 multi_point_tag, point_tag, point_tag,
1088 pointlike_tag, pointlike_tag, pointlike_tag
1089 > : detail::overlay::multipoint_point_point
1091 MultiPoint, Point, PointOut, OverlayType
1098 typename Point, typename MultiPoint, typename PointOut,
1099 overlay_type OverlayType,
1100 bool Reverse1, bool Reverse2, bool ReverseOut
1102 struct intersection_insert
1104 Point, MultiPoint, PointOut, OverlayType,
1105 Reverse1, Reverse2, ReverseOut,
1106 point_tag, multi_point_tag, point_tag,
1107 pointlike_tag, pointlike_tag, pointlike_tag
1108 > : detail::overlay::point_multipoint_point
1110 Point, MultiPoint, PointOut, OverlayType
1117 typename MultiPoint1, typename MultiPoint2, typename PointOut,
1118 overlay_type OverlayType,
1119 bool Reverse1, bool Reverse2, bool ReverseOut
1121 struct intersection_insert
1123 MultiPoint1, MultiPoint2, PointOut, OverlayType,
1124 Reverse1, Reverse2, ReverseOut,
1125 multi_point_tag, multi_point_tag, point_tag,
1126 pointlike_tag, pointlike_tag, pointlike_tag
1127 > : detail::overlay::multipoint_multipoint_point
1129 MultiPoint1, MultiPoint2, PointOut, OverlayType
1134 // dispatch for difference/intersection of pointlike-linear geometries
1137 typename Point, typename Linear, typename PointOut,
1138 overlay_type OverlayType,
1139 bool Reverse1, bool Reverse2, bool ReverseOut,
1142 struct intersection_insert
1144 Point, Linear, PointOut, OverlayType,
1145 Reverse1, Reverse2, ReverseOut,
1146 point_tag, Tag, point_tag,
1147 pointlike_tag, linear_tag, pointlike_tag
1148 > : detail_dispatch::overlay::pointlike_linear_point
1150 Point, Linear, PointOut, OverlayType,
1151 point_tag, typename tag_cast<Tag, segment_tag, linear_tag>::type
1158 typename MultiPoint, typename Linear, typename PointOut,
1159 overlay_type OverlayType,
1160 bool Reverse1, bool Reverse2, bool ReverseOut,
1163 struct intersection_insert
1165 MultiPoint, Linear, PointOut, OverlayType,
1166 Reverse1, Reverse2, ReverseOut,
1167 multi_point_tag, Tag, point_tag,
1168 pointlike_tag, linear_tag, pointlike_tag
1169 > : detail_dispatch::overlay::pointlike_linear_point
1171 MultiPoint, Linear, PointOut, OverlayType,
1173 typename tag_cast<Tag, segment_tag, linear_tag>::type
1180 typename Linestring, typename MultiPoint, typename PointOut,
1181 bool Reverse1, bool Reverse2, bool ReverseOut
1183 struct intersection_insert
1185 Linestring, MultiPoint, PointOut, overlay_intersection,
1186 Reverse1, Reverse2, ReverseOut,
1187 linestring_tag, multi_point_tag, point_tag,
1188 linear_tag, pointlike_tag, pointlike_tag
1191 template <typename RobustPolicy, typename OutputIterator, typename Strategy>
1192 static inline OutputIterator apply(Linestring const& linestring,
1193 MultiPoint const& multipoint,
1194 RobustPolicy const& robust_policy,
1196 Strategy const& strategy)
1198 return detail_dispatch::overlay::pointlike_linear_point
1200 MultiPoint, Linestring, PointOut, overlay_intersection,
1201 multi_point_tag, linear_tag
1202 >::apply(multipoint, linestring, robust_policy, out, strategy);
1207 } // namespace dispatch
1208 #endif // DOXYGEN_NO_DISPATCH
1211 #ifndef DOXYGEN_NO_DETAIL
1212 namespace detail { namespace intersection
1218 typename GeometryOut,
1220 overlay_type OverlayType,
1221 typename Geometry1, typename Geometry2,
1222 typename RobustPolicy,
1223 typename OutputIterator,
1226 inline OutputIterator insert(Geometry1 const& geometry1,
1227 Geometry2 const& geometry2,
1228 RobustPolicy robust_policy,
1230 Strategy const& strategy)
1232 return boost::mpl::if_c
1234 geometry::reverse_dispatch<Geometry1, Geometry2>::type::value,
1235 geometry::dispatch::intersection_insert_reversed
1237 Geometry1, Geometry2,
1240 overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
1241 overlay::do_reverse<geometry::point_order<Geometry2>::value, ReverseSecond>::value,
1242 overlay::do_reverse<geometry::point_order<GeometryOut>::value>::value
1244 geometry::dispatch::intersection_insert
1246 Geometry1, Geometry2,
1249 geometry::detail::overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
1250 geometry::detail::overlay::do_reverse<geometry::point_order<Geometry2>::value, ReverseSecond>::value
1252 >::type::apply(geometry1, geometry2, robust_policy, out, strategy);
1257 \brief \brief_calc2{intersection} \brief_strategy
1258 \ingroup intersection
1259 \details \details_calc2{intersection_insert, spatial set theoretic intersection}
1260 \brief_strategy. \details_insert{intersection}
1261 \tparam GeometryOut \tparam_geometry{\p_l_or_c}
1262 \tparam Geometry1 \tparam_geometry
1263 \tparam Geometry2 \tparam_geometry
1264 \tparam OutputIterator \tparam_out{\p_l_or_c}
1265 \tparam Strategy \tparam_strategy_overlay
1266 \param geometry1 \param_geometry
1267 \param geometry2 \param_geometry
1268 \param out \param_out{intersection}
1269 \param strategy \param_strategy{intersection}
1272 \qbk{distinguish,with strategy}
1273 \qbk{[include reference/algorithms/intersection.qbk]}
1277 typename GeometryOut,
1280 typename OutputIterator,
1283 inline OutputIterator intersection_insert(Geometry1 const& geometry1,
1284 Geometry2 const& geometry2,
1286 Strategy const& strategy)
1288 concepts::check<Geometry1 const>();
1289 concepts::check<Geometry2 const>();
1291 typedef typename geometry::rescale_policy_type
1293 typename geometry::point_type<Geometry1>::type // TODO from both
1294 >::type rescale_policy_type;
1296 rescale_policy_type robust_policy
1297 = geometry::get_rescale_policy<rescale_policy_type>(geometry1, geometry2);
1299 return detail::intersection::insert
1301 GeometryOut, false, overlay_intersection
1302 >(geometry1, geometry2, robust_policy, out, strategy);
1307 \brief \brief_calc2{intersection}
1308 \ingroup intersection
1309 \details \details_calc2{intersection_insert, spatial set theoretic intersection}.
1310 \details_insert{intersection}
1311 \tparam GeometryOut \tparam_geometry{\p_l_or_c}
1312 \tparam Geometry1 \tparam_geometry
1313 \tparam Geometry2 \tparam_geometry
1314 \tparam OutputIterator \tparam_out{\p_l_or_c}
1315 \param geometry1 \param_geometry
1316 \param geometry2 \param_geometry
1317 \param out \param_out{intersection}
1320 \qbk{[include reference/algorithms/intersection.qbk]}
1324 typename GeometryOut,
1327 typename OutputIterator
1329 inline OutputIterator intersection_insert(Geometry1 const& geometry1,
1330 Geometry2 const& geometry2,
1333 concepts::check<Geometry1 const>();
1334 concepts::check<Geometry2 const>();
1336 typedef typename strategy::intersection::services::default_strategy
1338 typename cs_tag<GeometryOut>::type
1339 >::type strategy_type;
1341 return intersection_insert<GeometryOut>(geometry1, geometry2, out,
1345 }} // namespace detail::intersection
1346 #endif // DOXYGEN_NO_DETAIL
1350 }} // namespace boost::geometry
1353 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_INTERSECTION_INSERT_HPP