1 // Boost.Geometry Index
3 // Spatial index distance predicates, calculators and checkers
4 // used in nearest query - specialized for envelopes
6 // Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
8 // This file was modified by Oracle on 2019-2020.
9 // Modifications copyright (c) 2019-2020 Oracle and/or its affiliates.
10 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
12 // Use, modification and distribution is subject to the Boost Software License,
13 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
14 // http://www.boost.org/LICENSE_1_0.txt)
16 #ifndef BOOST_GEOMETRY_INDEX_DETAIL_DISTANCE_PREDICATES_HPP
17 #define BOOST_GEOMETRY_INDEX_DETAIL_DISTANCE_PREDICATES_HPP
19 #include <boost/geometry/core/static_assert.hpp>
21 #include <boost/geometry/index/detail/algorithms/comparable_distance_near.hpp>
22 #include <boost/geometry/index/detail/algorithms/comparable_distance_far.hpp>
23 #include <boost/geometry/index/detail/algorithms/comparable_distance_centroid.hpp>
24 #include <boost/geometry/index/detail/algorithms/path_intersection.hpp>
26 #include <boost/geometry/index/detail/tags.hpp>
28 namespace boost { namespace geometry { namespace index { namespace detail {
30 // ------------------------------------------------------------------ //
32 // ------------------------------------------------------------------ //
37 to_nearest(T const& v) : value(v) {}
44 to_centroid(T const& v) : value(v) {}
51 to_furthest(T const& v) : value(v) {}
57 struct to_nearest_tag {};
58 struct to_centroid_tag {};
59 struct to_furthest_tag {};
61 // ------------------------------------------------------------------ //
62 // relation traits and access
63 // ------------------------------------------------------------------ //
69 typedef to_nearest_tag tag;
70 static inline T const& value(T const& v) { return v; }
71 static inline T & value(T & v) { return v; }
75 struct relation< to_nearest<T> >
78 typedef to_nearest_tag tag;
79 static inline T const& value(to_nearest<T> const& r) { return r.value; }
80 static inline T & value(to_nearest<T> & r) { return r.value; }
84 struct relation< to_centroid<T> >
87 typedef to_centroid_tag tag;
88 static inline T const& value(to_centroid<T> const& r) { return r.value; }
89 static inline T & value(to_centroid<T> & r) { return r.value; }
93 struct relation< to_furthest<T> >
96 typedef to_furthest_tag tag;
97 static inline T const& value(to_furthest<T> const& r) { return r.value; }
98 static inline T & value(to_furthest<T> & r) { return r.value; }
101 // ------------------------------------------------------------------ //
105 typename G1, typename G2, typename Strategy,
106 typename Tag1 = typename geometry::tag<G1>::type,
107 typename Tag2 = typename geometry::tag<G2>::type
109 struct comparable_distance_call_base
111 typedef typename geometry::default_comparable_distance_result
116 static inline result_type apply(G1 const& g1, G2 const& g2, Strategy const&)
118 return geometry::comparable_distance(g1, g2);
124 typename G1, typename G2, typename Strategy
126 struct comparable_distance_call_base<G1, G2, Strategy, point_tag, point_tag>
128 typedef typename geometry::comparable_distance_result
131 typename Strategy::comparable_distance_point_point_strategy_type
134 static inline result_type apply(G1 const& g1, G2 const& g2, Strategy const& s)
136 return geometry::comparable_distance(g1, g2,
137 s.get_comparable_distance_point_point_strategy());
143 typename G1, typename G2, typename Strategy
145 struct comparable_distance_call_base<G1, G2, Strategy, point_tag, box_tag>
147 typedef typename geometry::comparable_distance_result
150 typename Strategy::comparable_distance_point_box_strategy_type
153 static inline result_type apply(G1 const& g1, G2 const& g2, Strategy const& s)
155 return geometry::comparable_distance(g1, g2,
156 s.get_comparable_distance_point_box_strategy());
162 typename G1, typename G2, typename Strategy
164 struct comparable_distance_call_base<G1, G2, Strategy, segment_tag, point_tag>
166 typedef typename geometry::comparable_distance_result
169 typename Strategy::comparable_distance_point_segment_strategy_type
172 static inline result_type apply(G1 const& g1, G2 const& g2, Strategy const& s)
174 return geometry::comparable_distance(g1, g2,
175 s.get_comparable_distance_point_segment_strategy());
181 typename G1, typename G2, typename Strategy
183 struct comparable_distance_call_base<G1, G2, Strategy, segment_tag, box_tag>
185 typedef typename geometry::comparable_distance_result
188 typename Strategy::comparable_distance_segment_box_strategy_type
191 static inline result_type apply(G1 const& g1, G2 const& g2, Strategy const& s)
193 return geometry::comparable_distance(g1, g2,
194 s.get_comparable_distance_segment_box_strategy());
200 typename G1, typename G2, typename Strategy
202 struct comparable_distance_call_base<G1, G2, Strategy, segment_tag, segment_tag>
204 typedef typename geometry::comparable_distance_result
207 typename Strategy::comparable_distance_point_segment_strategy_type
210 static inline result_type apply(G1 const& g1, G2 const& g2, Strategy const& s)
212 return geometry::comparable_distance(g1, g2,
213 s.get_comparable_distance_point_segment_strategy());
219 typename G1, typename G2, typename Strategy
221 struct comparable_distance_call
222 : comparable_distance_call_base<G1, G2, Strategy>
227 typename G1, typename G2
229 struct comparable_distance_call<G1, G2, default_strategy>
230 : comparable_distance_call_base<G1, G2, default_strategy, void, void>
233 // ------------------------------------------------------------------ //
234 // calculate_distance
235 // ------------------------------------------------------------------ //
237 template <typename Predicate, typename Indexable, typename Strategy, typename Tag>
238 struct calculate_distance
240 BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
241 "Invalid Predicate or Tag.",
242 Predicate, Indexable, Strategy, Tag);
245 // this handles nearest() with default Point parameter, to_nearest() and bounds
246 template <typename PointRelation, typename Indexable, typename Strategy, typename Tag>
247 struct calculate_distance< predicates::nearest<PointRelation>, Indexable, Strategy, Tag>
249 typedef detail::relation<PointRelation> relation;
250 typedef comparable_distance_call
252 typename relation::value_type,
256 typedef typename call_type::result_type result_type;
258 static inline bool apply(predicates::nearest<PointRelation> const& p, Indexable const& i,
259 Strategy const& s, result_type & result)
261 result = call_type::apply(relation::value(p.point_or_relation), i, s);
266 template <typename Point, typename Indexable, typename Strategy>
267 struct calculate_distance< predicates::nearest< to_centroid<Point> >, Indexable, Strategy, value_tag>
269 typedef Point point_type;
270 typedef typename geometry::default_comparable_distance_result
272 point_type, Indexable
275 static inline bool apply(predicates::nearest< to_centroid<Point> > const& p, Indexable const& i,
276 Strategy const& , result_type & result)
278 result = index::detail::comparable_distance_centroid(p.point_or_relation.value, i);
283 template <typename Point, typename Indexable, typename Strategy>
284 struct calculate_distance< predicates::nearest< to_furthest<Point> >, Indexable, Strategy, value_tag>
286 typedef Point point_type;
287 typedef typename geometry::default_comparable_distance_result
289 point_type, Indexable
292 static inline bool apply(predicates::nearest< to_furthest<Point> > const& p, Indexable const& i,
293 Strategy const& , result_type & result)
295 result = index::detail::comparable_distance_far(p.point_or_relation.value, i);
300 template <typename SegmentOrLinestring, typename Indexable, typename Strategy, typename Tag>
301 struct calculate_distance< predicates::path<SegmentOrLinestring>, Indexable, Strategy, Tag>
303 typedef typename index::detail::default_path_intersection_distance_type<
304 Indexable, SegmentOrLinestring
307 static inline bool apply(predicates::path<SegmentOrLinestring> const& p, Indexable const& i,
308 Strategy const& , result_type & result)
310 return index::detail::path_intersection(i, p.geometry, result);
314 }}}} // namespace boost::geometry::index::detail
316 #endif // BOOST_GEOMETRY_INDEX_RTREE_DISTANCE_PREDICATES_HPP