1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2 
3 // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
4 
5 // Use, modification and distribution is subject to the Boost Software License,
6 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
7 // http://www.boost.org/LICENSE_1_0.txt)
8 
9 #ifndef BOOST_GEOMETRY_ALGORITHMS_DIFFERENCE_HPP
10 #define BOOST_GEOMETRY_ALGORITHMS_DIFFERENCE_HPP
11 
12 #include <algorithm>
13 
14 #include <boost/geometry/algorithms/detail/overlay/intersection_insert.hpp>
15 #include <boost/geometry/policies/robustness/get_rescale_policy.hpp>
16 
17 namespace boost { namespace geometry
18 {
19 
20 #ifndef DOXYGEN_NO_DETAIL
21 namespace detail { namespace difference
22 {
23 
24 /*!
25 \brief_calc2{difference} \brief_strategy
26 \ingroup difference
27 \details \details_calc2{difference_insert, spatial set theoretic difference}
28     \brief_strategy. \details_inserter{difference}
29 \tparam GeometryOut output geometry type, must be specified
30 \tparam Geometry1 \tparam_geometry
31 \tparam Geometry2 \tparam_geometry
32 \tparam OutputIterator output iterator
33 \tparam Strategy \tparam_strategy_overlay
34 \param geometry1 \param_geometry
35 \param geometry2 \param_geometry
36 \param out \param_out{difference}
37 \param strategy \param_strategy{difference}
38 \return \return_out
39 
40 \qbk{distinguish,with strategy}
41 */
42 template
43 <
44     typename GeometryOut,
45     typename Geometry1,
46     typename Geometry2,
47     typename RobustPolicy,
48     typename OutputIterator,
49     typename Strategy
50 >
difference_insert(Geometry1 const & geometry1,Geometry2 const & geometry2,RobustPolicy const & robust_policy,OutputIterator out,Strategy const & strategy)51 inline OutputIterator difference_insert(Geometry1 const& geometry1,
52             Geometry2 const& geometry2,
53             RobustPolicy const& robust_policy,
54             OutputIterator out,
55             Strategy const& strategy)
56 {
57     concept::check<Geometry1 const>();
58     concept::check<Geometry2 const>();
59     concept::check<GeometryOut>();
60 
61     return geometry::dispatch::intersection_insert
62         <
63             Geometry1, Geometry2,
64             GeometryOut,
65             overlay_difference,
66             geometry::detail::overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
67             geometry::detail::overlay::do_reverse<geometry::point_order<Geometry2>::value, true>::value
68         >::apply(geometry1, geometry2, robust_policy, out, strategy);
69 }
70 
71 /*!
72 \brief_calc2{difference}
73 \ingroup difference
74 \details \details_calc2{difference_insert, spatial set theoretic difference}.
75     \details_insert{difference}
76 \tparam GeometryOut output geometry type, must be specified
77 \tparam Geometry1 \tparam_geometry
78 \tparam Geometry2 \tparam_geometry
79 \tparam OutputIterator output iterator
80 \param geometry1 \param_geometry
81 \param geometry2 \param_geometry
82 \param out \param_out{difference}
83 \return \return_out
84 
85 \qbk{[include reference/algorithms/difference_insert.qbk]}
86 */
87 template
88 <
89     typename GeometryOut,
90     typename Geometry1,
91     typename Geometry2,
92     typename RobustPolicy,
93     typename OutputIterator
94 >
difference_insert(Geometry1 const & geometry1,Geometry2 const & geometry2,RobustPolicy const & robust_policy,OutputIterator out)95 inline OutputIterator difference_insert(Geometry1 const& geometry1,
96             Geometry2 const& geometry2,
97             RobustPolicy const& robust_policy,
98             OutputIterator out)
99 {
100     concept::check<Geometry1 const>();
101     concept::check<Geometry2 const>();
102     concept::check<GeometryOut>();
103 
104     typedef strategy_intersection
105         <
106             typename cs_tag<GeometryOut>::type,
107             Geometry1,
108             Geometry2,
109             typename geometry::point_type<GeometryOut>::type,
110             RobustPolicy
111         > strategy;
112 
113     return difference_insert<GeometryOut>(geometry1, geometry2,
114             robust_policy, out, strategy());
115 }
116 
117 
118 }} // namespace detail::difference
119 #endif // DOXYGEN_NO_DETAIL
120 
121 
122 
123 /*!
124 \brief_calc2{difference}
125 \ingroup difference
126 \details \details_calc2{difference, spatial set theoretic difference}.
127 \tparam Geometry1 \tparam_geometry
128 \tparam Geometry2 \tparam_geometry
129 \tparam Collection \tparam_output_collection
130 \param geometry1 \param_geometry
131 \param geometry2 \param_geometry
132 \param output_collection the output collection
133 
134 \qbk{[include reference/algorithms/difference.qbk]}
135 */
136 template
137 <
138     typename Geometry1,
139     typename Geometry2,
140     typename Collection
141 >
difference(Geometry1 const & geometry1,Geometry2 const & geometry2,Collection & output_collection)142 inline void difference(Geometry1 const& geometry1,
143             Geometry2 const& geometry2, Collection& output_collection)
144 {
145     concept::check<Geometry1 const>();
146     concept::check<Geometry2 const>();
147 
148     typedef typename boost::range_value<Collection>::type geometry_out;
149     concept::check<geometry_out>();
150 
151     typedef typename geometry::rescale_overlay_policy_type
152         <
153             Geometry1,
154             Geometry2
155         >::type rescale_policy_type;
156 
157     rescale_policy_type robust_policy
158             = geometry::get_rescale_policy<rescale_policy_type>(geometry1, geometry2);
159 
160     detail::difference::difference_insert<geometry_out>(
161             geometry1, geometry2, robust_policy,
162             std::back_inserter(output_collection));
163 }
164 
165 
166 }} // namespace boost::geometry
167 
168 
169 #endif // BOOST_GEOMETRY_ALGORITHMS_DIFFERENCE_HPP
170