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 2013-2020.
6 // Modifications copyright (c) 2013-2020 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_RELATE_INTERFACE_HPP
15 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_INTERFACE_HPP
20 #include <boost/variant/apply_visitor.hpp>
21 #include <boost/variant/static_visitor.hpp>
22 #include <boost/variant/variant_fwd.hpp>
24 #include <boost/geometry/algorithms/detail/relate/de9im.hpp>
25 #include <boost/geometry/algorithms/not_implemented.hpp>
26 #include <boost/geometry/core/coordinate_dimension.hpp>
27 #include <boost/geometry/core/tag.hpp>
28 #include <boost/geometry/core/tags.hpp>
29 #include <boost/geometry/core/topological_dimension.hpp>
30 #include <boost/geometry/geometries/concepts/check.hpp>
31 #include <boost/geometry/strategies/default_strategy.hpp>
32 #include <boost/geometry/strategies/detail.hpp>
33 #include <boost/geometry/strategies/relate/services.hpp>
34 #include <boost/geometry/util/sequence.hpp>
35 #include <boost/geometry/util/type_traits.hpp>
38 namespace boost { namespace geometry {
41 #ifndef DOXYGEN_NO_DETAIL
42 namespace detail { namespace relate {
44 // is_generic allows dispatch::relate to generate compile-time error
45 template <typename Geometry1, typename Geometry2>
48 static const bool value = (util::is_polysegmental<Geometry1>::value
49 && util::is_polysegmental<Geometry2>::value)
51 (util::is_point<Geometry1>::value
52 && util::is_polysegmental<Geometry2>::value)
54 (util::is_polysegmental<Geometry1>::value
55 && util::is_point<Geometry2>::value);
58 }} // namespace detail::relate
59 #endif // DOXYGEN_NO_DETAIL
62 #ifndef DOXYGEN_NO_DISPATCH
66 template <typename Geometry1,
68 typename Tag1 = typename geometry::tag<Geometry1>::type,
69 typename Tag2 = typename geometry::tag<Geometry2>::type,
70 int TopDim1 = geometry::topological_dimension<Geometry1>::value,
71 int TopDim2 = geometry::topological_dimension<Geometry2>::value,
72 bool IsGeneric = detail::relate::is_generic<Geometry1, Geometry2>::value
74 struct relate : not_implemented<Tag1, Tag2>
77 } // namespace dispatch
78 #endif // DOXYGEN_NO_DISPATCH
80 #ifndef DOXYGEN_NO_DETAIL
81 namespace detail { namespace relate {
83 template <typename Geometry1, typename Geometry2>
84 struct interruption_enabled
86 static const bool value =
87 dispatch::relate<Geometry1, Geometry2>::interruption_enabled;
90 template <typename Geometry1, typename Geometry2, typename Result>
91 struct result_handler_type
92 : not_implemented<Result>
95 template <typename Geometry1, typename Geometry2>
96 struct result_handler_type<Geometry1, Geometry2, geometry::de9im::mask>
100 geometry::de9im::mask,
109 template <typename Geometry1, typename Geometry2, typename ...Masks>
110 struct result_handler_type<Geometry1, Geometry2, std::tuple<Masks...>>
114 std::tuple<Masks...>,
123 template <typename Geometry1, typename Geometry2,
124 char II, char IB, char IE,
125 char BI, char BB, char BE,
126 char EI, char EB, char EE>
127 struct result_handler_type
131 geometry::de9im::static_mask<II, IB, IE, BI, BB, BE, EI, EB, EE>
134 typedef static_mask_handler
136 geometry::de9im::static_mask<II, IB, IE, BI, BB, BE, EI, EB, EE>,
145 template <typename Geometry1, typename Geometry2, typename ...StaticMasks>
146 struct result_handler_type<Geometry1, Geometry2, util::type_sequence<StaticMasks...>>
148 typedef static_mask_handler
150 util::type_sequence<StaticMasks...>,
160 }} // namespace detail::relate
161 #endif // DOXYGEN_NO_DETAIL
163 namespace resolve_strategy {
169 bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
173 template <typename Geometry1, typename Geometry2, typename ResultHandler>
174 static inline void apply(Geometry1 const& geometry1,
175 Geometry2 const& geometry2,
176 ResultHandler & handler,
177 Strategy const& strategy)
183 >::apply(geometry1, geometry2, handler, strategy);
187 template <typename Strategy>
188 struct relate<Strategy, false>
190 template <typename Geometry1, typename Geometry2, typename ResultHandler>
191 static inline void apply(Geometry1 const& geometry1,
192 Geometry2 const& geometry2,
193 ResultHandler & handler,
194 Strategy const& strategy)
196 using strategies::relate::services::strategy_converter;
201 >::apply(geometry1, geometry2, handler,
202 strategy_converter<Strategy>::get(strategy));
207 struct relate<default_strategy, false>
209 template <typename Geometry1, typename Geometry2, typename ResultHandler>
210 static inline void apply(Geometry1 const& geometry1,
211 Geometry2 const& geometry2,
212 ResultHandler & handler,
215 typedef typename strategies::relate::services::default_strategy
219 >::type strategy_type;
225 >::apply(geometry1, geometry2, handler, strategy_type());
229 } // resolve_strategy
231 namespace resolve_variant {
233 template <typename Geometry1, typename Geometry2>
236 template <typename Mask, typename Strategy>
237 static inline bool apply(Geometry1 const& geometry1,
238 Geometry2 const& geometry2,
240 Strategy const& strategy)
242 concepts::check<Geometry1 const>();
243 concepts::check<Geometry2 const>();
244 assert_dimension_equal<Geometry1, Geometry2>();
246 typename detail::relate::result_handler_type
251 >::type handler(mask);
253 resolve_strategy::relate<Strategy>::apply(geometry1, geometry2, handler, strategy);
255 return handler.result();
259 template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
260 struct relate<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
262 template <typename Mask, typename Strategy>
263 struct visitor : boost::static_visitor<bool>
265 Geometry2 const& m_geometry2;
267 Strategy const& m_strategy;
269 visitor(Geometry2 const& geometry2, Mask const& mask, Strategy const& strategy)
270 : m_geometry2(geometry2), m_mask(mask), m_strategy(strategy) {}
272 template <typename Geometry1>
273 bool operator()(Geometry1 const& geometry1) const
275 return relate<Geometry1, Geometry2>
276 ::apply(geometry1, m_geometry2, m_mask, m_strategy);
280 template <typename Mask, typename Strategy>
282 apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
283 Geometry2 const& geometry2,
285 Strategy const& strategy)
287 return boost::apply_visitor(visitor<Mask, Strategy>(geometry2, mask, strategy), geometry1);
291 template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
292 struct relate<Geometry1, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
294 template <typename Mask, typename Strategy>
295 struct visitor : boost::static_visitor<bool>
297 Geometry1 const& m_geometry1;
299 Strategy const& m_strategy;
301 visitor(Geometry1 const& geometry1, Mask const& mask, Strategy const& strategy)
302 : m_geometry1(geometry1), m_mask(mask), m_strategy(strategy) {}
304 template <typename Geometry2>
305 bool operator()(Geometry2 const& geometry2) const
307 return relate<Geometry1, Geometry2>
308 ::apply(m_geometry1, geometry2, m_mask, m_strategy);
312 template <typename Mask, typename Strategy>
314 apply(Geometry1 const& geometry1,
315 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2,
317 Strategy const& strategy)
319 return boost::apply_visitor(visitor<Mask, Strategy>(geometry1, mask, strategy), geometry2);
324 BOOST_VARIANT_ENUM_PARAMS(typename T1),
325 BOOST_VARIANT_ENUM_PARAMS(typename T2)
328 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>,
329 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>
332 template <typename Mask, typename Strategy>
333 struct visitor : boost::static_visitor<bool>
336 Strategy const& m_strategy;
338 visitor(Mask const& mask, Strategy const& strategy)
339 : m_mask(mask), m_strategy(strategy) {}
341 template <typename Geometry1, typename Geometry2>
342 bool operator()(Geometry1 const& geometry1,
343 Geometry2 const& geometry2) const
345 return relate<Geometry1, Geometry2>
346 ::apply(geometry1, geometry2, m_mask, m_strategy);
350 template <typename Mask, typename Strategy>
352 apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)> const& geometry1,
353 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2,
355 Strategy const& strategy)
357 return boost::apply_visitor(visitor<Mask, Strategy>(mask, strategy), geometry1, geometry2);
361 } // namespace resolve_variant
364 \brief Checks relation between a pair of geometries defined by a mask.
366 \tparam Geometry1 \tparam_geometry
367 \tparam Geometry2 \tparam_geometry
368 \tparam Mask An intersection model Mask type.
369 \tparam Strategy \tparam_strategy{Relate}
370 \param geometry1 \param_geometry
371 \param geometry2 \param_geometry
372 \param mask An intersection model mask object.
373 \param strategy \param_strategy{relate}
374 \return true if the relation is compatible with the mask, false otherwise.
376 \qbk{distinguish,with strategy}
377 \qbk{[include reference/algorithms/relate.qbk]}
379 template <typename Geometry1, typename Geometry2, typename Mask, typename Strategy>
380 inline bool relate(Geometry1 const& geometry1,
381 Geometry2 const& geometry2,
383 Strategy const& strategy)
385 return resolve_variant::relate
389 >::apply(geometry1, geometry2, mask, strategy);
393 \brief Checks relation between a pair of geometries defined by a mask.
395 \tparam Geometry1 \tparam_geometry
396 \tparam Geometry2 \tparam_geometry
397 \tparam Mask An intersection model Mask type.
398 \param geometry1 \param_geometry
399 \param geometry2 \param_geometry
400 \param mask An intersection model mask object.
401 \return true if the relation is compatible with the mask, false otherwise.
403 \qbk{[include reference/algorithms/relate.qbk]}
405 template <typename Geometry1, typename Geometry2, typename Mask>
406 inline bool relate(Geometry1 const& geometry1,
407 Geometry2 const& geometry2,
410 return resolve_variant::relate
414 >::apply(geometry1, geometry2, mask, default_strategy());
417 }} // namespace boost::geometry
419 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_INTERFACE_HPP