1 // Boost.Geometry (aka GGL, Generic Geometry Library)
3 // Copyright (c) 2014, 2019, 2020 Oracle and/or its affiliates.
5 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
6 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
8 // Licensed under the Boost Software License version 1.0.
9 // http://www.boost.org/users/license.html
11 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_MULTIPOINT_TO_GEOMETRY_HPP
12 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_MULTIPOINT_TO_GEOMETRY_HPP
14 #include <boost/range/begin.hpp>
15 #include <boost/range/end.hpp>
16 #include <boost/range/size.hpp>
18 #include <boost/geometry/core/point_type.hpp>
19 #include <boost/geometry/core/tags.hpp>
21 #include <boost/geometry/strategies/distance.hpp>
22 #include <boost/geometry/strategies/tags.hpp>
24 #include <boost/geometry/algorithms/covered_by.hpp>
26 #include <boost/geometry/algorithms/dispatch/distance.hpp>
28 #include <boost/geometry/algorithms/detail/check_iterator_range.hpp>
29 #include <boost/geometry/algorithms/detail/distance/range_to_geometry_rtree.hpp>
32 namespace boost { namespace geometry
35 #ifndef DOXYGEN_NO_DETAIL
36 namespace detail { namespace distance
40 template <typename MultiPoint1, typename MultiPoint2, typename Strategy>
41 struct multipoint_to_multipoint
43 typedef typename strategy::distance::services::return_type
46 typename point_type<MultiPoint1>::type,
47 typename point_type<MultiPoint2>::type
50 static inline return_type apply(MultiPoint1 const& multipoint1,
51 MultiPoint2 const& multipoint2,
52 Strategy const& strategy)
54 if (boost::size(multipoint2) < boost::size(multipoint1))
57 return point_or_segment_range_to_geometry_rtree
59 typename boost::range_iterator<MultiPoint2 const>::type,
62 >::apply(boost::begin(multipoint2),
63 boost::end(multipoint2),
68 return point_or_segment_range_to_geometry_rtree
70 typename boost::range_iterator<MultiPoint1 const>::type,
73 >::apply(boost::begin(multipoint1),
74 boost::end(multipoint1),
81 template <typename MultiPoint, typename Linear, typename Strategy>
82 struct multipoint_to_linear
84 typedef typename strategy::distance::services::return_type
87 typename point_type<MultiPoint>::type,
88 typename point_type<Linear>::type
91 static inline return_type apply(MultiPoint const& multipoint,
93 Strategy const& strategy)
95 return detail::distance::point_or_segment_range_to_geometry_rtree
97 typename boost::range_iterator<MultiPoint const>::type,
100 >::apply(boost::begin(multipoint),
101 boost::end(multipoint),
106 static inline return_type apply(Linear const& linear,
107 MultiPoint const& multipoint,
108 Strategy const& strategy)
110 return apply(multipoint, linear, strategy);
115 template <typename MultiPoint, typename Areal, typename Strategy>
116 class multipoint_to_areal
119 template <typename CoveredByStrategy>
120 struct not_covered_by_areal
122 not_covered_by_areal(Areal const& areal, CoveredByStrategy const& strategy)
123 : m_areal(areal), m_strategy(strategy)
126 template <typename Point>
127 inline bool apply(Point const& point) const
129 return !geometry::covered_by(point, m_areal, m_strategy);
132 Areal const& m_areal;
133 CoveredByStrategy const& m_strategy;
137 typedef typename strategy::distance::services::return_type
140 typename point_type<MultiPoint>::type,
141 typename point_type<Areal>::type
144 static inline return_type apply(MultiPoint const& multipoint,
146 Strategy const& strategy)
148 typedef typename Strategy::point_in_geometry_strategy_type pg_strategy_type;
150 typedef not_covered_by_areal<pg_strategy_type> predicate_type;
152 // predicate holds references so the strategy has to be created here
153 pg_strategy_type pg_strategy = strategy.get_point_in_geometry_strategy();
154 predicate_type predicate(areal, pg_strategy);
156 if (check_iterator_range
158 predicate_type, false
159 >::apply(boost::begin(multipoint),
160 boost::end(multipoint),
163 return detail::distance::point_or_segment_range_to_geometry_rtree
165 typename boost::range_iterator<MultiPoint const>::type,
168 >::apply(boost::begin(multipoint),
169 boost::end(multipoint),
176 static inline return_type apply(Areal const& areal,
177 MultiPoint const& multipoint,
178 Strategy const& strategy)
180 return apply(multipoint, areal, strategy);
185 }} // namespace detail::distance
186 #endif // DOXYGEN_NO_DETAIL
190 #ifndef DOXYGEN_NO_DISPATCH
195 template <typename MultiPoint1, typename MultiPoint2, typename Strategy>
198 MultiPoint1, MultiPoint2, Strategy,
199 multi_point_tag, multi_point_tag,
200 strategy_tag_distance_point_point, false
201 > : detail::distance::multipoint_to_multipoint
203 MultiPoint1, MultiPoint2, Strategy
208 template <typename MultiPoint, typename Linear, typename Strategy>
211 MultiPoint, Linear, Strategy, multi_point_tag, linear_tag,
212 strategy_tag_distance_point_segment, false
213 > : detail::distance::multipoint_to_linear<MultiPoint, Linear, Strategy>
217 template <typename Linear, typename MultiPoint, typename Strategy>
220 Linear, MultiPoint, Strategy, linear_tag, multi_point_tag,
221 strategy_tag_distance_point_segment, false
222 > : detail::distance::multipoint_to_linear<MultiPoint, Linear, Strategy>
226 template <typename MultiPoint, typename Areal, typename Strategy>
229 MultiPoint, Areal, Strategy, multi_point_tag, areal_tag,
230 strategy_tag_distance_point_segment, false
231 > : detail::distance::multipoint_to_areal<MultiPoint, Areal, Strategy>
235 template <typename Areal, typename MultiPoint, typename Strategy>
238 Areal, MultiPoint, Strategy, areal_tag, multi_point_tag,
239 strategy_tag_distance_point_segment, false
240 > : detail::distance::multipoint_to_areal<MultiPoint, Areal, Strategy>
244 } // namespace dispatch
245 #endif // DOXYGEN_NO_DISPATCH
248 }} // namespace boost::geometry
251 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_MULTIPOINT_TO_GEOMETRY_HPP