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, 2014, 2015, 2017.
9 // Modifications copyright (c) 2013-2017, 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_ALGORITHMS_DETAIL_DISJOINT_POINT_POINT_HPP
22 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_POINT_POINT_HPP
23
24 #include <cstddef>
25
26 #include <boost/type_traits/is_same.hpp>
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/util/math.hpp>
37 #include <boost/geometry/util/select_most_precise.hpp>
38
39 #include <boost/geometry/strategies/strategy_transform.hpp>
40
41 #include <boost/geometry/geometries/helper_geometry.hpp>
42
43 #include <boost/geometry/algorithms/transform.hpp>
44
45 #include <boost/geometry/algorithms/detail/normalize.hpp>
46
47 #include <boost/geometry/algorithms/dispatch/disjoint.hpp>
48
49
50 namespace boost { namespace geometry
51 {
52
53
54 #ifndef DOXYGEN_NO_DETAIL
55 namespace detail { namespace disjoint
56 {
57
58
59 template <std::size_t Dimension, std::size_t DimensionCount>
60 struct point_point_generic
61 {
62 template <typename Point1, typename Point2, typename Strategy>
applyboost::geometry::detail::disjoint::point_point_generic63 static inline bool apply(Point1 const& p1, Point2 const& p2, Strategy const& )
64 {
65 return apply(p1, p2);
66 }
67
68 template <typename Point1, typename Point2>
applyboost::geometry::detail::disjoint::point_point_generic69 static inline bool apply(Point1 const& p1, Point2 const& p2)
70 {
71 if (! geometry::math::equals(get<Dimension>(p1), get<Dimension>(p2)))
72 {
73 return true;
74 }
75 return
76 point_point_generic<Dimension + 1, DimensionCount>::apply(p1, p2);
77 }
78 };
79
80 template <std::size_t DimensionCount>
81 struct point_point_generic<DimensionCount, DimensionCount>
82 {
83 template <typename Point1, typename Point2>
applyboost::geometry::detail::disjoint::point_point_generic84 static inline bool apply(Point1 const&, Point2 const& )
85 {
86 return false;
87 }
88 };
89
90
91 class point_point_on_spheroid
92 {
93 private:
94 template <typename Point1, typename Point2, bool SameUnits>
95 struct are_same_points
96 {
applyboost::geometry::detail::disjoint::point_point_on_spheroid::are_same_points97 static inline bool apply(Point1 const& point1, Point2 const& point2)
98 {
99 typedef typename helper_geometry<Point1>::type helper_point_type1;
100 typedef typename helper_geometry<Point2>::type helper_point_type2;
101
102 helper_point_type1 point1_normalized
103 = return_normalized<helper_point_type1>(point1);
104 helper_point_type2 point2_normalized
105 = return_normalized<helper_point_type2>(point2);
106
107 return point_point_generic
108 <
109 0, dimension<Point1>::value
110 >::apply(point1_normalized, point2_normalized);
111 }
112 };
113
114 template <typename Point1, typename Point2>
115 struct are_same_points<Point1, Point2, false> // points have different units
116 {
applyboost::geometry::detail::disjoint::point_point_on_spheroid::are_same_points117 static inline bool apply(Point1 const& point1, Point2 const& point2)
118 {
119 typedef typename geometry::select_most_precise
120 <
121 typename fp_coordinate_type<Point1>::type,
122 typename fp_coordinate_type<Point2>::type
123 >::type calculation_type;
124
125 typename helper_geometry
126 <
127 Point1, calculation_type, radian
128 >::type helper_point1, helper_point2;
129
130 Point1 point1_normalized = return_normalized<Point1>(point1);
131 Point2 point2_normalized = return_normalized<Point2>(point2);
132
133 geometry::transform(point1_normalized, helper_point1);
134 geometry::transform(point2_normalized, helper_point2);
135
136 return point_point_generic
137 <
138 0, dimension<Point1>::value
139 >::apply(helper_point1, helper_point2);
140 }
141 };
142
143 public:
144 template <typename Point1, typename Point2, typename Strategy>
apply(Point1 const & point1,Point2 const & point2,Strategy const &)145 static inline bool apply(Point1 const& point1, Point2 const& point2, Strategy const& )
146 {
147 return apply(point1, point2);
148 }
149
150 template <typename Point1, typename Point2>
apply(Point1 const & point1,Point2 const & point2)151 static inline bool apply(Point1 const& point1, Point2 const& point2)
152 {
153 return are_same_points
154 <
155 Point1,
156 Point2,
157 boost::is_same
158 <
159 typename coordinate_system<Point1>::type::units,
160 typename coordinate_system<Point2>::type::units
161 >::value
162 >::apply(point1, point2);
163 }
164 };
165
166
167 template
168 <
169 typename Point1, typename Point2,
170 std::size_t Dimension, std::size_t DimensionCount,
171 typename CSTag1 = typename cs_tag<Point1>::type,
172 typename CSTag2 = CSTag1
173 >
174 struct point_point
175 : point_point<Point1, Point2, Dimension, DimensionCount, cartesian_tag>
176 {};
177
178 template
179 <
180 typename Point1, typename Point2,
181 std::size_t Dimension, std::size_t DimensionCount
182 >
183 struct point_point
184 <
185 Point1, Point2, Dimension, DimensionCount, spherical_equatorial_tag
186 > : point_point_on_spheroid
187 {};
188
189 template
190 <
191 typename Point1, typename Point2,
192 std::size_t Dimension, std::size_t DimensionCount
193 >
194 struct point_point
195 <
196 Point1, Point2, Dimension, DimensionCount, geographic_tag
197 > : point_point_on_spheroid
198 {};
199
200 template
201 <
202 typename Point1, typename Point2,
203 std::size_t Dimension, std::size_t DimensionCount
204 >
205 struct point_point<Point1, Point2, Dimension, DimensionCount, cartesian_tag>
206 : point_point_generic<Dimension, DimensionCount>
207 {};
208
209
210 /*!
211 \brief Internal utility function to detect of points are disjoint
212 \note To avoid circular references
213 */
214 template <typename Point1, typename Point2>
disjoint_point_point(Point1 const & point1,Point2 const & point2)215 inline bool disjoint_point_point(Point1 const& point1, Point2 const& point2)
216 {
217 return point_point
218 <
219 Point1, Point2,
220 0, dimension<Point1>::type::value
221 >::apply(point1, point2);
222 }
223
224
225 }} // namespace detail::disjoint
226 #endif // DOXYGEN_NO_DETAIL
227
228
229
230
231 #ifndef DOXYGEN_NO_DISPATCH
232 namespace dispatch
233 {
234
235
236 template <typename Point1, typename Point2, std::size_t DimensionCount>
237 struct disjoint<Point1, Point2, DimensionCount, point_tag, point_tag, false>
238 : detail::disjoint::point_point<Point1, Point2, 0, DimensionCount>
239 {};
240
241
242 } // namespace dispatch
243 #endif // DOXYGEN_NO_DISPATCH
244
245 }} // namespace boost::geometry
246
247 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_POINT_POINT_HPP
248