1 // Boost.Geometry (aka GGL, Generic Geometry Library)
3 // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
4 // Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
5 // Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
7 // This file was modified by Oracle on 2013, 2014, 2017, 2018.
8 // Modifications copyright (c) 2013-2018 Oracle and/or its affiliates.
10 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
12 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
13 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
15 // Use, modification and distribution is subject to the Boost Software License,
16 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
17 // http://www.boost.org/LICENSE_1_0.txt)
19 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_WITHIN_INTERFACE_HPP
20 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_WITHIN_INTERFACE_HPP
23 #include <boost/concept_check.hpp>
25 #include <boost/variant/apply_visitor.hpp>
26 #include <boost/variant/static_visitor.hpp>
27 #include <boost/variant/variant_fwd.hpp>
29 #include <boost/geometry/algorithms/not_implemented.hpp>
31 #include <boost/geometry/core/tag.hpp>
32 #include <boost/geometry/core/tag_cast.hpp>
34 #include <boost/geometry/geometries/concepts/check.hpp>
35 #include <boost/geometry/strategies/concepts/within_concept.hpp>
36 #include <boost/geometry/strategies/default_strategy.hpp>
37 #include <boost/geometry/strategies/within.hpp>
40 namespace boost { namespace geometry
43 #ifndef DOXYGEN_NO_DISPATCH
51 typename Tag1 = typename tag<Geometry1>::type,
52 typename Tag2 = typename tag<Geometry2>::type
55 : not_implemented<Tag1, Tag2>
59 } // namespace dispatch
60 #endif // DOXYGEN_NO_DISPATCH
63 namespace resolve_strategy
68 template <typename Geometry1, typename Geometry2, typename Strategy>
69 static inline bool apply(Geometry1 const& geometry1,
70 Geometry2 const& geometry2,
71 Strategy const& strategy)
73 concepts::within::check<Geometry1, Geometry2, Strategy>();
75 return dispatch::within<Geometry1, Geometry2>::apply(geometry1, geometry2, strategy);
78 template <typename Geometry1, typename Geometry2>
79 static inline bool apply(Geometry1 const& geometry1,
80 Geometry2 const& geometry2,
83 typedef typename strategy::within::services::default_strategy
87 >::type strategy_type;
89 return apply(geometry1, geometry2, strategy_type());
93 } // namespace resolve_strategy
96 namespace resolve_variant
99 template <typename Geometry1, typename Geometry2>
102 template <typename Strategy>
103 static inline bool apply(Geometry1 const& geometry1,
104 Geometry2 const& geometry2,
105 Strategy const& strategy)
107 concepts::check<Geometry1 const>();
108 concepts::check<Geometry2 const>();
109 assert_dimension_equal<Geometry1, Geometry2>();
111 return resolve_strategy::within::apply(geometry1,
117 template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
118 struct within<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
120 template <typename Strategy>
121 struct visitor: boost::static_visitor<bool>
123 Geometry2 const& m_geometry2;
124 Strategy const& m_strategy;
126 visitor(Geometry2 const& geometry2, Strategy const& strategy)
127 : m_geometry2(geometry2)
128 , m_strategy(strategy)
131 template <typename Geometry1>
132 bool operator()(Geometry1 const& geometry1) const
134 return within<Geometry1, Geometry2>::apply(geometry1,
140 template <typename Strategy>
142 apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
143 Geometry2 const& geometry2,
144 Strategy const& strategy)
146 return boost::apply_visitor(visitor<Strategy>(geometry2, strategy),
151 template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
152 struct within<Geometry1, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
154 template <typename Strategy>
155 struct visitor: boost::static_visitor<bool>
157 Geometry1 const& m_geometry1;
158 Strategy const& m_strategy;
160 visitor(Geometry1 const& geometry1, Strategy const& strategy)
161 : m_geometry1(geometry1)
162 , m_strategy(strategy)
165 template <typename Geometry2>
166 bool operator()(Geometry2 const& geometry2) const
168 return within<Geometry1, Geometry2>::apply(m_geometry1,
174 template <typename Strategy>
176 apply(Geometry1 const& geometry1,
177 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2,
178 Strategy const& strategy)
180 return boost::apply_visitor(visitor<Strategy>(geometry1, strategy),
187 BOOST_VARIANT_ENUM_PARAMS(typename T1),
188 BOOST_VARIANT_ENUM_PARAMS(typename T2)
191 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>,
192 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>
195 template <typename Strategy>
196 struct visitor: boost::static_visitor<bool>
198 Strategy const& m_strategy;
200 visitor(Strategy const& strategy): m_strategy(strategy) {}
202 template <typename Geometry1, typename Geometry2>
203 bool operator()(Geometry1 const& geometry1,
204 Geometry2 const& geometry2) const
206 return within<Geometry1, Geometry2>::apply(geometry1,
212 template <typename Strategy>
214 apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)> const& geometry1,
215 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2,
216 Strategy const& strategy)
218 return boost::apply_visitor(visitor<Strategy>(strategy),
228 \brief \brief_check12{is completely inside}
230 \details \details_check12{within, is completely inside}.
231 \tparam Geometry1 \tparam_geometry
232 \tparam Geometry2 \tparam_geometry
233 \param geometry1 \param_geometry which might be within the second geometry
234 \param geometry2 \param_geometry which might contain the first geometry
235 \return true if geometry1 is completely contained within geometry2,
237 \note The default strategy is used for within detection
240 \qbk{[include reference/algorithms/within.qbk]}
248 template<typename Geometry1, typename Geometry2>
249 inline bool within(Geometry1 const& geometry1, Geometry2 const& geometry2)
251 return resolve_variant::within
255 >::apply(geometry1, geometry2, default_strategy());
259 \brief \brief_check12{is completely inside} \brief_strategy
261 \details \details_check12{within, is completely inside}, \brief_strategy. \details_strategy_reasons
262 \tparam Geometry1 \tparam_geometry
263 \tparam Geometry2 \tparam_geometry
264 \param geometry1 \param_geometry which might be within the second geometry
265 \param geometry2 \param_geometry which might contain the first geometry
266 \param strategy strategy to be used
267 \return true if geometry1 is completely contained within geometry2,
270 \qbk{distinguish,with strategy}
271 \qbk{[include reference/algorithms/within.qbk]}
273 [heading Available Strategies]
274 \* [link geometry.reference.strategies.strategy_within_winding Winding (coordinate system agnostic)]
275 \* [link geometry.reference.strategies.strategy_within_franklin Franklin (cartesian)]
276 \* [link geometry.reference.strategies.strategy_within_crossings_multiply Crossings Multiply (cartesian)]
280 [within_strategy_output]
284 template<typename Geometry1, typename Geometry2, typename Strategy>
285 inline bool within(Geometry1 const& geometry1,
286 Geometry2 const& geometry2,
287 Strategy const& strategy)
289 return resolve_variant::within
293 >::apply(geometry1, geometry2, strategy);
296 }} // namespace boost::geometry
298 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_WITHIN_INTERFACE_HPP