1 // Boost.Geometry 2 3 // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. 4 5 // This file was modified by Oracle on 2014-2019. 6 // Modifications copyright (c) 2014-2019 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 22 #include <boost/geometry/formulas/spherical.hpp> 23 24 #include <boost/geometry/srs/spheroid.hpp> 25 26 #include <boost/geometry/util/math.hpp> 27 #include <boost/geometry/util/promote_floating_point.hpp> 28 #include <boost/geometry/util/select_calculation_type.hpp> 29 30 #include <boost/geometry/strategies/geographic/disjoint_segment_box.hpp> 31 #include <boost/geometry/strategies/geographic/envelope.hpp> 32 #include <boost/geometry/strategies/geographic/parameters.hpp> 33 #include <boost/geometry/strategies/side.hpp> 34 #include <boost/geometry/strategies/spherical/point_in_point.hpp> 35 //#include <boost/geometry/strategies/concepts/side_concept.hpp> 36 37 38 namespace boost { namespace geometry 39 { 40 41 42 namespace strategy { namespace side 43 { 44 45 46 /*! 47 \brief Check at which side of a segment a point lies 48 left of segment (> 0), right of segment (< 0), on segment (0) 49 \ingroup strategies 50 \tparam FormulaPolicy Geodesic solution formula policy. 51 \tparam Spheroid Reference model of coordinate system. 52 \tparam CalculationType \tparam_calculation 53 54 \qbk{ 55 [heading See also] 56 [link geometry.reference.srs.srs_spheroid srs::spheroid] 57 } 58 */ 59 template 60 < 61 typename FormulaPolicy = strategy::andoyer, 62 typename Spheroid = srs::spheroid<double>, 63 typename CalculationType = void 64 > 65 class geographic 66 { 67 public: 68 typedef geographic_tag cs_tag; 69 70 typedef strategy::envelope::geographic 71 < 72 FormulaPolicy, 73 Spheroid, 74 CalculationType 75 > envelope_strategy_type; 76 get_envelope_strategy() const77 inline envelope_strategy_type get_envelope_strategy() const 78 { 79 return envelope_strategy_type(m_model); 80 } 81 82 typedef strategy::disjoint::segment_box_geographic 83 < 84 FormulaPolicy, 85 Spheroid, 86 CalculationType 87 > disjoint_strategy_type; 88 get_disjoint_strategy() const89 inline disjoint_strategy_type get_disjoint_strategy() const 90 { 91 return disjoint_strategy_type(m_model); 92 } 93 94 typedef strategy::within::spherical_point_point equals_point_point_strategy_type; get_equals_point_point_strategy()95 static inline equals_point_point_strategy_type get_equals_point_point_strategy() 96 { 97 return equals_point_point_strategy_type(); 98 } 99 geographic()100 geographic() 101 {} 102 geographic(Spheroid const & model)103 explicit geographic(Spheroid const& model) 104 : m_model(model) 105 {} 106 107 template <typename P1, typename P2, typename P> apply(P1 const & p1,P2 const & p2,P const & p) const108 inline int apply(P1 const& p1, P2 const& p2, P const& p) const 109 { 110 typedef typename promote_floating_point 111 < 112 typename select_calculation_type_alt 113 < 114 CalculationType, 115 P1, P2, P 116 >::type 117 >::type calc_t; 118 119 typedef typename FormulaPolicy::template inverse 120 <calc_t, false, true, false, false, false> inverse_formula; 121 122 calc_t a1p = azimuth<calc_t, inverse_formula>(p1, p, m_model); 123 calc_t a12 = azimuth<calc_t, inverse_formula>(p1, p2, m_model); 124 125 return formula::azimuth_side_value(a1p, a12); 126 } 127 model() const128 Spheroid const& model() const 129 { 130 return m_model; 131 } 132 133 private: 134 template <typename ResultType, 135 typename InverseFormulaType, 136 typename Point1, 137 typename Point2, 138 typename ModelT> azimuth(Point1 const & point1,Point2 const & point2,ModelT const & model)139 static inline ResultType azimuth(Point1 const& point1, Point2 const& point2, 140 ModelT const& model) 141 { 142 return InverseFormulaType::apply(get_as_radian<0>(point1), 143 get_as_radian<1>(point1), 144 get_as_radian<0>(point2), 145 get_as_radian<1>(point2), 146 model).azimuth; 147 } 148 149 Spheroid m_model; 150 }; 151 152 153 }} // namespace strategy::side 154 155 156 }} // namespace boost::geometry 157 158 159 #endif // BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_SIDE_HPP 160