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 2014, 2017, 2019.
6 // Modifications copyright (c) 2014-2019, 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_DETAIL_INTERSECTION_INTERFACE_HPP
15 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTION_INTERFACE_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/algorithms/detail/tupled_output.hpp>
24 #include <boost/geometry/policies/robustness/get_rescale_policy.hpp>
25 #include <boost/geometry/strategies/default_strategy.hpp>
26 #include <boost/geometry/util/range.hpp>
29 namespace boost { namespace geometry
33 #ifndef DOXYGEN_NO_DISPATCH
37 // By default, all is forwarded to the intersection_insert-dispatcher
40 typename Geometry1, typename Geometry2,
41 typename Tag1 = typename geometry::tag<Geometry1>::type,
42 typename Tag2 = typename geometry::tag<Geometry2>::type,
43 bool Reverse = reverse_dispatch<Geometry1, Geometry2>::type::value
47 template <typename RobustPolicy, typename GeometryOut, typename Strategy>
48 static inline bool apply(Geometry1 const& geometry1,
49 Geometry2 const& geometry2,
50 RobustPolicy const& robust_policy,
51 GeometryOut& geometry_out,
52 Strategy const& strategy)
54 typedef typename geometry::detail::output_geometry_value
61 Geometry1, Geometry2, SingleOut,
63 >::apply(geometry1, geometry2, robust_policy,
64 geometry::detail::output_geometry_back_inserter(geometry_out),
73 // If reversal is needed, perform it
76 typename Geometry1, typename Geometry2,
77 typename Tag1, typename Tag2
85 : intersection<Geometry2, Geometry1, Tag2, Tag1, false>
87 template <typename RobustPolicy, typename GeometryOut, typename Strategy>
88 static inline bool apply(
91 RobustPolicy const& robust_policy,
93 Strategy const& strategy)
100 >::apply(g2, g1, robust_policy, out, strategy);
105 } // namespace dispatch
106 #endif // DOXYGEN_NO_DISPATCH
109 namespace resolve_strategy {
117 typename GeometryOut,
120 static inline bool apply(Geometry1 const& geometry1,
121 Geometry2 const& geometry2,
122 GeometryOut & geometry_out,
123 Strategy const& strategy)
125 typedef typename geometry::rescale_overlay_policy_type
129 typename Strategy::cs_tag
130 >::type rescale_policy_type;
132 rescale_policy_type robust_policy
133 = geometry::get_rescale_policy<rescale_policy_type>(
134 geometry1, geometry2, strategy);
136 return dispatch::intersection
140 >::apply(geometry1, geometry2, robust_policy, geometry_out,
150 static inline bool apply(Geometry1 const& geometry1,
151 Geometry2 const& geometry2,
152 GeometryOut & geometry_out,
155 typedef typename geometry::rescale_overlay_policy_type
159 typename geometry::cs_tag<Geometry1>::type
160 >::type rescale_policy_type;
162 typename strategy::relate::services::default_strategy
167 rescale_policy_type robust_policy
168 = geometry::get_rescale_policy<rescale_policy_type>(
169 geometry1, geometry2, strategy);
171 return dispatch::intersection
175 >::apply(geometry1, geometry2, robust_policy, geometry_out,
180 } // resolve_strategy
183 namespace resolve_variant
186 template <typename Geometry1, typename Geometry2>
189 template <typename GeometryOut, typename Strategy>
190 static inline bool apply(Geometry1 const& geometry1,
191 Geometry2 const& geometry2,
192 GeometryOut& geometry_out,
193 Strategy const& strategy)
195 concepts::check<Geometry1 const>();
196 concepts::check<Geometry2 const>();
198 return resolve_strategy::intersection::apply(geometry1,
206 template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
207 struct intersection<variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
209 template <typename GeometryOut, typename Strategy>
210 struct visitor: static_visitor<bool>
212 Geometry2 const& m_geometry2;
213 GeometryOut& m_geometry_out;
214 Strategy const& m_strategy;
216 visitor(Geometry2 const& geometry2,
217 GeometryOut& geometry_out,
218 Strategy const& strategy)
219 : m_geometry2(geometry2)
220 , m_geometry_out(geometry_out)
221 , m_strategy(strategy)
224 template <typename Geometry1>
225 bool operator()(Geometry1 const& geometry1) const
231 >::apply(geometry1, m_geometry2, m_geometry_out, m_strategy);
235 template <typename GeometryOut, typename Strategy>
237 apply(variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
238 Geometry2 const& geometry2,
239 GeometryOut& geometry_out,
240 Strategy const& strategy)
242 return boost::apply_visitor(visitor<GeometryOut, Strategy>(geometry2,
250 template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
251 struct intersection<Geometry1, variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
253 template <typename GeometryOut, typename Strategy>
254 struct visitor: static_visitor<bool>
256 Geometry1 const& m_geometry1;
257 GeometryOut& m_geometry_out;
258 Strategy const& m_strategy;
260 visitor(Geometry1 const& geometry1,
261 GeometryOut& geometry_out,
262 Strategy const& strategy)
263 : m_geometry1(geometry1)
264 , m_geometry_out(geometry_out)
265 , m_strategy(strategy)
268 template <typename Geometry2>
269 bool operator()(Geometry2 const& geometry2) const
275 >::apply(m_geometry1, geometry2, m_geometry_out, m_strategy);
279 template <typename GeometryOut, typename Strategy>
281 apply(Geometry1 const& geometry1,
282 variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2,
283 GeometryOut& geometry_out,
284 Strategy const& strategy)
286 return boost::apply_visitor(visitor<GeometryOut, Strategy>(geometry1,
294 template <BOOST_VARIANT_ENUM_PARAMS(typename T1), BOOST_VARIANT_ENUM_PARAMS(typename T2)>
295 struct intersection<variant<BOOST_VARIANT_ENUM_PARAMS(T1)>, variant<BOOST_VARIANT_ENUM_PARAMS(T2)> >
297 template <typename GeometryOut, typename Strategy>
298 struct visitor: static_visitor<bool>
300 GeometryOut& m_geometry_out;
301 Strategy const& m_strategy;
303 visitor(GeometryOut& geometry_out, Strategy const& strategy)
304 : m_geometry_out(geometry_out)
305 , m_strategy(strategy)
308 template <typename Geometry1, typename Geometry2>
309 bool operator()(Geometry1 const& geometry1,
310 Geometry2 const& geometry2) const
316 >::apply(geometry1, geometry2, m_geometry_out, m_strategy);
320 template <typename GeometryOut, typename Strategy>
322 apply(variant<BOOST_VARIANT_ENUM_PARAMS(T1)> const& geometry1,
323 variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2,
324 GeometryOut& geometry_out,
325 Strategy const& strategy)
327 return boost::apply_visitor(visitor<GeometryOut, Strategy>(geometry_out,
329 geometry1, geometry2);
333 } // namespace resolve_variant
337 \brief \brief_calc2{intersection}
338 \ingroup intersection
339 \details \details_calc2{intersection, spatial set theoretic intersection}.
340 \tparam Geometry1 \tparam_geometry
341 \tparam Geometry2 \tparam_geometry
342 \tparam GeometryOut Collection of geometries (e.g. std::vector, std::deque, boost::geometry::multi*) of which
343 the value_type fulfills a \p_l_or_c concept, or it is the output geometry (e.g. for a box)
344 \tparam Strategy \tparam_strategy{Intersection}
345 \param geometry1 \param_geometry
346 \param geometry2 \param_geometry
347 \param geometry_out The output geometry, either a multi_point, multi_polygon,
348 multi_linestring, or a box (for intersection of two boxes)
349 \param strategy \param_strategy{intersection}
351 \qbk{distinguish,with strategy}
352 \qbk{[include reference/algorithms/intersection.qbk]}
358 typename GeometryOut,
361 inline bool intersection(Geometry1 const& geometry1,
362 Geometry2 const& geometry2,
363 GeometryOut& geometry_out,
364 Strategy const& strategy)
366 return resolve_variant::intersection
370 >::apply(geometry1, geometry2, geometry_out, strategy);
375 \brief \brief_calc2{intersection}
376 \ingroup intersection
377 \details \details_calc2{intersection, spatial set theoretic intersection}.
378 \tparam Geometry1 \tparam_geometry
379 \tparam Geometry2 \tparam_geometry
380 \tparam GeometryOut Collection of geometries (e.g. std::vector, std::deque, boost::geometry::multi*) of which
381 the value_type fulfills a \p_l_or_c concept, or it is the output geometry (e.g. for a box)
382 \param geometry1 \param_geometry
383 \param geometry2 \param_geometry
384 \param geometry_out The output geometry, either a multi_point, multi_polygon,
385 multi_linestring, or a box (for intersection of two boxes)
387 \qbk{[include reference/algorithms/intersection.qbk]}
395 inline bool intersection(Geometry1 const& geometry1,
396 Geometry2 const& geometry2,
397 GeometryOut& geometry_out)
399 return resolve_variant::intersection
403 >::apply(geometry1, geometry2, geometry_out, default_strategy());
407 }} // namespace boost::geometry
410 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTION_INTERFACE_HPP