1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2 
3 // Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
4 // Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
5 // Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
6 // Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland.
7 
8 // This file was modified by Oracle on 2014.
9 // Modifications copyright (c) 2014, Oracle and/or its affiliates.
10 
11 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
12 
13 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
14 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
15 
16 // Use, modification and distribution is subject to the Boost Software License,
17 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
18 // http://www.boost.org/LICENSE_1_0.txt)
19 
20 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_BACKWARD_COMPATIBILITY_HPP
21 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_BACKWARD_COMPATIBILITY_HPP
22 
23 #include <boost/geometry/core/closure.hpp>
24 #include <boost/geometry/core/point_type.hpp>
25 #include <boost/geometry/core/tags.hpp>
26 
27 #include <boost/geometry/strategies/distance.hpp>
28 #include <boost/geometry/strategies/tags.hpp>
29 
30 #include <boost/geometry/algorithms/assign.hpp>
31 
32 #include <boost/geometry/algorithms/dispatch/distance.hpp>
33 
34 #include <boost/geometry/algorithms/detail/distance/default_strategies.hpp>
35 #include <boost/geometry/algorithms/detail/distance/point_to_geometry.hpp>
36 #include <boost/geometry/algorithms/detail/distance/multipoint_to_geometry.hpp>
37 
38 
39 namespace boost { namespace geometry
40 {
41 
42 
43 #ifndef DOXYGEN_NO_DETAIL
44 namespace detail { namespace distance
45 {
46 
47 
48 template<typename Point, typename Segment, typename Strategy>
49 struct point_to_segment
50 {
51     static inline typename strategy::distance::services::return_type
52         <
53             Strategy,
54             Point,
55             typename point_type<Segment>::type
56         >::type
applyboost::geometry::detail::distance::point_to_segment57     apply(Point const& point, Segment const& segment, Strategy const& )
58     {
59         typename detail::distance::default_ps_strategy
60             <
61                 Point,
62                 typename point_type<Segment>::type,
63                 Strategy
64             >::type segment_strategy;
65 
66         typename point_type<Segment>::type p[2];
67         geometry::detail::assign_point_from_index<0>(segment, p[0]);
68         geometry::detail::assign_point_from_index<1>(segment, p[1]);
69         return segment_strategy.apply(point, p[0], p[1]);
70     }
71 };
72 
73 
74 }} // namespace detail::distance
75 #endif // DOXYGEN_NO_DETAIL
76 
77 
78 
79 
80 #ifndef DOXYGEN_NO_DISPATCH
81 namespace dispatch
82 {
83 
84 
85 // Point-segment version 1, with point-point strategy
86 template <typename Point, typename Segment, typename Strategy>
87 struct distance
88 <
89     Point, Segment, Strategy,
90     point_tag, segment_tag, strategy_tag_distance_point_point,
91     false
92 > : detail::distance::point_to_segment<Point, Segment, Strategy>
93 {};
94 
95 
96 // Point-line version 1, where point-point strategy is specified
97 template <typename Point, typename Linestring, typename Strategy>
98 struct distance
99 <
100     Point, Linestring, Strategy,
101     point_tag, linestring_tag, strategy_tag_distance_point_point,
102     false
103 >
104 {
105 
106     static inline typename strategy::distance::services::return_type
107         <
108             Strategy, Point, typename point_type<Linestring>::type
109         >::type
applyboost::geometry::dispatch::distance110     apply(Point const& point,
111           Linestring const& linestring,
112           Strategy const&)
113     {
114         typedef typename detail::distance::default_ps_strategy
115                     <
116                         Point,
117                         typename point_type<Linestring>::type,
118                         Strategy
119                     >::type ps_strategy_type;
120 
121         return detail::distance::point_to_range
122             <
123                 Point, Linestring, closed, ps_strategy_type
124             >::apply(point, linestring, ps_strategy_type());
125     }
126 };
127 
128 
129 // Point-ring , where point-point strategy is specified
130 template <typename Point, typename Ring, typename Strategy>
131 struct distance
132 <
133     Point, Ring, Strategy,
134     point_tag, ring_tag, strategy_tag_distance_point_point,
135     false
136 >
137 {
138     typedef typename strategy::distance::services::return_type
139         <
140             Strategy, Point, typename point_type<Ring>::type
141         >::type return_type;
142 
applyboost::geometry::dispatch::distance143     static inline return_type apply(Point const& point,
144             Ring const& ring,
145             Strategy const&)
146     {
147         typedef typename detail::distance::default_ps_strategy
148             <
149                 Point,
150                 typename point_type<Ring>::type,
151                 Strategy
152             >::type ps_strategy_type;
153 
154         return detail::distance::point_to_ring
155             <
156                 Point, Ring,
157                 geometry::closure<Ring>::value,
158                 ps_strategy_type
159             >::apply(point, ring, ps_strategy_type());
160     }
161 };
162 
163 
164 // Point-polygon , where point-point strategy is specified
165 template <typename Point, typename Polygon, typename Strategy>
166 struct distance
167 <
168     Point, Polygon, Strategy,
169     point_tag, polygon_tag, strategy_tag_distance_point_point,
170     false
171 >
172 {
173     typedef typename strategy::distance::services::return_type
174         <
175             Strategy, Point, typename point_type<Polygon>::type
176         >::type return_type;
177 
applyboost::geometry::dispatch::distance178     static inline return_type apply(Point const& point,
179                                     Polygon const& polygon,
180                                     Strategy const&)
181     {
182         typedef typename detail::distance::default_ps_strategy
183             <
184                 Point,
185                 typename point_type<Polygon>::type,
186                 Strategy
187             >::type ps_strategy_type;
188 
189         return detail::distance::point_to_polygon
190             <
191                 Point,
192                 Polygon,
193                 geometry::closure<Polygon>::value,
194                 ps_strategy_type
195             >::apply(point, polygon, ps_strategy_type());
196     }
197 };
198 
199 
200 
201 
202 template
203 <
204     typename Point,
205     typename MultiGeometry,
206     typename MultiGeometryTag,
207     typename Strategy
208 >
209 struct distance
210     <
211         Point, MultiGeometry, Strategy,
212         point_tag, MultiGeometryTag,
213         strategy_tag_distance_point_point, false
214     >
215 {
216     typedef typename strategy::distance::services::return_type
217         <
218             Strategy, Point, typename point_type<MultiGeometry>::type
219         >::type return_type;
220 
applyboost::geometry::dispatch::distance221     static inline return_type apply(Point const& point,
222                                     MultiGeometry const& multigeometry,
223                                     Strategy const&)
224     {
225         typedef typename detail::distance::default_ps_strategy
226             <
227                 Point,
228                 typename point_type<MultiGeometry>::type,
229                 Strategy
230             >::type ps_strategy_type;
231 
232         return distance
233             <
234                 Point, MultiGeometry, ps_strategy_type,
235                 point_tag, MultiGeometryTag,
236                 strategy_tag_distance_point_segment, false
237             >::apply(point, multigeometry, ps_strategy_type());
238     }
239 };
240 
241 
242 template
243 <
244     typename Geometry,
245     typename MultiPoint,
246     typename GeometryTag,
247     typename Strategy
248 >
249 struct distance
250     <
251         Geometry, MultiPoint, Strategy,
252         GeometryTag, multi_point_tag,
253         strategy_tag_distance_point_point, false
254     >
255 {
256     typedef typename strategy::distance::services::return_type
257         <
258             Strategy,
259             typename point_type<MultiPoint>::type,
260             typename point_type<Geometry>::type
261         >::type return_type;
262 
applyboost::geometry::dispatch::distance263     static inline return_type apply(Geometry const& geometry,
264                                     MultiPoint const& multipoint,
265                                     Strategy const&)
266     {
267         typedef typename detail::distance::default_ps_strategy
268             <
269                 typename point_type<MultiPoint>::type,
270                 typename point_type<Geometry>::type,
271                 Strategy
272             >::type ps_strategy_type;
273 
274         return distance
275             <
276                 Geometry, MultiPoint, ps_strategy_type,
277                 GeometryTag, multi_point_tag,
278                 strategy_tag_distance_point_segment, false
279             >::apply(geometry, multipoint, ps_strategy_type());
280     }
281 };
282 
283 
284 template
285 <
286     typename MultiPoint,
287     typename MultiGeometry,
288     typename MultiGeometryTag,
289     typename Strategy
290 >
291 struct distance
292     <
293         MultiPoint, MultiGeometry, Strategy,
294         multi_point_tag, MultiGeometryTag,
295         strategy_tag_distance_point_point, false
296     >
297 {
298     typedef typename strategy::distance::services::return_type
299         <
300             Strategy,
301             typename point_type<MultiPoint>::type,
302             typename point_type<MultiGeometry>::type
303         >::type return_type;
304 
applyboost::geometry::dispatch::distance305     static inline return_type apply(MultiPoint const& multipoint,
306                                     MultiGeometry const& multigeometry,
307                                     Strategy const&)
308     {
309         typedef typename detail::distance::default_ps_strategy
310             <
311                 typename point_type<MultiPoint>::type,
312                 typename point_type<MultiGeometry>::type,
313                 Strategy
314             >::type ps_strategy_type;
315 
316         return distance
317             <
318                 MultiPoint, MultiGeometry, ps_strategy_type,
319                 multi_point_tag, MultiGeometryTag,
320                 strategy_tag_distance_point_segment, false
321             >::apply(multipoint, multigeometry, ps_strategy_type());
322     }
323 };
324 
325 
326 } // namespace dispatch
327 #endif // DOXYGEN_NO_DISPATCH
328 
329 
330 }} // namespace boost::geometry
331 
332 
333 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_BACKWARD_COMPATIBILITY_HPP
334