1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2 
3 // Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
4 // Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
5 // Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
6 // Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland
7 
8 // This file was modified by Oracle on 2013-2020.
9 // Modifications copyright (c) 2013-2020, Oracle and/or its affiliates.
10 
11 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
12 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
13 
14 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
15 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
16 
17 // Use, modification and distribution is subject to the Boost Software License,
18 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
19 // http://www.boost.org/LICENSE_1_0.txt)
20 
21 #ifndef BOOST_GEOMETRY_STRATEGY_SPHERICAL_POINT_IN_POINT_HPP
22 #define BOOST_GEOMETRY_STRATEGY_SPHERICAL_POINT_IN_POINT_HPP
23 
24 
25 #include <cstddef>
26 #include <type_traits>
27 
28 #include <boost/geometry/core/access.hpp>
29 #include <boost/geometry/core/radian_access.hpp>
30 #include <boost/geometry/core/coordinate_dimension.hpp>
31 #include <boost/geometry/core/coordinate_system.hpp>
32 #include <boost/geometry/core/coordinate_type.hpp>
33 #include <boost/geometry/core/cs.hpp>
34 #include <boost/geometry/core/tags.hpp>
35 
36 #include <boost/geometry/algorithms/detail/normalize.hpp>
37 #include <boost/geometry/algorithms/dispatch/disjoint.hpp>
38 #include <boost/geometry/algorithms/transform.hpp>
39 
40 #include <boost/geometry/geometries/helper_geometry.hpp>
41 
42 #include <boost/geometry/strategies/cartesian/point_in_point.hpp>
43 #include <boost/geometry/strategies/covered_by.hpp>
44 #include <boost/geometry/strategies/strategy_transform.hpp>
45 #include <boost/geometry/strategies/within.hpp>
46 
47 #include <boost/geometry/util/math.hpp>
48 #include <boost/geometry/util/select_most_precise.hpp>
49 
50 
51 namespace boost { namespace geometry
52 {
53 
54 #ifndef DOXYGEN_NO_DETAIL
55 namespace detail { namespace within
56 {
57 
58 class point_point_on_spheroid
59 {
60 public:
61     typedef spherical_tag cs_tag;
62 
63 private:
64     template <typename Point1, typename Point2, bool SameUnits>
65     struct are_same_points
66     {
applyboost::geometry::detail::within::point_point_on_spheroid::are_same_points67         static inline bool apply(Point1 const& point1, Point2 const& point2)
68         {
69             typedef typename helper_geometry<Point1>::type helper_point_type1;
70             typedef typename helper_geometry<Point2>::type helper_point_type2;
71 
72             helper_point_type1 point1_normalized;
73             strategy::normalize::spherical_point::apply(point1, point1_normalized);
74             helper_point_type2 point2_normalized;
75             strategy::normalize::spherical_point::apply(point2, point2_normalized);
76 
77             return point_point_generic
78                 <
79                     0, dimension<Point1>::value
80                 >::apply(point1_normalized, point2_normalized);
81         }
82     };
83 
84     template <typename Point1, typename Point2>
85     struct are_same_points<Point1, Point2, false> // points have different units
86     {
applyboost::geometry::detail::within::point_point_on_spheroid::are_same_points87         static inline bool apply(Point1 const& point1, Point2 const& point2)
88         {
89             typedef typename geometry::select_most_precise
90                 <
91                     typename fp_coordinate_type<Point1>::type,
92                     typename fp_coordinate_type<Point2>::type
93                 >::type calculation_type;
94 
95             typename helper_geometry
96                 <
97                     Point1, calculation_type, radian
98                 >::type helper_point1, helper_point2;
99 
100             Point1 point1_normalized;
101             strategy::normalize::spherical_point::apply(point1, point1_normalized);
102             Point2 point2_normalized;
103             strategy::normalize::spherical_point::apply(point2, point2_normalized);
104 
105             geometry::transform(point1_normalized, helper_point1);
106             geometry::transform(point2_normalized, helper_point2);
107 
108             return point_point_generic
109                 <
110                     0, dimension<Point1>::value
111                 >::apply(helper_point1, helper_point2);
112         }
113     };
114 
115 public:
116     template <typename Point1, typename Point2>
apply(Point1 const & point1,Point2 const & point2)117     static inline bool apply(Point1 const& point1, Point2 const& point2)
118     {
119         return are_same_points
120             <
121                 Point1,
122                 Point2,
123                 std::is_same
124                     <
125                         typename detail::cs_angular_units<Point1>::type,
126                         typename detail::cs_angular_units<Point2>::type
127                     >::value
128             >::apply(point1, point2);
129     }
130 };
131 
132 }} // namespace detail::within
133 #endif // DOXYGEN_NO_DETAIL
134 
135 
136 namespace strategy { namespace within
137 {
138 
139 struct spherical_point_point
140     : geometry::detail::within::point_point_on_spheroid
141 {};
142 
143 
144 #ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
145 namespace services
146 {
147 
148 template <typename PointLike1, typename PointLike2, typename Tag1, typename Tag2>
149 struct default_strategy<PointLike1, PointLike2, Tag1, Tag2, pointlike_tag, pointlike_tag, spherical_tag, spherical_tag>
150 {
151     typedef strategy::within::spherical_point_point type;
152 };
153 
154 } // namespace services
155 #endif
156 
157 
158 }} // namespace strategy::within
159 
160 
161 #ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
162 namespace strategy { namespace covered_by { namespace services
163 {
164 
165 template <typename PointLike1, typename PointLike2, typename Tag1, typename Tag2>
166 struct default_strategy<PointLike1, PointLike2, Tag1, Tag2, pointlike_tag, pointlike_tag, spherical_tag, spherical_tag>
167 {
168     typedef strategy::within::spherical_point_point type;
169 };
170 
171 }}} // namespace strategy::covered_by::services
172 #endif
173 
174 
175 }} // namespace boost::geometry
176 
177 
178 #endif // BOOST_GEOMETRY_STRATEGY_SPHERICAL_POINT_IN_POINT_HPP
179