File indexing completed on 2025-09-18 08:42:51
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_INTERSECTION_INSERT_HPP
0017 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_INTERSECTION_INSERT_HPP
0018
0019
0020 #include <cstddef>
0021 #include <deque>
0022 #include <type_traits>
0023
0024 #include <boost/range/begin.hpp>
0025 #include <boost/range/end.hpp>
0026 #include <boost/range/size.hpp>
0027
0028 #include <boost/geometry/algorithms/convert.hpp>
0029 #include <boost/geometry/algorithms/detail/point_on_border.hpp>
0030 #include <boost/geometry/algorithms/detail/overlay/clip_linestring.hpp>
0031 #include <boost/geometry/algorithms/detail/overlay/follow.hpp>
0032 #include <boost/geometry/algorithms/detail/overlay/get_intersection_points.hpp>
0033 #include <boost/geometry/algorithms/detail/overlay/linear_linear.hpp>
0034 #include <boost/geometry/algorithms/detail/overlay/overlay.hpp>
0035 #include <boost/geometry/algorithms/detail/overlay/overlay_type.hpp>
0036 #include <boost/geometry/algorithms/detail/overlay/pointlike_areal.hpp>
0037 #include <boost/geometry/algorithms/detail/overlay/pointlike_linear.hpp>
0038 #include <boost/geometry/algorithms/detail/overlay/pointlike_pointlike.hpp>
0039 #include <boost/geometry/algorithms/detail/overlay/range_in_geometry.hpp>
0040 #include <boost/geometry/algorithms/detail/overlay/segment_as_subrange.hpp>
0041
0042 #include <boost/geometry/core/point_order.hpp>
0043 #include <boost/geometry/core/reverse_dispatch.hpp>
0044 #include <boost/geometry/core/static_assert.hpp>
0045 #include <boost/geometry/core/tag_cast.hpp>
0046
0047 #include <boost/geometry/geometries/concepts/check.hpp>
0048
0049 #include <boost/geometry/strategies/default_strategy.hpp>
0050 #include <boost/geometry/strategies/detail.hpp>
0051 #include <boost/geometry/strategies/relate/services.hpp>
0052
0053 #include <boost/geometry/views/segment_view.hpp>
0054 #include <boost/geometry/views/detail/boundary_view.hpp>
0055
0056 #if defined(BOOST_GEOMETRY_DEBUG_FOLLOW)
0057 #include <boost/geometry/algorithms/detail/overlay/debug_turn_info.hpp>
0058 #include <boost/geometry/io/wkt/wkt.hpp>
0059 #include <boost/geometry/views/enumerate_view.hpp>
0060 #endif
0061
0062 namespace boost { namespace geometry
0063 {
0064
0065 #ifndef DOXYGEN_NO_DETAIL
0066 namespace detail { namespace intersection
0067 {
0068
0069 template <typename PointOut>
0070 struct intersection_segment_segment_point
0071 {
0072 template
0073 <
0074 typename Segment1, typename Segment2,
0075 typename OutputIterator, typename Strategy
0076 >
0077 static inline OutputIterator apply(Segment1 const& segment1,
0078 Segment2 const& segment2,
0079 OutputIterator out,
0080 Strategy const& strategy)
0081 {
0082 using point_type = point_type_t<PointOut>;
0083 using intersection_return_type = segment_intersection_points<point_type>;
0084 using policy_type = policies::relate::segments_intersection_points
0085 <
0086 intersection_return_type
0087 >;
0088
0089
0090 detail::segment_as_subrange<Segment1> sub_range1(segment1);
0091 detail::segment_as_subrange<Segment2> sub_range2(segment2);
0092
0093 intersection_return_type
0094 is = strategy.relate().apply(sub_range1, sub_range2, policy_type());
0095
0096 for (std::size_t i = 0; i < is.count; i++)
0097 {
0098 PointOut p;
0099 geometry::convert(is.intersections[i], p);
0100 *out++ = p;
0101 }
0102 return out;
0103 }
0104 };
0105
0106 template <typename PointOut>
0107 struct intersection_linestring_linestring_point
0108 {
0109 template
0110 <
0111 typename Linestring1, typename Linestring2,
0112 typename OutputIterator,
0113 typename Strategy
0114 >
0115 static inline OutputIterator apply(Linestring1 const& linestring1,
0116 Linestring2 const& linestring2,
0117 OutputIterator out,
0118 Strategy const& strategy)
0119 {
0120 using turn_info = detail::overlay::turn_info<PointOut>;
0121 std::deque<turn_info> turns;
0122
0123 geometry::get_intersection_points(linestring1, linestring2,
0124 turns, strategy);
0125
0126 for (auto const& turn : turns)
0127 {
0128 PointOut p;
0129 geometry::convert(turn.point, p);
0130 *out++ = p;
0131 }
0132 return out;
0133 }
0134 };
0135
0136
0137
0138
0139 template
0140 <
0141 bool ReverseAreal,
0142 typename GeometryOut,
0143 overlay_type OverlayType,
0144 bool FollowIsolatedPoints
0145 >
0146 struct intersection_of_linestring_with_areal
0147 {
0148 #if defined(BOOST_GEOMETRY_DEBUG_FOLLOW)
0149 template <typename Turn, typename Operation>
0150 static inline void debug_follow(Turn const& turn, Operation op,
0151 int index)
0152 {
0153 std::cout << index
0154 << " at " << op.seg_id
0155 << " meth: " << method_char(turn.method)
0156 << " op: " << operation_char(op.operation)
0157 << " vis: " << visited_char(op.visited)
0158 << " of: " << operation_char(turn.operations[0].operation)
0159 << operation_char(turn.operations[1].operation)
0160 << " " << geometry::wkt(turn.point)
0161 << std::endl;
0162 }
0163
0164 template <typename Turn>
0165 static inline void debug_turn(Turn const& t, bool non_crossing)
0166 {
0167 std::cout << "checking turn @"
0168 << geometry::wkt(t.point)
0169 << "; " << method_char(t.method)
0170 << ":" << operation_char(t.operations[0].operation)
0171 << "/" << operation_char(t.operations[1].operation)
0172 << "; non-crossing? "
0173 << std::boolalpha << non_crossing << std::noboolalpha
0174 << std::endl;
0175 }
0176 #endif
0177
0178 template <typename Linestring, typename Areal, typename Strategy, typename Turns>
0179 static inline bool simple_turns_analysis(Linestring const& linestring,
0180 Areal const& areal,
0181 Strategy const& strategy,
0182 Turns const& turns,
0183 int & inside_value)
0184 {
0185 using namespace overlay;
0186
0187 bool found_continue = false;
0188 bool found_intersection = false;
0189 bool found_union = false;
0190 bool found_front = false;
0191
0192 for (auto const& turn : turns)
0193 {
0194 method_type const method = turn.method;
0195 operation_type const op = turn.operations[0].operation;
0196
0197 if (method == method_crosses)
0198 {
0199 return false;
0200 }
0201 else if (op == operation_intersection)
0202 {
0203 found_intersection = true;
0204 }
0205 else if (op == operation_union)
0206 {
0207 found_union = true;
0208 }
0209 else if (op == operation_continue)
0210 {
0211 found_continue = true;
0212 }
0213
0214 if ((found_intersection || found_continue) && found_union)
0215 {
0216 return false;
0217 }
0218
0219 if (turn.operations[0].position == position_front)
0220 {
0221 found_front = true;
0222 }
0223 }
0224
0225 if (found_front)
0226 {
0227 if (found_intersection)
0228 {
0229 inside_value = 1;
0230 }
0231 else if (found_union)
0232 {
0233 inside_value = -1;
0234 }
0235 else
0236 {
0237 inside_value = 0;
0238 }
0239 return true;
0240 }
0241
0242
0243
0244
0245
0246 inside_value = range_in_geometry(linestring, areal, strategy);
0247
0248 if ( (found_intersection && inside_value == -1)
0249 || (found_continue && inside_value == -1)
0250 || (found_union && inside_value == 1) )
0251 {
0252 return false;
0253 }
0254
0255 return true;
0256 }
0257
0258 template
0259 <
0260 typename LineString, typename Areal,
0261 typename OutputIterator, typename Strategy
0262 >
0263 static inline OutputIterator apply(LineString const& linestring, Areal const& areal,
0264 OutputIterator out,
0265 Strategy const& strategy)
0266 {
0267 if (boost::size(linestring) == 0)
0268 {
0269 return out;
0270 }
0271
0272 using follower = detail::overlay::follow
0273 <
0274 GeometryOut,
0275 LineString,
0276 Areal,
0277 OverlayType,
0278 false,
0279 FollowIsolatedPoints
0280 >;
0281
0282 using linear = typename geometry::detail::output_geometry_access
0283 <
0284 GeometryOut, linestring_tag, linestring_tag
0285 >;
0286
0287 using point_type = point_type_t<typename linear::type>;
0288
0289 using ratio_type = geometry::segment_ratio
0290 <
0291 coordinate_type_t<point_type>
0292 >;
0293
0294 using turn_info = detail::overlay::turn_info
0295 <
0296 point_type,
0297 ratio_type,
0298 detail::overlay::turn_operation_linear
0299 <
0300 point_type,
0301 ratio_type
0302 >
0303 >;
0304
0305 std::deque<turn_info> turns;
0306
0307 detail::get_turns::no_interrupt_policy policy;
0308
0309 using turn_policy = detail::overlay::get_turn_info_linear_areal
0310 <
0311 detail::overlay::assign_null_policy
0312 >;
0313
0314 dispatch::get_turns
0315 <
0316 geometry::tag_t<LineString>,
0317 geometry::tag_t<Areal>,
0318 LineString,
0319 Areal,
0320 false,
0321 (OverlayType == overlay_intersection ? ReverseAreal : !ReverseAreal),
0322 turn_policy
0323 >::apply(0, linestring, 1, areal,
0324 strategy,
0325 turns, policy);
0326
0327 int inside_value = 0;
0328 if (simple_turns_analysis(linestring, areal, strategy, turns, inside_value))
0329 {
0330
0331
0332
0333
0334
0335
0336 if (follower::included(inside_value))
0337 {
0338 typename linear::type copy;
0339 geometry::convert(linestring, copy);
0340 *linear::get(out)++ = copy;
0341 }
0342
0343 return out;
0344 }
0345
0346 #if defined(BOOST_GEOMETRY_DEBUG_FOLLOW)
0347 for (auto const& item : util::enumerate(turns))
0348 {
0349 auto const& turn = item.value;
0350 debug_follow(turn, turn.operations[0], item.index);
0351 }
0352 #endif
0353
0354 return follower::apply
0355 (
0356 linestring, areal,
0357 geometry::detail::overlay::operation_intersection,
0358 turns, out, strategy
0359 );
0360 }
0361 };
0362
0363
0364 template <typename Turns, typename OutputIterator>
0365 inline OutputIterator intersection_output_turn_points(Turns const& turns,
0366 OutputIterator out)
0367 {
0368 for (auto const& turn : turns)
0369 {
0370 *out++ = turn.point;
0371 }
0372
0373 return out;
0374 }
0375
0376 template <typename PointOut>
0377 struct intersection_areal_areal_point
0378 {
0379 template
0380 <
0381 typename Geometry1, typename Geometry2,
0382 typename OutputIterator,
0383 typename Strategy
0384 >
0385 static inline OutputIterator apply(Geometry1 const& geometry1,
0386 Geometry2 const& geometry2,
0387 OutputIterator out,
0388 Strategy const& strategy)
0389 {
0390 using turn_info = detail::overlay::turn_info
0391 <
0392 PointOut,
0393 typename segment_ratio_type<PointOut>::type
0394 >;
0395 std::vector<turn_info> turns;
0396
0397 detail::get_turns::no_interrupt_policy policy;
0398
0399 geometry::get_turns
0400 <
0401 false, false, detail::overlay::assign_null_policy
0402 >(geometry1, geometry2, strategy, turns, policy);
0403
0404 return intersection_output_turn_points(turns, out);
0405 }
0406 };
0407
0408 template <typename PointOut>
0409 struct intersection_linear_areal_point
0410 {
0411 template
0412 <
0413 typename Geometry1, typename Geometry2,
0414 typename OutputIterator,
0415 typename Strategy
0416 >
0417 static inline OutputIterator apply(Geometry1 const& geometry1,
0418 Geometry2 const& geometry2,
0419 OutputIterator out,
0420 Strategy const& strategy)
0421 {
0422 using ratio_type = geometry::segment_ratio<geometry::coordinate_type_t<PointOut>>;
0423
0424 using turn_info = detail::overlay::turn_info
0425 <
0426 PointOut,
0427 ratio_type,
0428 detail::overlay::turn_operation_linear
0429 <
0430 PointOut,
0431 ratio_type
0432 >
0433 >;
0434
0435 using turn_policy = detail::overlay::get_turn_info_linear_areal
0436 <
0437 detail::overlay::assign_null_policy
0438 >;
0439
0440 std::vector<turn_info> turns;
0441
0442 detail::get_turns::no_interrupt_policy interrupt_policy;
0443
0444 dispatch::get_turns
0445 <
0446 geometry::tag_t<Geometry1>,
0447 geometry::tag_t<Geometry2>,
0448 Geometry1,
0449 Geometry2,
0450 false,
0451 false,
0452 turn_policy
0453 >::apply(0, geometry1, 1, geometry2,
0454 strategy,
0455 turns, interrupt_policy);
0456
0457 return intersection_output_turn_points(turns, out);
0458 }
0459 };
0460
0461 template <typename PointOut>
0462 struct intersection_areal_linear_point
0463 {
0464 template
0465 <
0466 typename Geometry1, typename Geometry2,
0467 typename OutputIterator,
0468 typename Strategy
0469 >
0470 static inline OutputIterator apply(Geometry1 const& geometry1,
0471 Geometry2 const& geometry2,
0472 OutputIterator out,
0473 Strategy const& strategy)
0474 {
0475 return intersection_linear_areal_point
0476 <
0477 PointOut
0478 >::apply(geometry2, geometry1, out, strategy);
0479 }
0480 };
0481
0482
0483 }}
0484 #endif
0485
0486
0487
0488 #ifndef DOXYGEN_NO_DISPATCH
0489 namespace dispatch
0490 {
0491
0492 template
0493 <
0494
0495 typename Geometry1,
0496 typename Geometry2,
0497 typename GeometryOut,
0498 overlay_type OverlayType,
0499
0500 bool Reverse1 = detail::overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
0501 bool Reverse2 = detail::overlay::do_reverse<geometry::point_order<Geometry2>::value>::value,
0502
0503 typename TagIn1 = tag_t<Geometry1>,
0504 typename TagIn2 = tag_t<Geometry2>,
0505 typename TagOut = typename detail::setop_insert_output_tag<GeometryOut>::type,
0506
0507 typename CastedTagIn1 = tag_cast_t<TagIn1, areal_tag, linear_tag, pointlike_tag>,
0508 typename CastedTagIn2 = tag_cast_t<TagIn2, areal_tag, linear_tag, pointlike_tag>,
0509 typename CastedTagOut = tag_cast_t<TagOut, areal_tag, linear_tag, pointlike_tag>
0510 >
0511 struct intersection_insert
0512 {
0513 BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
0514 "Not or not yet implemented for these Geometry types or their order.",
0515 Geometry1, Geometry2, GeometryOut,
0516 std::integral_constant<overlay_type, OverlayType>);
0517 };
0518
0519
0520 template
0521 <
0522 typename Geometry1, typename Geometry2,
0523 typename GeometryOut,
0524 overlay_type OverlayType,
0525 bool Reverse1, bool Reverse2,
0526 typename TagIn1, typename TagIn2, typename TagOut
0527 >
0528 struct intersection_insert
0529 <
0530 Geometry1, Geometry2,
0531 GeometryOut,
0532 OverlayType,
0533 Reverse1, Reverse2,
0534 TagIn1, TagIn2, TagOut,
0535 areal_tag, areal_tag, areal_tag
0536 > : detail::overlay::overlay
0537 <
0538 Geometry1, Geometry2, Reverse1, Reverse2,
0539 detail::overlay::do_reverse<geometry::point_order<GeometryOut>::value>::value,
0540 GeometryOut, OverlayType
0541 >
0542 {};
0543
0544
0545
0546 template
0547 <
0548 typename Geometry, typename Box,
0549 typename GeometryOut,
0550 overlay_type OverlayType,
0551 bool Reverse1, bool Reverse2,
0552 typename TagIn, typename TagOut
0553 >
0554 struct intersection_insert
0555 <
0556 Geometry, Box,
0557 GeometryOut,
0558 OverlayType,
0559 Reverse1, Reverse2,
0560 TagIn, box_tag, TagOut,
0561 areal_tag, areal_tag, areal_tag
0562 > : detail::overlay::overlay
0563 <
0564 Geometry, Box, Reverse1, Reverse2,
0565 detail::overlay::do_reverse<geometry::point_order<GeometryOut>::value>::value,
0566 GeometryOut, OverlayType
0567 >
0568 {};
0569
0570
0571 template
0572 <
0573 typename Segment1, typename Segment2,
0574 typename GeometryOut,
0575 overlay_type OverlayType,
0576 bool Reverse1, bool Reverse2
0577 >
0578 struct intersection_insert
0579 <
0580 Segment1, Segment2,
0581 GeometryOut,
0582 OverlayType,
0583 Reverse1, Reverse2,
0584 segment_tag, segment_tag, point_tag,
0585 linear_tag, linear_tag, pointlike_tag
0586 > : detail::intersection::intersection_segment_segment_point<GeometryOut>
0587 {};
0588
0589
0590 template
0591 <
0592 typename Linestring1, typename Linestring2,
0593 typename GeometryOut,
0594 overlay_type OverlayType,
0595 bool Reverse1, bool Reverse2
0596 >
0597 struct intersection_insert
0598 <
0599 Linestring1, Linestring2,
0600 GeometryOut,
0601 OverlayType,
0602 Reverse1, Reverse2,
0603 linestring_tag, linestring_tag, point_tag,
0604 linear_tag, linear_tag, pointlike_tag
0605 > : detail::intersection::intersection_linestring_linestring_point<GeometryOut>
0606 {};
0607
0608
0609 template
0610 <
0611 typename Linestring, typename Box,
0612 typename GeometryOut,
0613 bool Reverse1, bool Reverse2
0614 >
0615 struct intersection_insert
0616 <
0617 Linestring, Box,
0618 GeometryOut,
0619 overlay_intersection,
0620 Reverse1, Reverse2,
0621 linestring_tag, box_tag, linestring_tag,
0622 linear_tag, areal_tag, linear_tag
0623 >
0624 {
0625 template <typename OutputIterator, typename Strategy>
0626 static inline OutputIterator apply(Linestring const& linestring,
0627 Box const& box,
0628 OutputIterator out, Strategy const& )
0629 {
0630 strategy::intersection::liang_barsky<Box, point_type_t<GeometryOut>> lb_strategy;
0631 return detail::intersection::clip_range_with_box
0632 <GeometryOut>(box, linestring, out, lb_strategy);
0633 }
0634 };
0635
0636
0637 template
0638 <
0639 typename Linestring, typename Polygon,
0640 typename GeometryOut,
0641 overlay_type OverlayType,
0642 bool ReverseLinestring, bool ReversePolygon
0643 >
0644 struct intersection_insert
0645 <
0646 Linestring, Polygon,
0647 GeometryOut,
0648 OverlayType,
0649 ReverseLinestring, ReversePolygon,
0650 linestring_tag, polygon_tag, linestring_tag,
0651 linear_tag, areal_tag, linear_tag
0652 > : detail::intersection::intersection_of_linestring_with_areal
0653 <
0654 ReversePolygon,
0655 GeometryOut,
0656 OverlayType,
0657 false
0658 >
0659 {};
0660
0661
0662 template
0663 <
0664 typename Linestring, typename Ring,
0665 typename GeometryOut,
0666 overlay_type OverlayType,
0667 bool ReverseLinestring, bool ReverseRing
0668 >
0669 struct intersection_insert
0670 <
0671 Linestring, Ring,
0672 GeometryOut,
0673 OverlayType,
0674 ReverseLinestring, ReverseRing,
0675 linestring_tag, ring_tag, linestring_tag,
0676 linear_tag, areal_tag, linear_tag
0677 > : detail::intersection::intersection_of_linestring_with_areal
0678 <
0679 ReverseRing,
0680 GeometryOut,
0681 OverlayType,
0682 false
0683 >
0684 {};
0685
0686 template
0687 <
0688 typename Segment, typename Box,
0689 typename GeometryOut,
0690 overlay_type OverlayType,
0691 bool Reverse1, bool Reverse2
0692 >
0693 struct intersection_insert
0694 <
0695 Segment, Box,
0696 GeometryOut,
0697 OverlayType,
0698 Reverse1, Reverse2,
0699 segment_tag, box_tag, linestring_tag,
0700 linear_tag, areal_tag, linear_tag
0701 >
0702 {
0703 template <typename OutputIterator, typename Strategy>
0704 static inline OutputIterator apply(Segment const& segment,
0705 Box const& box,
0706 OutputIterator out, Strategy const& )
0707 {
0708 geometry::segment_view<Segment> range(segment);
0709
0710 strategy::intersection::liang_barsky<Box, point_type_t<GeometryOut>> lb_strategy;
0711 return detail::intersection::clip_range_with_box
0712 <GeometryOut>(box, range, out, lb_strategy);
0713 }
0714 };
0715
0716 template
0717 <
0718 typename Geometry1, typename Geometry2,
0719 typename PointOut,
0720 overlay_type OverlayType,
0721 bool Reverse1, bool Reverse2,
0722 typename Tag1, typename Tag2
0723 >
0724 struct intersection_insert
0725 <
0726 Geometry1, Geometry2,
0727 PointOut,
0728 OverlayType,
0729 Reverse1, Reverse2,
0730 Tag1, Tag2, point_tag,
0731 areal_tag, areal_tag, pointlike_tag
0732 >
0733 : public detail::intersection::intersection_areal_areal_point
0734 <
0735 PointOut
0736 >
0737 {};
0738
0739 template
0740 <
0741 typename Geometry1, typename Geometry2,
0742 typename PointOut,
0743 overlay_type OverlayType,
0744 bool Reverse1, bool Reverse2,
0745 typename Tag1, typename Tag2
0746 >
0747 struct intersection_insert
0748 <
0749 Geometry1, Geometry2,
0750 PointOut,
0751 OverlayType,
0752 Reverse1, Reverse2,
0753 Tag1, Tag2, point_tag,
0754 linear_tag, areal_tag, pointlike_tag
0755 >
0756 : public detail::intersection::intersection_linear_areal_point
0757 <
0758 PointOut
0759 >
0760 {};
0761
0762 template
0763 <
0764 typename Geometry1, typename Geometry2,
0765 typename PointOut,
0766 overlay_type OverlayType,
0767 bool Reverse1, bool Reverse2,
0768 typename Tag1, typename Tag2
0769 >
0770 struct intersection_insert
0771 <
0772 Geometry1, Geometry2,
0773 PointOut,
0774 OverlayType,
0775 Reverse1, Reverse2,
0776 Tag1, Tag2, point_tag,
0777 areal_tag, linear_tag, pointlike_tag
0778 >
0779 : public detail::intersection::intersection_areal_linear_point
0780 <
0781 PointOut
0782 >
0783 {};
0784
0785 template
0786 <
0787 typename Geometry1, typename Geometry2, typename GeometryOut,
0788 overlay_type OverlayType,
0789 bool Reverse1, bool Reverse2
0790 >
0791 struct intersection_insert_reversed
0792 {
0793 template <typename OutputIterator, typename Strategy>
0794 static inline OutputIterator apply(Geometry1 const& g1,
0795 Geometry2 const& g2,
0796 OutputIterator out,
0797 Strategy const& strategy)
0798 {
0799 return intersection_insert
0800 <
0801 Geometry2, Geometry1, GeometryOut,
0802 OverlayType,
0803 Reverse2, Reverse1
0804 >::apply(g2, g1, out, strategy);
0805 }
0806 };
0807
0808
0809
0810 template
0811 <
0812 typename Geometry1, typename Geometry2,
0813 typename LinestringOut,
0814 bool Reverse1, bool Reverse2,
0815 typename Tag1, typename Tag2
0816 >
0817 struct intersection_insert
0818 <
0819 Geometry1, Geometry2,
0820 LinestringOut,
0821 overlay_intersection,
0822 Reverse1, Reverse2,
0823 Tag1, Tag2, linestring_tag,
0824 areal_tag, areal_tag, linear_tag
0825 >
0826 {
0827 template
0828 <
0829 typename OutputIterator, typename Strategy
0830 >
0831 static inline OutputIterator apply(Geometry1 const& geometry1,
0832 Geometry2 const& geometry2,
0833 OutputIterator oit,
0834 Strategy const& strategy)
0835 {
0836 detail::boundary_view<Geometry1 const> view1(geometry1);
0837 detail::boundary_view<Geometry2 const> view2(geometry2);
0838
0839 return detail::overlay::linear_linear_linestring
0840 <
0841 detail::boundary_view<Geometry1 const>,
0842 detail::boundary_view<Geometry2 const>,
0843 LinestringOut,
0844 overlay_intersection
0845 >::apply(view1, view2, oit, strategy);
0846 }
0847 };
0848
0849
0850 template
0851 <
0852 typename Linear1, typename Linear2, typename LineStringOut,
0853 overlay_type OverlayType,
0854 bool Reverse1, bool Reverse2,
0855 typename TagIn1, typename TagIn2
0856 >
0857 struct intersection_insert
0858 <
0859 Linear1, Linear2, LineStringOut, OverlayType,
0860 Reverse1, Reverse2,
0861 TagIn1, TagIn2, linestring_tag,
0862 linear_tag, linear_tag, linear_tag
0863 > : detail::overlay::linear_linear_linestring
0864 <
0865 Linear1, Linear2, LineStringOut, OverlayType
0866 >
0867 {};
0868
0869 template
0870 <
0871 typename Linear1, typename Linear2, typename TupledOut,
0872 overlay_type OverlayType,
0873 bool Reverse1, bool Reverse2,
0874 typename TagIn1, typename TagIn2
0875 >
0876 struct intersection_insert
0877 <
0878 Linear1, Linear2, TupledOut, OverlayType,
0879 Reverse1, Reverse2,
0880 TagIn1, TagIn2, detail::tupled_output_tag,
0881 linear_tag, linear_tag, detail::tupled_output_tag
0882 >
0883 : detail::expect_output
0884 <
0885 Linear1, Linear2, TupledOut,
0886
0887 std::conditional_t
0888 <
0889 (OverlayType == overlay_intersection),
0890 point_tag,
0891 void
0892 >,
0893 linestring_tag
0894 >
0895 {
0896
0897
0898 template
0899 <
0900 typename OutputIterators, typename Strategy
0901 >
0902 static inline OutputIterators apply(Linear1 const& linear1,
0903 Linear2 const& linear2,
0904 OutputIterators oit,
0905 Strategy const& strategy)
0906 {
0907 return detail::overlay::linear_linear_linestring
0908 <
0909 Linear1, Linear2, TupledOut, OverlayType
0910 >::apply(linear1, linear2, oit, strategy);
0911 }
0912 };
0913
0914
0915
0916
0917 template
0918 <
0919 typename Point1, typename Point2, typename PointOut,
0920 overlay_type OverlayType,
0921 bool Reverse1, bool Reverse2
0922 >
0923 struct intersection_insert
0924 <
0925 Point1, Point2, PointOut, OverlayType,
0926 Reverse1, Reverse2,
0927 point_tag, point_tag, point_tag,
0928 pointlike_tag, pointlike_tag, pointlike_tag
0929 > : detail::overlay::point_point_point
0930 <
0931 Point1, Point2, PointOut, OverlayType
0932 >
0933 {};
0934
0935
0936 template
0937 <
0938 typename MultiPoint, typename Point, typename PointOut,
0939 overlay_type OverlayType,
0940 bool Reverse1, bool Reverse2
0941 >
0942 struct intersection_insert
0943 <
0944 MultiPoint, Point, PointOut, OverlayType,
0945 Reverse1, Reverse2,
0946 multi_point_tag, point_tag, point_tag,
0947 pointlike_tag, pointlike_tag, pointlike_tag
0948 > : detail::overlay::multipoint_point_point
0949 <
0950 MultiPoint, Point, PointOut, OverlayType
0951 >
0952 {};
0953
0954
0955 template
0956 <
0957 typename Point, typename MultiPoint, typename PointOut,
0958 overlay_type OverlayType,
0959 bool Reverse1, bool Reverse2
0960 >
0961 struct intersection_insert
0962 <
0963 Point, MultiPoint, PointOut, OverlayType,
0964 Reverse1, Reverse2,
0965 point_tag, multi_point_tag, point_tag,
0966 pointlike_tag, pointlike_tag, pointlike_tag
0967 > : detail::overlay::point_multipoint_point
0968 <
0969 Point, MultiPoint, PointOut, OverlayType
0970 >
0971 {};
0972
0973
0974 template
0975 <
0976 typename MultiPoint1, typename MultiPoint2, typename PointOut,
0977 overlay_type OverlayType,
0978 bool Reverse1, bool Reverse2
0979 >
0980 struct intersection_insert
0981 <
0982 MultiPoint1, MultiPoint2, PointOut, OverlayType,
0983 Reverse1, Reverse2,
0984 multi_point_tag, multi_point_tag, point_tag,
0985 pointlike_tag, pointlike_tag, pointlike_tag
0986 > : detail::overlay::multipoint_multipoint_point
0987 <
0988 MultiPoint1, MultiPoint2, PointOut, OverlayType
0989 >
0990 {};
0991
0992
0993 template
0994 <
0995 typename PointLike1, typename PointLike2, typename TupledOut,
0996 overlay_type OverlayType,
0997 bool Reverse1, bool Reverse2,
0998 typename TagIn1, typename TagIn2
0999 >
1000 struct intersection_insert
1001 <
1002 PointLike1, PointLike2, TupledOut, OverlayType,
1003 Reverse1, Reverse2,
1004 TagIn1, TagIn2, detail::tupled_output_tag,
1005 pointlike_tag, pointlike_tag, detail::tupled_output_tag
1006 >
1007 : detail::expect_output<PointLike1, PointLike2, TupledOut, point_tag>
1008 {
1009
1010
1011 template
1012 <
1013 typename OutputIterators, typename Strategy
1014 >
1015 static inline OutputIterators apply(PointLike1 const& pointlike1,
1016 PointLike2 const& pointlike2,
1017 OutputIterators oits,
1018 Strategy const& strategy)
1019 {
1020 namespace bgt = boost::geometry::tuples;
1021
1022 static const bool out_point_index = bgt::find_index_if
1023 <
1024 TupledOut, geometry::detail::is_tag_same_as_pred<point_tag>::template pred
1025 >::value;
1026
1027 bgt::get<out_point_index>(oits) = intersection_insert
1028 <
1029 PointLike1, PointLike2,
1030 typename bgt::element
1031 <
1032 out_point_index, TupledOut
1033 >::type,
1034 OverlayType
1035 >::apply(pointlike1, pointlike2,
1036 bgt::get<out_point_index>(oits),
1037 strategy);
1038
1039 return oits;
1040 }
1041 };
1042
1043
1044
1045 template
1046 <
1047 typename Point, typename Linear, typename PointOut,
1048 overlay_type OverlayType,
1049 bool Reverse1, bool Reverse2,
1050 typename Tag
1051 >
1052 struct intersection_insert
1053 <
1054 Point, Linear, PointOut, OverlayType,
1055 Reverse1, Reverse2,
1056 point_tag, Tag, point_tag,
1057 pointlike_tag, linear_tag, pointlike_tag
1058 > : detail_dispatch::overlay::pointlike_linear_point
1059 <
1060 Point, Linear, PointOut, OverlayType,
1061 point_tag, tag_cast_t<Tag, segment_tag, linear_tag>
1062 >
1063 {};
1064
1065
1066 template
1067 <
1068 typename MultiPoint, typename Linear, typename PointOut,
1069 overlay_type OverlayType,
1070 bool Reverse1, bool Reverse2,
1071 typename Tag
1072 >
1073 struct intersection_insert
1074 <
1075 MultiPoint, Linear, PointOut, OverlayType,
1076 Reverse1, Reverse2,
1077 multi_point_tag, Tag, point_tag,
1078 pointlike_tag, linear_tag, pointlike_tag
1079 > : detail_dispatch::overlay::pointlike_linear_point
1080 <
1081 MultiPoint, Linear, PointOut, OverlayType,
1082 multi_point_tag,
1083 tag_cast_t<Tag, segment_tag, linear_tag>
1084 >
1085 {};
1086
1087
1088
1089
1090 template
1091 <
1092 typename Linestring, typename MultiPoint, typename PointOut,
1093 bool Reverse1, bool Reverse2
1094 >
1095 struct intersection_insert
1096 <
1097 Linestring, MultiPoint, PointOut, overlay_intersection,
1098 Reverse1, Reverse2,
1099 linestring_tag, multi_point_tag, point_tag,
1100 linear_tag, pointlike_tag, pointlike_tag
1101 >
1102 {
1103 template <typename OutputIterator, typename Strategy>
1104 static inline OutputIterator apply(Linestring const& linestring,
1105 MultiPoint const& multipoint,
1106 OutputIterator out,
1107 Strategy const& strategy)
1108 {
1109 return detail_dispatch::overlay::pointlike_linear_point
1110 <
1111 MultiPoint, Linestring, PointOut, overlay_intersection,
1112 multi_point_tag, linear_tag
1113 >::apply(multipoint, linestring, out, strategy);
1114 }
1115 };
1116
1117
1118 template
1119 <
1120 typename PointLike, typename Linear, typename TupledOut,
1121 overlay_type OverlayType,
1122 bool Reverse1, bool Reverse2,
1123 typename TagIn1, typename TagIn2
1124 >
1125 struct intersection_insert
1126 <
1127 PointLike, Linear, TupledOut, OverlayType,
1128 Reverse1, Reverse2,
1129 TagIn1, TagIn2, detail::tupled_output_tag,
1130 pointlike_tag, linear_tag, detail::tupled_output_tag
1131 >
1132
1133 : intersection_insert
1134 <
1135 PointLike, Linear, TupledOut, OverlayType,
1136 Reverse1, Reverse2,
1137 TagIn1, TagIn2, detail::tupled_output_tag,
1138 pointlike_tag, pointlike_tag, detail::tupled_output_tag
1139 >
1140 {};
1141
1142
1143
1144
1145 template
1146 <
1147 typename Linestring, typename MultiPoint, typename TupledOut,
1148 bool Reverse1, bool Reverse2
1149 >
1150 struct intersection_insert
1151 <
1152 Linestring, MultiPoint, TupledOut, overlay_intersection,
1153 Reverse1, Reverse2,
1154 linestring_tag, multi_point_tag, detail::tupled_output_tag,
1155 linear_tag, pointlike_tag, detail::tupled_output_tag
1156 >
1157 {
1158 template <typename OutputIterators, typename Strategy>
1159 static inline OutputIterators apply(Linestring const& linestring,
1160 MultiPoint const& multipoint,
1161 OutputIterators out,
1162 Strategy const& strategy)
1163 {
1164 return intersection_insert
1165 <
1166 MultiPoint, Linestring, TupledOut, overlay_intersection
1167 >::apply(multipoint, linestring, out, strategy);
1168 }
1169 };
1170
1171
1172
1173 template
1174 <
1175 typename Point, typename Areal, typename PointOut,
1176 overlay_type OverlayType,
1177 bool Reverse1, bool Reverse2,
1178 typename ArealTag
1179 >
1180 struct intersection_insert
1181 <
1182 Point, Areal, PointOut, OverlayType,
1183 Reverse1, Reverse2,
1184 point_tag, ArealTag, point_tag,
1185 pointlike_tag, areal_tag, pointlike_tag
1186 > : detail_dispatch::overlay::pointlike_areal_point
1187 <
1188 Point, Areal, PointOut, OverlayType,
1189 point_tag, ArealTag
1190 >
1191 {};
1192
1193 template
1194 <
1195 typename MultiPoint, typename Areal, typename PointOut,
1196 overlay_type OverlayType,
1197 bool Reverse1, bool Reverse2,
1198 typename ArealTag
1199 >
1200 struct intersection_insert
1201 <
1202 MultiPoint, Areal, PointOut, OverlayType,
1203 Reverse1, Reverse2,
1204 multi_point_tag, ArealTag, point_tag,
1205 pointlike_tag, areal_tag, pointlike_tag
1206 > : detail_dispatch::overlay::pointlike_areal_point
1207 <
1208 MultiPoint, Areal, PointOut, OverlayType,
1209 multi_point_tag, ArealTag
1210 >
1211 {};
1212
1213
1214
1215 template
1216 <
1217 typename Areal, typename MultiPoint, typename PointOut,
1218 bool Reverse1, bool Reverse2,
1219 typename ArealTag
1220 >
1221 struct intersection_insert
1222 <
1223 Areal, MultiPoint, PointOut, overlay_intersection,
1224 Reverse1, Reverse2,
1225 ArealTag, multi_point_tag, point_tag,
1226 areal_tag, pointlike_tag, pointlike_tag
1227 >
1228 {
1229 template <typename OutputIterator, typename Strategy>
1230 static inline OutputIterator apply(Areal const& areal,
1231 MultiPoint const& multipoint,
1232 OutputIterator out,
1233 Strategy const& strategy)
1234 {
1235 return detail_dispatch::overlay::pointlike_areal_point
1236 <
1237 MultiPoint, Areal, PointOut, overlay_intersection,
1238 multi_point_tag, ArealTag
1239 >::apply(multipoint, areal, out, strategy);
1240 }
1241 };
1242
1243
1244 template
1245 <
1246 typename PointLike, typename Areal, typename TupledOut,
1247 overlay_type OverlayType,
1248 bool Reverse1, bool Reverse2,
1249 typename TagIn1, typename TagIn2
1250 >
1251 struct intersection_insert
1252 <
1253 PointLike, Areal, TupledOut, OverlayType,
1254 Reverse1, Reverse2,
1255 TagIn1, TagIn2, detail::tupled_output_tag,
1256 pointlike_tag, areal_tag, detail::tupled_output_tag
1257 >
1258
1259 : intersection_insert
1260 <
1261 PointLike, Areal, TupledOut, OverlayType,
1262 Reverse1, Reverse2,
1263 TagIn1, TagIn2, detail::tupled_output_tag,
1264 pointlike_tag, pointlike_tag, detail::tupled_output_tag
1265 >
1266 {};
1267
1268
1269
1270
1271 template
1272 <
1273 typename Areal, typename MultiPoint, typename TupledOut,
1274 bool Reverse1, bool Reverse2,
1275 typename TagIn1
1276 >
1277 struct intersection_insert
1278 <
1279 Areal, MultiPoint, TupledOut, overlay_intersection,
1280 Reverse1, Reverse2,
1281 TagIn1, multi_point_tag, detail::tupled_output_tag,
1282 areal_tag, pointlike_tag, detail::tupled_output_tag
1283 >
1284 {
1285 template <typename OutputIterators, typename Strategy>
1286 static inline OutputIterators apply(Areal const& areal,
1287 MultiPoint const& multipoint,
1288 OutputIterators out,
1289 Strategy const& strategy)
1290 {
1291 return intersection_insert
1292 <
1293 MultiPoint, Areal, TupledOut, overlay_intersection
1294 >::apply(multipoint, areal, out, strategy);
1295 }
1296 };
1297
1298
1299 template
1300 <
1301 typename Linestring, typename Polygon,
1302 typename TupledOut,
1303 overlay_type OverlayType,
1304 bool ReverseLinestring, bool ReversePolygon
1305 >
1306 struct intersection_insert
1307 <
1308 Linestring, Polygon,
1309 TupledOut,
1310 OverlayType,
1311 ReverseLinestring, ReversePolygon,
1312 linestring_tag, polygon_tag, detail::tupled_output_tag,
1313 linear_tag, areal_tag, detail::tupled_output_tag
1314 > : detail::intersection::intersection_of_linestring_with_areal
1315 <
1316 ReversePolygon,
1317 TupledOut,
1318 OverlayType,
1319 true
1320 >
1321 {};
1322
1323 template
1324 <
1325 typename Linestring, typename Ring,
1326 typename TupledOut,
1327 overlay_type OverlayType,
1328 bool ReverseLinestring, bool ReverseRing
1329 >
1330 struct intersection_insert
1331 <
1332 Linestring, Ring,
1333 TupledOut,
1334 OverlayType,
1335 ReverseLinestring, ReverseRing,
1336 linestring_tag, ring_tag, detail::tupled_output_tag,
1337 linear_tag, areal_tag, detail::tupled_output_tag
1338 > : detail::intersection::intersection_of_linestring_with_areal
1339 <
1340 ReverseRing,
1341 TupledOut,
1342 OverlayType,
1343 true
1344 >
1345 {};
1346
1347
1348 }
1349 #endif
1350
1351
1352 #ifndef DOXYGEN_NO_DETAIL
1353 namespace detail { namespace intersection
1354 {
1355
1356
1357 template
1358 <
1359 typename GeometryOut,
1360 bool ReverseSecond,
1361 overlay_type OverlayType,
1362 typename Geometry1, typename Geometry2,
1363 typename OutputIterator,
1364 typename Strategy
1365 >
1366 inline OutputIterator insert(Geometry1 const& geometry1,
1367 Geometry2 const& geometry2,
1368 OutputIterator out,
1369 Strategy const& strategy)
1370 {
1371 return std::conditional_t
1372 <
1373 geometry::reverse_dispatch<Geometry1, Geometry2>::type::value,
1374 geometry::dispatch::intersection_insert_reversed
1375 <
1376 Geometry1, Geometry2,
1377 GeometryOut,
1378 OverlayType,
1379 overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
1380 overlay::do_reverse<geometry::point_order<Geometry2>::value, ReverseSecond>::value
1381 >,
1382 geometry::dispatch::intersection_insert
1383 <
1384 Geometry1, Geometry2,
1385 GeometryOut,
1386 OverlayType,
1387 geometry::detail::overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
1388 geometry::detail::overlay::do_reverse<geometry::point_order<Geometry2>::value, ReverseSecond>::value
1389 >
1390 >::apply(geometry1, geometry2, out, strategy);
1391 }
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413 template
1414 <
1415 typename GeometryOut,
1416 typename Geometry1,
1417 typename Geometry2,
1418 typename OutputIterator,
1419 typename Strategy
1420 >
1421 inline OutputIterator intersection_insert(Geometry1 const& geometry1,
1422 Geometry2 const& geometry2,
1423 OutputIterator out,
1424 Strategy const& strategy)
1425 {
1426 concepts::check<Geometry1 const>();
1427 concepts::check<Geometry2 const>();
1428
1429 return detail::intersection::insert
1430 <
1431 GeometryOut, false, overlay_intersection
1432 >(geometry1, geometry2, out, strategy);
1433 }
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452 template
1453 <
1454 typename GeometryOut,
1455 typename Geometry1,
1456 typename Geometry2,
1457 typename OutputIterator
1458 >
1459 inline OutputIterator intersection_insert(Geometry1 const& geometry1,
1460 Geometry2 const& geometry2,
1461 OutputIterator out)
1462 {
1463 concepts::check<Geometry1 const>();
1464 concepts::check<Geometry2 const>();
1465
1466 using strategy_type = typename strategies::relate::services::default_strategy
1467 <
1468 Geometry1, Geometry2
1469 >::type;
1470
1471 return intersection_insert<GeometryOut>(geometry1, geometry2, out,
1472 strategy_type());
1473 }
1474
1475 }}
1476 #endif
1477
1478
1479
1480 }}
1481
1482
1483 #endif