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