1 // Boost.Geometry
2 
3 // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
4 
5 // This file was modified by Oracle on 2014-2017.
6 // Modifications copyright (c) 2014-2017 Oracle and/or its affiliates.
7 
8 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
9 
10 // Use, modification and distribution is subject to the Boost Software License,
11 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
12 // http://www.boost.org/LICENSE_1_0.txt)
13 
14 #ifndef BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_SIDE_HPP
15 #define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_SIDE_HPP
16 
17 #include <boost/geometry/core/cs.hpp>
18 #include <boost/geometry/core/access.hpp>
19 #include <boost/geometry/core/radian_access.hpp>
20 #include <boost/geometry/core/radius.hpp>
21 #include <boost/geometry/core/srs.hpp>
22 
23 #include <boost/geometry/formulas/spherical.hpp>
24 
25 #include <boost/geometry/util/math.hpp>
26 #include <boost/geometry/util/promote_floating_point.hpp>
27 #include <boost/geometry/util/select_calculation_type.hpp>
28 
29 #include <boost/geometry/strategies/geographic/disjoint_segment_box.hpp>
30 #include <boost/geometry/strategies/geographic/envelope_segment.hpp>
31 #include <boost/geometry/strategies/geographic/parameters.hpp>
32 #include <boost/geometry/strategies/side.hpp>
33 //#include <boost/geometry/strategies/concepts/side_concept.hpp>
34 
35 
36 namespace boost { namespace geometry
37 {
38 
39 
40 namespace strategy { namespace side
41 {
42 
43 
44 /*!
45 \brief Check at which side of a segment a point lies
46          left of segment (> 0), right of segment (< 0), on segment (0)
47 \ingroup strategies
48 \tparam FormulaPolicy Geodesic solution formula policy.
49 \tparam Spheroid Reference model of coordinate system.
50 \tparam CalculationType \tparam_calculation
51  */
52 template
53 <
54     typename FormulaPolicy = strategy::andoyer,
55     typename Spheroid = srs::spheroid<double>,
56     typename CalculationType = void
57 >
58 class geographic
59 {
60 public:
61     typedef strategy::envelope::geographic_segment
62         <
63             FormulaPolicy,
64             Spheroid,
65             CalculationType
66         > envelope_strategy_type;
67 
get_envelope_strategy() const68     inline envelope_strategy_type get_envelope_strategy() const
69     {
70         return envelope_strategy_type(m_model);
71     }
72 
73     typedef strategy::disjoint::segment_box_geographic
74         <
75             FormulaPolicy,
76             Spheroid,
77             CalculationType
78         > disjoint_strategy_type;
79 
get_disjoint_strategy() const80     inline disjoint_strategy_type get_disjoint_strategy() const
81     {
82         return disjoint_strategy_type(m_model);
83     }
84 
geographic()85     geographic()
86     {}
87 
geographic(Spheroid const & model)88     explicit geographic(Spheroid const& model)
89         : m_model(model)
90     {}
91 
92     template <typename P1, typename P2, typename P>
apply(P1 const & p1,P2 const & p2,P const & p) const93     inline int apply(P1 const& p1, P2 const& p2, P const& p) const
94     {
95         typedef typename promote_floating_point
96             <
97                 typename select_calculation_type_alt
98                     <
99                         CalculationType,
100                         P1, P2, P
101                     >::type
102             >::type calc_t;
103 
104         typedef typename FormulaPolicy::template inverse
105                     <calc_t, false, true, false, false, false> inverse_formula;
106 
107         calc_t a1p = azimuth<calc_t, inverse_formula>(p1, p, m_model);
108         calc_t a12 = azimuth<calc_t, inverse_formula>(p1, p2, m_model);
109 
110         return formula::azimuth_side_value(a1p, a12);
111     }
112 
113 private:
114     template <typename ResultType,
115               typename InverseFormulaType,
116               typename Point1,
117               typename Point2,
118               typename ModelT>
azimuth(Point1 const & point1,Point2 const & point2,ModelT const & model)119     static inline ResultType azimuth(Point1 const& point1, Point2 const& point2,
120                                      ModelT const& model)
121     {
122         return InverseFormulaType::apply(get_as_radian<0>(point1),
123                                          get_as_radian<1>(point1),
124                                          get_as_radian<0>(point2),
125                                          get_as_radian<1>(point2),
126                                          model).azimuth;
127     }
128 
129     Spheroid m_model;
130 };
131 
132 
133 }} // namespace strategy::side
134 
135 
136 }} // namespace boost::geometry
137 
138 
139 #endif // BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_SIDE_HPP
140