3 // Copyright (c) 2021, Oracle and/or its affiliates.
5 // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
7 // Licensed under the Boost Software License version 1.0.
8 // http://www.boost.org/users/license.html
10 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_CLOSEST_POINTS_MULTIPOINT_TO_GEOMETRY_HPP
11 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_CLOSEST_POINTS_MULTIPOINT_TO_GEOMETRY_HPP
15 #include <boost/geometry/algorithms/covered_by.hpp>
16 #include <boost/geometry/algorithms/detail/closest_points/range_to_geometry_rtree.hpp>
17 #include <boost/geometry/algorithms/detail/closest_points/utilities.hpp>
18 #include <boost/geometry/algorithms/dispatch/closest_points.hpp>
20 #include <boost/geometry/core/point_type.hpp>
21 #include <boost/geometry/core/tags.hpp>
23 #include <boost/geometry/geometries/linestring.hpp>
26 namespace boost { namespace geometry
29 #ifndef DOXYGEN_NO_DETAIL
30 namespace detail { namespace closest_points
34 struct multipoint_to_multipoint
43 static inline void apply(MultiPoint1 const& multipoint1,
44 MultiPoint2 const& multipoint2,
45 Segment& shortest_seg,
46 Strategies const& strategies)
48 if (boost::size(multipoint1) < boost::size(multipoint2))
50 point_or_segment_range_to_geometry_rtree::apply(
51 boost::begin(multipoint2),
52 boost::end(multipoint2),
56 detail::closest_points::swap_segment_points::apply(shortest_seg);
59 point_or_segment_range_to_geometry_rtree::apply(
60 boost::begin(multipoint1),
61 boost::end(multipoint1),
68 struct multipoint_to_linear
77 static inline void apply(MultiPoint const& multipoint,
79 Segment& shortest_seg,
80 Strategies const& strategies)
82 point_or_segment_range_to_geometry_rtree::apply(
83 boost::begin(multipoint),
84 boost::end(multipoint),
91 struct linear_to_multipoint
100 static inline void apply(Linear const& linear,
101 MultiPoint const& multipoint,
102 Segment& shortest_seg,
103 Strategies const& strategies)
105 multipoint_to_linear::apply(multipoint, linear, shortest_seg, strategies);
106 detail::closest_points::swap_segment_points::apply(shortest_seg);
110 struct segment_to_multipoint
119 static inline void apply(Segment const& segment,
120 MultiPoint const& multipoint,
121 OutSegment& shortest_seg,
122 Strategies const& strategies)
124 using linestring_type = geometry::model::linestring
126 typename point_type<Segment>::type
128 linestring_type linestring;
129 convert(segment, linestring);
130 multipoint_to_linear::apply(multipoint, linestring, shortest_seg, strategies);
131 detail::closest_points::swap_segment_points::apply(shortest_seg);
135 struct multipoint_to_segment
144 static inline void apply(MultiPoint const& multipoint,
145 Segment const& segment,
146 OutSegment& shortest_seg,
147 Strategies const& strategies)
149 using linestring_type = geometry::model::linestring
151 typename point_type<Segment>::type
153 linestring_type linestring;
154 convert(segment, linestring);
155 multipoint_to_linear::apply(multipoint, linestring, shortest_seg,
161 struct multipoint_to_areal
166 template <typename Areal, typename Strategies>
167 struct covered_by_areal
169 covered_by_areal(Areal const& areal, Strategies const& strategy)
170 : m_areal(areal), m_strategy(strategy)
173 template <typename Point>
174 inline bool operator()(Point const& point) const
176 return geometry::covered_by(point, m_areal, m_strategy);
179 Areal const& m_areal;
180 Strategies const& m_strategy;
192 static inline void apply(MultiPoint const& multipoint,
194 Segment& shortest_seg,
195 Strategies const& strategies)
197 covered_by_areal<Areal, Strategies> predicate(areal, strategies);
199 auto it = std::find_if(
200 boost::begin(multipoint),
201 boost::end(multipoint),
204 if (it != boost::end(multipoint))
206 return set_segment_from_points::apply(*it, *it, shortest_seg);
210 point_or_segment_range_to_geometry_rtree::apply(
211 boost::begin(multipoint),
212 boost::end(multipoint),
219 struct areal_to_multipoint
228 static inline void apply(Areal const& areal,
229 MultiPoint const& multipoint,
230 Segment& shortest_seg,
231 Strategies const& strategies)
233 multipoint_to_areal::apply(multipoint, areal, shortest_seg, strategies);
234 detail::closest_points::swap_segment_points::apply(shortest_seg);
238 }} // namespace detail::closest_points
239 #endif // DOXYGEN_NO_DETAIL
243 #ifndef DOXYGEN_NO_DISPATCH
248 template <typename MultiPoint1, typename MultiPoint2>
249 struct closest_points
251 MultiPoint1, MultiPoint2,
252 multi_point_tag, multi_point_tag,
254 > : detail::closest_points::multipoint_to_multipoint
258 template <typename MultiPoint, typename Linear>
259 struct closest_points
262 multi_point_tag, linear_tag,
264 > : detail::closest_points::multipoint_to_linear
268 template <typename Linear, typename MultiPoint>
269 struct closest_points
272 linear_tag, multi_point_tag,
274 > : detail::closest_points::linear_to_multipoint
278 template <typename MultiPoint, typename Segment>
279 struct closest_points
282 multi_point_tag, segment_tag,
284 > : detail::closest_points::multipoint_to_segment
288 template <typename Segment, typename MultiPoint>
289 struct closest_points
292 segment_tag, multi_point_tag,
294 > : detail::closest_points::segment_to_multipoint
298 template <typename MultiPoint, typename Areal>
299 struct closest_points
302 multi_point_tag, areal_tag,
304 > : detail::closest_points::multipoint_to_areal
308 template <typename Areal, typename MultiPoint>
309 struct closest_points
312 areal_tag, multi_point_tag,
314 > : detail::closest_points::areal_to_multipoint
318 } // namespace dispatch
319 #endif // DOXYGEN_NO_DISPATCH
322 }} // namespace boost::geometry
325 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_CLOSEST_POINTS_MULTIPOINT_TO_GEOMETRY_HPP