1 // Boost.Geometry (aka GGL, Generic Geometry Library)
3 // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
5 // This file was modified by Oracle on 2017.
6 // Modifications copyright (c) 2017, Oracle and/or its affiliates.
8 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
10 // Use, modification and distribution is subject to the Boost Software License,
11 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
12 // http://www.boost.org/LICENSE_1_0.txt)
14 #ifndef BOOST_GEOMETRY_ALGORITHMS_DIFFERENCE_HPP
15 #define BOOST_GEOMETRY_ALGORITHMS_DIFFERENCE_HPP
18 #include <boost/variant/apply_visitor.hpp>
19 #include <boost/variant/static_visitor.hpp>
20 #include <boost/variant/variant_fwd.hpp>
22 #include <boost/geometry/algorithms/detail/overlay/intersection_insert.hpp>
23 #include <boost/geometry/policies/robustness/get_rescale_policy.hpp>
24 #include <boost/geometry/strategies/default_strategy.hpp>
25 #include <boost/geometry/util/range.hpp>
28 namespace boost { namespace geometry
31 #ifndef DOXYGEN_NO_DETAIL
32 namespace detail { namespace difference
36 \brief_calc2{difference} \brief_strategy
38 \details \details_calc2{difference_insert, spatial set theoretic difference}
39 \brief_strategy. \details_inserter{difference}
40 \tparam GeometryOut output geometry type, must be specified
41 \tparam Geometry1 \tparam_geometry
42 \tparam Geometry2 \tparam_geometry
43 \tparam OutputIterator output iterator
44 \tparam Strategy \tparam_strategy_overlay
45 \param geometry1 \param_geometry
46 \param geometry2 \param_geometry
47 \param out \param_out{difference}
48 \param strategy \param_strategy{difference}
51 \qbk{distinguish,with strategy}
58 typename RobustPolicy,
59 typename OutputIterator,
62 inline OutputIterator difference_insert(Geometry1 const& geometry1,
63 Geometry2 const& geometry2,
64 RobustPolicy const& robust_policy,
66 Strategy const& strategy)
68 concepts::check<Geometry1 const>();
69 concepts::check<Geometry2 const>();
70 concepts::check<GeometryOut>();
72 return geometry::dispatch::intersection_insert
77 geometry::detail::overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
78 geometry::detail::overlay::do_reverse<geometry::point_order<Geometry2>::value, true>::value
79 >::apply(geometry1, geometry2, robust_policy, out, strategy);
83 \brief_calc2{difference}
85 \details \details_calc2{difference_insert, spatial set theoretic difference}.
86 \details_insert{difference}
87 \tparam GeometryOut output geometry type, must be specified
88 \tparam Geometry1 \tparam_geometry
89 \tparam Geometry2 \tparam_geometry
90 \tparam OutputIterator output iterator
91 \param geometry1 \param_geometry
92 \param geometry2 \param_geometry
93 \param out \param_out{difference}
96 \qbk{[include reference/algorithms/difference_insert.qbk]}
100 typename GeometryOut,
103 typename RobustPolicy,
104 typename OutputIterator
106 inline OutputIterator difference_insert(Geometry1 const& geometry1,
107 Geometry2 const& geometry2,
108 RobustPolicy const& robust_policy,
111 typedef typename strategy::relate::services::default_strategy
115 >::type strategy_type;
117 return difference_insert<GeometryOut>(geometry1, geometry2,
118 robust_policy, out, strategy_type());
122 }} // namespace detail::difference
123 #endif // DOXYGEN_NO_DETAIL
126 namespace resolve_strategy {
134 typename RobustPolicy,
138 static inline void apply(Geometry1 const& geometry1,
139 Geometry2 const& geometry2,
140 RobustPolicy const& robust_policy,
141 Collection & output_collection,
142 Strategy const& strategy)
144 typedef typename boost::range_value<Collection>::type geometry_out;
146 detail::difference::difference_insert<geometry_out>(
147 geometry1, geometry2, robust_policy,
148 range::back_inserter(output_collection),
156 typename RobustPolicy,
159 static inline void apply(Geometry1 const& geometry1,
160 Geometry2 const& geometry2,
161 RobustPolicy const& robust_policy,
162 Collection & output_collection,
165 typedef typename boost::range_value<Collection>::type geometry_out;
167 detail::difference::difference_insert<geometry_out>(
168 geometry1, geometry2, robust_policy,
169 range::back_inserter(output_collection));
173 } // resolve_strategy
176 namespace resolve_variant
179 template <typename Geometry1, typename Geometry2>
182 template <typename Collection, typename Strategy>
183 static inline void apply(Geometry1 const& geometry1,
184 Geometry2 const& geometry2,
185 Collection& output_collection,
186 Strategy const& strategy)
188 typedef typename geometry::rescale_overlay_policy_type
192 >::type rescale_policy_type;
194 rescale_policy_type robust_policy
195 = geometry::get_rescale_policy<rescale_policy_type>(geometry1,
198 resolve_strategy::difference::apply(geometry1, geometry2,
206 template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
207 struct difference<variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
209 template <typename Collection, typename Strategy>
210 struct visitor: static_visitor<>
212 Geometry2 const& m_geometry2;
213 Collection& m_output_collection;
214 Strategy const& m_strategy;
216 visitor(Geometry2 const& geometry2,
217 Collection& output_collection,
218 Strategy const& strategy)
219 : m_geometry2(geometry2)
220 , m_output_collection(output_collection)
221 , m_strategy(strategy)
224 template <typename Geometry1>
225 void operator()(Geometry1 const& geometry1) const
231 >::apply(geometry1, m_geometry2, m_output_collection, m_strategy);
235 template <typename Collection, typename Strategy>
237 apply(variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
238 Geometry2 const& geometry2,
239 Collection& output_collection,
240 Strategy const& strategy)
242 boost::apply_visitor(visitor<Collection, Strategy>(geometry2,
250 template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
251 struct difference<Geometry1, variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
253 template <typename Collection, typename Strategy>
254 struct visitor: static_visitor<>
256 Geometry1 const& m_geometry1;
257 Collection& m_output_collection;
258 Strategy const& m_strategy;
260 visitor(Geometry1 const& geometry1,
261 Collection& output_collection,
262 Strategy const& strategy)
263 : m_geometry1(geometry1)
264 , m_output_collection(output_collection)
265 , m_strategy(strategy)
268 template <typename Geometry2>
269 void operator()(Geometry2 const& geometry2) const
275 >::apply(m_geometry1, geometry2, m_output_collection, m_strategy);
279 template <typename Collection, typename Strategy>
281 apply(Geometry1 const& geometry1,
282 variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2,
283 Collection& output_collection,
284 Strategy const& strategy)
286 boost::apply_visitor(visitor<Collection, Strategy>(geometry1,
294 template <BOOST_VARIANT_ENUM_PARAMS(typename T1), BOOST_VARIANT_ENUM_PARAMS(typename T2)>
295 struct difference<variant<BOOST_VARIANT_ENUM_PARAMS(T1)>, variant<BOOST_VARIANT_ENUM_PARAMS(T2)> >
297 template <typename Collection, typename Strategy>
298 struct visitor: static_visitor<>
300 Collection& m_output_collection;
301 Strategy const& m_strategy;
303 visitor(Collection& output_collection, Strategy const& strategy)
304 : m_output_collection(output_collection)
305 , m_strategy(strategy)
308 template <typename Geometry1, typename Geometry2>
309 void operator()(Geometry1 const& geometry1,
310 Geometry2 const& geometry2) const
316 >::apply(geometry1, geometry2, m_output_collection, m_strategy);
320 template <typename Collection, typename Strategy>
322 apply(variant<BOOST_VARIANT_ENUM_PARAMS(T1)> const& geometry1,
323 variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2,
324 Collection& output_collection,
325 Strategy const& strategy)
327 boost::apply_visitor(visitor<Collection, Strategy>(output_collection,
329 geometry1, geometry2);
333 } // namespace resolve_variant
337 \brief_calc2{difference}
339 \details \details_calc2{difference, spatial set theoretic difference}.
340 \tparam Geometry1 \tparam_geometry
341 \tparam Geometry2 \tparam_geometry
342 \tparam Collection \tparam_output_collection
343 \tparam Strategy \tparam_strategy{Difference}
344 \param geometry1 \param_geometry
345 \param geometry2 \param_geometry
346 \param output_collection the output collection
347 \param strategy \param_strategy{difference}
349 \qbk{distinguish,with strategy}
350 \qbk{[include reference/algorithms/difference.qbk]}
359 inline void difference(Geometry1 const& geometry1,
360 Geometry2 const& geometry2,
361 Collection& output_collection,
362 Strategy const& strategy)
364 resolve_variant::difference
368 >::apply(geometry1, geometry2, output_collection, strategy);
373 \brief_calc2{difference}
375 \details \details_calc2{difference, spatial set theoretic difference}.
376 \tparam Geometry1 \tparam_geometry
377 \tparam Geometry2 \tparam_geometry
378 \tparam Collection \tparam_output_collection
379 \param geometry1 \param_geometry
380 \param geometry2 \param_geometry
381 \param output_collection the output collection
383 \qbk{[include reference/algorithms/difference.qbk]}
391 inline void difference(Geometry1 const& geometry1,
392 Geometry2 const& geometry2,
393 Collection& output_collection)
395 resolve_variant::difference
399 >::apply(geometry1, geometry2, output_collection, default_strategy());
403 }} // namespace boost::geometry
406 #endif // BOOST_GEOMETRY_ALGORITHMS_DIFFERENCE_HPP