1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2
3 // Copyright (c) 2015 Barend Gehrels, Amsterdam, the Netherlands.
4
5 // This file was modified by Oracle on 2015, 2017, 2018.
6 // Modifications copyright (c) 2015-2018, 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_ALGORITHMS_DETAIL_SECTIONS_FUNCTIONS_HPP
15 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_SECTIONS_FUNCTIONS_HPP
16
17
18 #include <boost/geometry/core/access.hpp>
19 #include <boost/geometry/algorithms/detail/recalculate.hpp>
20 #include <boost/geometry/policies/robustness/robust_point_type.hpp>
21
22 // For spherical/geographic longitudes covered_by point/box
23 #include <boost/geometry/strategies/cartesian/point_in_box.hpp>
24
25 #include <boost/geometry/util/select_coordinate_type.hpp>
26
27
28 namespace boost { namespace geometry
29 {
30
31 #ifndef DOXYGEN_NO_DETAIL
32 namespace detail { namespace section
33 {
34
35 // TODO: This code is CS-specific, should be moved to strategies
36
37 template
38 <
39 std::size_t Dimension,
40 typename Geometry,
41 typename CastedCSTag = typename tag_cast
42 <
43 typename cs_tag<Geometry>::type,
44 spherical_tag
45 >::type
46 >
47 struct preceding_check
48 {
49 template <typename Point, typename Box>
applyboost::geometry::detail::section::preceding_check50 static inline bool apply(int dir, Point const& point, Box const& /*point_box*/, Box const& other_box)
51 {
52 return (dir == 1 && get<Dimension>(point) < get<min_corner, Dimension>(other_box))
53 || (dir == -1 && get<Dimension>(point) > get<max_corner, Dimension>(other_box));
54 }
55 };
56
57 template <typename Geometry>
58 struct preceding_check<0, Geometry, spherical_tag>
59 {
60 template <typename Point, typename Box>
applyboost::geometry::detail::section::preceding_check61 static inline bool apply(int dir, Point const& point, Box const& point_box, Box const& other_box)
62 {
63 typedef typename select_coordinate_type
64 <
65 Point, Box
66 >::type calc_t;
67 typedef typename coordinate_system<Point>::type::units units_t;
68
69 calc_t const c0 = 0;
70
71 calc_t const value = get<0>(point);
72 calc_t const other_min = get<min_corner, 0>(other_box);
73 calc_t const other_max = get<max_corner, 0>(other_box);
74
75 bool const pt_covered = strategy::within::detail::covered_by_range
76 <
77 Point, 0, spherical_tag
78 >::apply(value,
79 other_min,
80 other_max);
81
82 if (pt_covered)
83 {
84 return false;
85 }
86
87 if (dir == 1)
88 {
89 calc_t const diff_min = math::longitude_distance_signed
90 <
91 units_t, calc_t
92 >(other_min, value);
93
94 calc_t const diff_min_min = math::longitude_distance_signed
95 <
96 units_t, calc_t
97 >(other_min, get<min_corner, 0>(point_box));
98
99 return diff_min < c0 && diff_min_min <= c0 && diff_min_min <= diff_min;
100 }
101 else if (dir == -1)
102 {
103 calc_t const diff_max = math::longitude_distance_signed
104 <
105 units_t, calc_t
106 >(other_max, value);
107
108 calc_t const diff_max_max = math::longitude_distance_signed
109 <
110 units_t, calc_t
111 >(other_max, get<max_corner, 0>(point_box));
112
113 return diff_max > c0 && diff_max_max >= c0 && diff_max <= diff_max_max;
114 }
115
116 return false;
117 }
118 };
119
120
121 template
122 <
123 std::size_t Dimension,
124 typename Point,
125 typename RobustBox,
126 typename RobustPolicy
127 >
preceding(int dir,Point const & point,RobustBox const & point_robust_box,RobustBox const & other_robust_box,RobustPolicy const & robust_policy)128 static inline bool preceding(int dir,
129 Point const& point,
130 RobustBox const& point_robust_box,
131 RobustBox const& other_robust_box,
132 RobustPolicy const& robust_policy)
133 {
134 typename geometry::robust_point_type<Point, RobustPolicy>::type robust_point;
135 geometry::recalculate(robust_point, point, robust_policy);
136 return preceding_check<Dimension, Point>::apply(dir, robust_point, point_robust_box, other_robust_box);
137 }
138
139 template
140 <
141 std::size_t Dimension,
142 typename Point,
143 typename RobustBox,
144 typename RobustPolicy
145 >
exceeding(int dir,Point const & point,RobustBox const & point_robust_box,RobustBox const & other_robust_box,RobustPolicy const & robust_policy)146 static inline bool exceeding(int dir,
147 Point const& point,
148 RobustBox const& point_robust_box,
149 RobustBox const& other_robust_box,
150 RobustPolicy const& robust_policy)
151 {
152 return preceding<Dimension>(-dir, point, point_robust_box, other_robust_box, robust_policy);
153 }
154
155
156 }} // namespace detail::section
157 #endif
158
159
160 }} // namespace boost::geometry
161
162 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_SECTIONS_FUNCTIONS_HPP
163