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.
8 // Modifications copyright (c) 2013-2017 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
75 typename tag<Geometry1>::type,
76 typename tag<Geometry2>::type,
77 typename tag_cast<typename tag<Geometry2>::type, areal_tag>::type,
81 return dispatch::within<Geometry1, Geometry2>::apply(geometry1, geometry2, strategy);
84 template <typename Geometry1, typename Geometry2>
85 static inline bool apply(Geometry1 const& geometry1,
86 Geometry2 const& geometry2,
89 typedef typename strategy::within::services::default_strategy
93 >::type strategy_type;
95 return apply(geometry1, geometry2, strategy_type());
99 } // namespace resolve_strategy
102 namespace resolve_variant
105 template <typename Geometry1, typename Geometry2>
108 template <typename Strategy>
109 static inline bool apply(Geometry1 const& geometry1,
110 Geometry2 const& geometry2,
111 Strategy const& strategy)
113 concepts::check<Geometry1 const>();
114 concepts::check<Geometry2 const>();
115 assert_dimension_equal<Geometry1, Geometry2>();
117 return resolve_strategy::within::apply(geometry1,
123 template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
124 struct within<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
126 template <typename Strategy>
127 struct visitor: boost::static_visitor<bool>
129 Geometry2 const& m_geometry2;
130 Strategy const& m_strategy;
132 visitor(Geometry2 const& geometry2, Strategy const& strategy)
133 : m_geometry2(geometry2)
134 , m_strategy(strategy)
137 template <typename Geometry1>
138 bool operator()(Geometry1 const& geometry1) const
140 return within<Geometry1, Geometry2>::apply(geometry1,
146 template <typename Strategy>
148 apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
149 Geometry2 const& geometry2,
150 Strategy const& strategy)
152 return boost::apply_visitor(visitor<Strategy>(geometry2, strategy),
157 template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
158 struct within<Geometry1, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
160 template <typename Strategy>
161 struct visitor: boost::static_visitor<bool>
163 Geometry1 const& m_geometry1;
164 Strategy const& m_strategy;
166 visitor(Geometry1 const& geometry1, Strategy const& strategy)
167 : m_geometry1(geometry1)
168 , m_strategy(strategy)
171 template <typename Geometry2>
172 bool operator()(Geometry2 const& geometry2) const
174 return within<Geometry1, Geometry2>::apply(m_geometry1,
180 template <typename Strategy>
182 apply(Geometry1 const& geometry1,
183 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2,
184 Strategy const& strategy)
186 return boost::apply_visitor(visitor<Strategy>(geometry1, strategy),
193 BOOST_VARIANT_ENUM_PARAMS(typename T1),
194 BOOST_VARIANT_ENUM_PARAMS(typename T2)
197 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>,
198 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>
201 template <typename Strategy>
202 struct visitor: boost::static_visitor<bool>
204 Strategy const& m_strategy;
206 visitor(Strategy const& strategy): m_strategy(strategy) {}
208 template <typename Geometry1, typename Geometry2>
209 bool operator()(Geometry1 const& geometry1,
210 Geometry2 const& geometry2) const
212 return within<Geometry1, Geometry2>::apply(geometry1,
218 template <typename Strategy>
220 apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)> const& geometry1,
221 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2,
222 Strategy const& strategy)
224 return boost::apply_visitor(visitor<Strategy>(strategy),
234 \brief \brief_check12{is completely inside}
236 \details \details_check12{within, is completely inside}.
237 \tparam Geometry1 \tparam_geometry
238 \tparam Geometry2 \tparam_geometry
239 \param geometry1 \param_geometry which might be within the second geometry
240 \param geometry2 \param_geometry which might contain the first geometry
241 \return true if geometry1 is completely contained within geometry2,
243 \note The default strategy is used for within detection
246 \qbk{[include reference/algorithms/within.qbk]}
254 template<typename Geometry1, typename Geometry2>
255 inline bool within(Geometry1 const& geometry1, Geometry2 const& geometry2)
257 return resolve_variant::within
261 >::apply(geometry1, geometry2, default_strategy());
265 \brief \brief_check12{is completely inside} \brief_strategy
267 \details \details_check12{within, is completely inside}, \brief_strategy. \details_strategy_reasons
268 \tparam Geometry1 \tparam_geometry
269 \tparam Geometry2 \tparam_geometry
270 \param geometry1 \param_geometry which might be within the second geometry
271 \param geometry2 \param_geometry which might contain the first geometry
272 \param strategy strategy to be used
273 \return true if geometry1 is completely contained within geometry2,
276 \qbk{distinguish,with strategy}
277 \qbk{[include reference/algorithms/within.qbk]}
279 [heading Available Strategies]
280 \* [link geometry.reference.strategies.strategy_within_winding Winding (coordinate system agnostic)]
281 \* [link geometry.reference.strategies.strategy_within_franklin Franklin (cartesian)]
282 \* [link geometry.reference.strategies.strategy_within_crossings_multiply Crossings Multiply (cartesian)]
286 [within_strategy_output]
290 template<typename Geometry1, typename Geometry2, typename Strategy>
291 inline bool within(Geometry1 const& geometry1,
292 Geometry2 const& geometry2,
293 Strategy const& strategy)
295 return resolve_variant::within
299 >::apply(geometry1, geometry2, strategy);
302 }} // namespace boost::geometry
304 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_WITHIN_INTERFACE_HPP