1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2 
3 // Copyright (c) 2018-2021 Oracle and/or its affiliates.
4 // Contributed and/or modified by Vissarion Fisikopoulos, on behalf of Oracle
5 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
6 
7 // Use, modification and distribution is subject to the Boost Software License,
8 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
9 // http://www.boost.org/LICENSE_1_0.txt)
10 
11 #ifndef BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_DISTANCE_SEGMENT_BOX_HPP
12 #define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_DISTANCE_SEGMENT_BOX_HPP
13 
14 #include <boost/geometry/srs/spheroid.hpp>
15 
16 #include <boost/geometry/core/coordinate_promotion.hpp>
17 
18 #include <boost/geometry/algorithms/detail/distance/segment_to_box.hpp>
19 
20 #include <boost/geometry/strategies/distance.hpp>
21 #include <boost/geometry/strategies/geographic/azimuth.hpp>
22 #include <boost/geometry/strategies/geographic/distance_cross_track.hpp>
23 #include <boost/geometry/strategies/geographic/distance_cross_track_point_box.hpp>
24 #include <boost/geometry/strategies/geographic/parameters.hpp>
25 #include <boost/geometry/strategies/geographic/side.hpp>
26 #include <boost/geometry/strategies/normalize.hpp>
27 #include <boost/geometry/strategies/spherical/disjoint_box_box.hpp>
28 #include <boost/geometry/strategies/spherical/distance_segment_box.hpp>
29 #include <boost/geometry/strategies/spherical/point_in_point.hpp>
30 
31 #include <boost/geometry/util/select_calculation_type.hpp>
32 
33 namespace boost { namespace geometry
34 {
35 
36 
37 namespace strategy { namespace distance
38 {
39 
40 template
41 <
42     typename FormulaPolicy = strategy::andoyer,
43     typename Spheroid = srs::spheroid<double>,
44     typename CalculationType = void
45 >
46 struct geographic_segment_box
47 {
48     template <typename PointOfSegment, typename PointOfBox>
49     struct return_type
50         : promote_floating_point
51           <
52               typename select_calculation_type
53                   <
54                       PointOfSegment,
55                       PointOfBox,
56                       CalculationType
57                   >::type
58           >
59     {};
60 
61     typedef geographic_tag cs_tag;
62 
63     //constructor
64 
geographic_segment_boxboost::geometry::strategy::distance::geographic_segment_box65     explicit geographic_segment_box(Spheroid const& spheroid = Spheroid())
66              : m_spheroid(spheroid)
67     {}
68 
modelboost::geometry::strategy::distance::geographic_segment_box69     Spheroid model() const
70     {
71         return m_spheroid;
72     }
73 
74     // methods
75 
76     template
77     <
78         typename LessEqual, typename ReturnType,
79         typename SegmentPoint, typename BoxPoint,
80         typename Strategies
81     >
segment_below_of_boxboost::geometry::strategy::distance::geographic_segment_box82     inline ReturnType segment_below_of_box(SegmentPoint const& p0,
83                                            SegmentPoint const& p1,
84                                            BoxPoint const& top_left,
85                                            BoxPoint const& top_right,
86                                            BoxPoint const& bottom_left,
87                                            BoxPoint const& bottom_right,
88                                            Strategies const& strategies) const
89     {
90         return generic_segment_box::segment_below_of_box
91                <
92                     LessEqual,
93                     ReturnType
94                >(p0,p1,top_left,top_right,bottom_left,bottom_right,
95                  strategies);
96     }
97 
98     template <typename SPoint, typename BPoint>
mirrorboost::geometry::strategy::distance::geographic_segment_box99     static void mirror(SPoint& p0,
100                        SPoint& p1,
101                        BPoint& bottom_left,
102                        BPoint& bottom_right,
103                        BPoint& top_left,
104                        BPoint& top_right)
105     {
106 
107        generic_segment_box::mirror(p0, p1,
108                                    bottom_left, bottom_right,
109                                    top_left, top_right);
110     }
111 
112 private :
113     Spheroid m_spheroid;
114 };
115 
116 #ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
117 namespace services
118 {
119 
120 //tags
121 
122 template <typename FormulaPolicy>
123 struct tag<geographic_segment_box<FormulaPolicy> >
124 {
125     typedef strategy_tag_distance_segment_box type;
126 };
127 
128 template
129 <
130         typename FormulaPolicy,
131         typename Spheroid
132 >
133 struct tag<geographic_segment_box<FormulaPolicy, Spheroid> >
134 {
135     typedef strategy_tag_distance_segment_box type;
136 };
137 
138 template
139 <
140         typename FormulaPolicy,
141         typename Spheroid,
142         typename CalculationType
143 >
144 struct tag<geographic_segment_box<FormulaPolicy, Spheroid, CalculationType> >
145 {
146     typedef strategy_tag_distance_segment_box type;
147 };
148 
149 // return types
150 
151 template <typename FormulaPolicy, typename PS, typename PB>
152 struct return_type<geographic_segment_box<FormulaPolicy>, PS, PB>
153     : geographic_segment_box<FormulaPolicy>::template return_type<PS, PB>
154 {};
155 
156 template
157 <
158         typename FormulaPolicy,
159         typename Spheroid,
160         typename PS,
161         typename PB
162 >
163 struct return_type<geographic_segment_box<FormulaPolicy, Spheroid>, PS, PB>
164     : geographic_segment_box<FormulaPolicy, Spheroid>::template return_type<PS, PB>
165 {};
166 
167 template
168 <
169         typename FormulaPolicy,
170         typename Spheroid,
171         typename CalculationType,
172         typename PS,
173         typename PB
174 >
175 struct return_type<geographic_segment_box<FormulaPolicy, Spheroid, CalculationType>, PS, PB>
176     : geographic_segment_box<FormulaPolicy, Spheroid, CalculationType>::template return_type<PS, PB>
177 {};
178 
179 //comparable types
180 
181 template
182 <
183         typename FormulaPolicy,
184         typename Spheroid,
185         typename CalculationType
186 >
187 struct comparable_type<geographic_segment_box<FormulaPolicy, Spheroid, CalculationType> >
188 {
189     typedef geographic_segment_box
190         <
191             FormulaPolicy, Spheroid, CalculationType
192         >  type;
193 };
194 
195 template
196 <
197         typename FormulaPolicy,
198         typename Spheroid,
199         typename CalculationType
200 >
201 struct get_comparable<geographic_segment_box<FormulaPolicy, Spheroid, CalculationType> >
202 {
203     typedef typename comparable_type
204         <
205             geographic_segment_box<FormulaPolicy, Spheroid, CalculationType>
206         >::type comparable_type;
207 public :
208     static inline comparable_type
applyboost::geometry::strategy::distance::services::get_comparable209     apply(geographic_segment_box<FormulaPolicy, Spheroid, CalculationType> const& )
210     {
211         return comparable_type();
212     }
213 };
214 
215 // result from distance
216 
217 template
218 <
219     typename FormulaPolicy,
220     typename PS,
221     typename PB
222 >
223 struct result_from_distance<geographic_segment_box<FormulaPolicy>, PS, PB>
224 {
225 private :
226     typedef typename geographic_segment_box
227         <
228             FormulaPolicy
229         >::template return_type<PS, PB>::type return_type;
230 public :
231     template <typename T>
232     static inline return_type
applyboost::geometry::strategy::distance::services::result_from_distance233     apply(geographic_segment_box<FormulaPolicy> const& , T const& distance)
234     {
235         return distance;
236     }
237 };
238 
239 template
240 <
241     typename FormulaPolicy,
242     typename Spheroid,
243     typename CalculationType,
244     typename PS,
245     typename PB
246 >
247 struct result_from_distance<geographic_segment_box<FormulaPolicy, Spheroid, CalculationType>, PS, PB>
248 {
249 private :
250     typedef typename geographic_segment_box
251         <
252             FormulaPolicy, Spheroid, CalculationType
253         >::template return_type<PS, PB>::type return_type;
254 public :
255     template <typename T>
256     static inline return_type
applyboost::geometry::strategy::distance::services::result_from_distance257     apply(geographic_segment_box<FormulaPolicy, Spheroid, CalculationType> const& , T const& distance)
258     {
259         return distance;
260     }
261 };
262 
263 
264 // default strategies
265 
266 template <typename Segment, typename Box>
267 struct default_strategy
268     <
269         segment_tag, box_tag, Segment, Box,
270         geographic_tag, geographic_tag
271     >
272 {
273     typedef geographic_segment_box<> type;
274 };
275 
276 template <typename Box, typename Segment>
277 struct default_strategy
278     <
279         box_tag, segment_tag, Box, Segment,
280         geographic_tag, geographic_tag
281     >
282 {
283     typedef typename default_strategy
284         <
285             segment_tag, box_tag, Segment, Box,
286             geographic_tag, geographic_tag
287         >::type type;
288 };
289 
290 }
291 #endif
292 
293 }} // namespace strategy::distance
294 
295 }} // namespace boost::geometry
296 #endif // BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_DISTANCE_SEGMENT_BOX_HPP
297