22
33// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
44
5- // This file was modified by Oracle on 2017, 2019.
6- // Modifications copyright (c) 2017, 2019 , Oracle and/or its affiliates.
5+ // This file was modified by Oracle on 2017, 2019, 2020 .
6+ // Modifications copyright (c) 2017-2020 , Oracle and/or its affiliates.
77
88// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
99
1919#include < boost/variant/static_visitor.hpp>
2020#include < boost/variant/variant_fwd.hpp>
2121
22+ #include < boost/geometry/algorithms/detail/intersection/multi.hpp>
2223#include < boost/geometry/algorithms/detail/overlay/intersection_insert.hpp>
2324#include < boost/geometry/policies/robustness/get_rescale_policy.hpp>
2425#include < boost/geometry/strategies/default_strategy.hpp>
@@ -32,6 +33,146 @@ namespace boost { namespace geometry
3233namespace detail { namespace difference
3334{
3435
36+ template
37+ <
38+ typename Geometry1,
39+ typename Geometry2,
40+ typename SingleOut,
41+ typename OutTag = typename detail::setop_insert_output_tag<SingleOut>::type,
42+ bool ReturnGeometry1 = (topological_dimension<Geometry1>::value
43+ > topological_dimension<Geometry2>::value)
44+ >
45+ struct call_intersection_insert
46+ {
47+ template
48+ <
49+ typename OutputIterator,
50+ typename RobustPolicy,
51+ typename Strategy
52+ >
53+ static inline OutputIterator apply (Geometry1 const & geometry1,
54+ Geometry2 const & geometry2,
55+ RobustPolicy const & robust_policy,
56+ OutputIterator out,
57+ Strategy const & strategy)
58+ {
59+ return geometry::dispatch::intersection_insert
60+ <
61+ Geometry1, Geometry2,
62+ SingleOut,
63+ overlay_difference,
64+ geometry::detail::overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
65+ geometry::detail::overlay::do_reverse<geometry::point_order<Geometry2>::value, true >::value
66+ >::apply (geometry1, geometry2, robust_policy, out, strategy);
67+ }
68+ };
69+
70+ template
71+ <
72+ typename Geometry1,
73+ typename Geometry2,
74+ typename SingleOut
75+ >
76+ struct call_intersection_insert_tupled_base
77+ {
78+ typedef typename geometry::detail::casted_tag_to_single_tag
79+ <
80+ typename geometry::tag_cast
81+ <
82+ typename geometry::tag<Geometry1>::type,
83+ pointlike_tag, linear_tag, areal_tag
84+ >::type
85+ >::type single_tag;
86+
87+ typedef detail::expect_output
88+ <
89+ Geometry1, Geometry2, SingleOut, single_tag
90+ > expect_check;
91+
92+ typedef typename geometry::detail::output_geometry_access
93+ <
94+ SingleOut, single_tag, single_tag
95+ > access;
96+ };
97+
98+ template
99+ <
100+ typename Geometry1,
101+ typename Geometry2,
102+ typename SingleOut
103+ >
104+ struct call_intersection_insert
105+ <
106+ Geometry1, Geometry2, SingleOut,
107+ detail::tupled_output_tag,
108+ false
109+ >
110+ : call_intersection_insert_tupled_base<Geometry1, Geometry2, SingleOut>
111+ {
112+ typedef call_intersection_insert_tupled_base<Geometry1, Geometry2, SingleOut> base_t ;
113+
114+ template
115+ <
116+ typename OutputIterator,
117+ typename RobustPolicy,
118+ typename Strategy
119+ >
120+ static inline OutputIterator apply (Geometry1 const & geometry1,
121+ Geometry2 const & geometry2,
122+ RobustPolicy const & robust_policy,
123+ OutputIterator out,
124+ Strategy const & strategy)
125+ {
126+ base_t::access::get (out) = call_intersection_insert
127+ <
128+ Geometry1, Geometry2,
129+ typename base_t ::access::type
130+ >::apply (geometry1, geometry2, robust_policy,
131+ base_t::access::get (out), strategy);
132+
133+ return out;
134+ }
135+ };
136+
137+ template
138+ <
139+ typename Geometry1,
140+ typename Geometry2,
141+ typename SingleOut
142+ >
143+ struct call_intersection_insert
144+ <
145+ Geometry1, Geometry2, SingleOut,
146+ detail::tupled_output_tag,
147+ true
148+ >
149+ : call_intersection_insert_tupled_base<Geometry1, Geometry2, SingleOut>
150+ {
151+ typedef call_intersection_insert_tupled_base<Geometry1, Geometry2, SingleOut> base_t ;
152+
153+ template
154+ <
155+ typename OutputIterator,
156+ typename RobustPolicy,
157+ typename Strategy
158+ >
159+ static inline OutputIterator apply (Geometry1 const & geometry1,
160+ Geometry2 const & geometry2,
161+ RobustPolicy const & robust_policy,
162+ OutputIterator out,
163+ Strategy const & strategy)
164+ {
165+ base_t::access::get (out) = geometry::detail::convert_to_output
166+ <
167+ Geometry1,
168+ typename base_t ::access::type
169+ >::apply (geometry1, base_t::access::get (out));
170+
171+ return out;
172+ }
173+ };
174+
175+
35176/* !
36177\brief_calc2{difference} \brief_strategy
37178\ingroup difference
@@ -65,7 +206,8 @@ inline OutputIterator difference_insert(Geometry1 const& geometry1,
65206{
66207 concepts::check<Geometry1 const >();
67208 concepts::check<Geometry2 const >();
68- concepts::check<GeometryOut>();
209+ // concepts::check<GeometryOut>();
210+ geometry::detail::output_geometry_concept_check<GeometryOut>::apply ();
69211
70212 typedef typename geometry::rescale_overlay_policy_type
71213 <
@@ -75,16 +217,12 @@ inline OutputIterator difference_insert(Geometry1 const& geometry1,
75217 >::type rescale_policy_type;
76218
77219 rescale_policy_type robust_policy
78- = geometry::get_rescale_policy<rescale_policy_type>(
79- geometry1, geometry2, strategy);
220+ = geometry::get_rescale_policy<rescale_policy_type>(
221+ geometry1, geometry2, strategy);
80222
81- return geometry::dispatch::intersection_insert
223+ return geometry::detail::difference::call_intersection_insert
82224 <
83- Geometry1, Geometry2,
84- GeometryOut,
85- overlay_difference,
86- geometry::detail::overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
87- geometry::detail::overlay::do_reverse<geometry::point_order<Geometry2>::value, true >::value
225+ Geometry1, Geometry2, GeometryOut
88226 >::apply (geometry1, geometry2, robust_policy, out, strategy);
89227}
90228
@@ -146,11 +284,14 @@ struct difference
146284 Collection & output_collection,
147285 Strategy const & strategy)
148286 {
149- typedef typename boost::range_value<Collection>::type geometry_out;
287+ typedef typename geometry::detail::output_geometry_value
288+ <
289+ Collection
290+ >::type single_out;
150291
151- detail::difference::difference_insert<geometry_out >(
292+ detail::difference::difference_insert<single_out >(
152293 geometry1, geometry2,
153- range::back_inserter (output_collection),
294+ geometry::detail::output_geometry_back_inserter (output_collection),
154295 strategy);
155296 }
156297
@@ -165,11 +306,13 @@ struct difference
165306 Collection & output_collection,
166307 default_strategy)
167308 {
168- typedef typename boost::range_value<Collection>::type geometry_out;
309+ typedef typename strategy::relate::services::default_strategy
310+ <
311+ Geometry1,
312+ Geometry2
313+ >::type strategy_type;
169314
170- detail::difference::difference_insert<geometry_out>(
171- geometry1, geometry2,
172- range::back_inserter (output_collection));
315+ apply (geometry1, geometry2, output_collection, strategy_type ());
173316 }
174317};
175318
0 commit comments