]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/geometry/algorithms/detail/overlay/handle_self_turns.hpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / boost / geometry / algorithms / detail / overlay / handle_self_turns.hpp
CommitLineData
b32b8144
FG
1// Boost.Geometry (aka GGL, Generic Geometry Library)
2
3// Copyright (c) 2017 Barend Gehrels, Amsterdam, the Netherlands.
11fdf7f2 4// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
b32b8144 5
20effc67
TL
6// This file was modified by Oracle on 2019-2020.
7// Modifications copyright (c) 2019-2020 Oracle and/or its affiliates.
92f5a8d4
TL
8
9// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
10
b32b8144
FG
11// Use, modification and distribution is subject to the Boost Software License,
12// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
13// http://www.boost.org/LICENSE_1_0.txt)
14
15#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_HANDLE_SELF_TURNS_HPP
16#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_HANDLE_SELF_TURNS_HPP
17
20effc67
TL
18#include <boost/range/begin.hpp>
19#include <boost/range/end.hpp>
20#include <boost/range/value_type.hpp>
b32b8144
FG
21
22#include <boost/geometry/algorithms/detail/overlay/cluster_info.hpp>
23#include <boost/geometry/algorithms/detail/overlay/is_self_turn.hpp>
24#include <boost/geometry/algorithms/detail/overlay/overlay_type.hpp>
11fdf7f2 25#include <boost/geometry/algorithms/covered_by.hpp>
b32b8144
FG
26#include <boost/geometry/algorithms/within.hpp>
27
28namespace boost { namespace geometry
29{
30
31#ifndef DOXYGEN_NO_DETAIL
32namespace detail { namespace overlay
33{
34
92f5a8d4
TL
35
36template
37<
38 typename Point, typename Geometry,
39 typename Tag2 = typename geometry::tag<Geometry>::type
40>
41struct check_within_strategy
42{
43 template <typename Strategy>
44 static inline typename Strategy::template point_in_geometry_strategy<Point, Geometry>::type
45 within(Strategy const& strategy)
46 {
47 return strategy.template get_point_in_geometry_strategy<Point, Geometry>();
48 }
49
50 template <typename Strategy>
51 static inline typename Strategy::template point_in_geometry_strategy<Point, Geometry>::type
52 covered_by(Strategy const& strategy)
53 {
54 return strategy.template get_point_in_geometry_strategy<Point, Geometry>();
55 }
56};
57
58template <typename Point, typename Geometry>
59struct check_within_strategy<Point, Geometry, box_tag>
60{
61 template <typename Strategy>
62 static inline typename Strategy::within_point_box_strategy_type
63 within(Strategy const& )
64 {
65 return typename Strategy::within_point_box_strategy_type();
66 }
67
68 template <typename Strategy>
69 static inline typename Strategy::covered_by_point_box_strategy_type
70 covered_by(Strategy const&)
71 {
72 return typename Strategy::covered_by_point_box_strategy_type();
73 }
74};
75
76
11fdf7f2
TL
77template <overlay_type OverlayType>
78struct check_within
79{
92f5a8d4
TL
80 template
81 <
82 typename Turn, typename Geometry0, typename Geometry1,
83 typename UmbrellaStrategy
84 >
11fdf7f2
TL
85 static inline
86 bool apply(Turn const& turn, Geometry0 const& geometry0,
92f5a8d4 87 Geometry1 const& geometry1, UmbrellaStrategy const& strategy)
11fdf7f2 88 {
92f5a8d4
TL
89 typedef typename Turn::point_type point_type;
90
11fdf7f2
TL
91 // Operations 0 and 1 have the same source index in self-turns
92 return turn.operations[0].seg_id.source_index == 0
92f5a8d4
TL
93 ? geometry::within(turn.point, geometry1,
94 check_within_strategy<point_type, Geometry1>::within(strategy))
95 : geometry::within(turn.point, geometry0,
96 check_within_strategy<point_type, Geometry0>::within(strategy));
11fdf7f2
TL
97 }
98
99};
100
101template <>
102struct check_within<overlay_difference>
103{
92f5a8d4
TL
104 template
105 <
106 typename Turn, typename Geometry0, typename Geometry1,
107 typename UmbrellaStrategy
108 >
11fdf7f2
TL
109 static inline
110 bool apply(Turn const& turn, Geometry0 const& geometry0,
92f5a8d4 111 Geometry1 const& geometry1, UmbrellaStrategy const& strategy)
11fdf7f2 112 {
92f5a8d4
TL
113 typedef typename Turn::point_type point_type;
114
11fdf7f2
TL
115 // difference = intersection(a, reverse(b))
116 // therefore we should reverse the meaning of within for geometry1
117 return turn.operations[0].seg_id.source_index == 0
92f5a8d4
TL
118 ? ! geometry::covered_by(turn.point, geometry1,
119 check_within_strategy<point_type, Geometry1>::covered_by(strategy))
120 : geometry::within(turn.point, geometry0,
121 check_within_strategy<point_type, Geometry0>::within(strategy));
11fdf7f2
TL
122 }
123};
124
b32b8144
FG
125struct discard_turns
126{
92f5a8d4
TL
127 template
128 <
129 typename Turns, typename Clusters,
130 typename Geometry0, typename Geometry1,
131 typename Strategy
132 >
b32b8144 133 static inline
92f5a8d4
TL
134 void apply(Turns& , Clusters const& ,
135 Geometry0 const& , Geometry1 const& ,
136 Strategy const& )
b32b8144
FG
137 {}
138};
139
140template <overlay_type OverlayType, operation_type OperationType>
141struct discard_closed_turns : discard_turns {};
142
143// It is only implemented for operation_union, not in buffer
144template <>
145struct discard_closed_turns<overlay_union, operation_union>
146{
92f5a8d4
TL
147 // Point in Geometry Strategy
148 template
149 <
150 typename Turns, typename Clusters,
151 typename Geometry0, typename Geometry1,
152 typename Strategy
153 >
b32b8144 154 static inline
11fdf7f2 155 void apply(Turns& turns, Clusters const& /*clusters*/,
92f5a8d4
TL
156 Geometry0 const& geometry0, Geometry1 const& geometry1,
157 Strategy const& strategy)
b32b8144
FG
158 {
159 typedef typename boost::range_value<Turns>::type turn_type;
160
161 for (typename boost::range_iterator<Turns>::type
162 it = boost::begin(turns);
163 it != boost::end(turns);
164 ++it)
165 {
166 turn_type& turn = *it;
167
11fdf7f2
TL
168 if (! turn.discarded
169 && is_self_turn<overlay_union>(turn)
92f5a8d4
TL
170 && check_within<overlay_union>::apply(turn, geometry0,
171 geometry1, strategy))
b32b8144 172 {
11fdf7f2 173 // Turn is in the interior of other geometry
b32b8144
FG
174 turn.discarded = true;
175 }
176 }
177 }
178};
179
11fdf7f2 180template <overlay_type OverlayType>
b32b8144
FG
181struct discard_self_intersection_turns
182{
183private :
184
b32b8144
FG
185 template <typename Turns, typename Clusters>
186 static inline
187 bool is_self_cluster(signed_size_type cluster_id,
188 const Turns& turns, Clusters const& clusters)
189 {
190 typename Clusters::const_iterator cit = clusters.find(cluster_id);
191 if (cit == clusters.end())
192 {
193 return false;
194 }
195
196 cluster_info const& cinfo = cit->second;
197 for (std::set<signed_size_type>::const_iterator it
198 = cinfo.turn_indices.begin();
199 it != cinfo.turn_indices.end(); ++it)
200 {
11fdf7f2 201 if (! is_self_turn<OverlayType>(turns[*it]))
b32b8144
FG
202 {
203 return false;
204 }
205 }
206
207 return true;
208 }
209
b32b8144 210 template <typename Turns, typename Clusters,
92f5a8d4 211 typename Geometry0, typename Geometry1, typename Strategy>
b32b8144
FG
212 static inline
213 void discard_clusters(Turns& turns, Clusters const& clusters,
92f5a8d4
TL
214 Geometry0 const& geometry0, Geometry1 const& geometry1,
215 Strategy const& strategy)
b32b8144
FG
216 {
217 for (typename Clusters::const_iterator cit = clusters.begin();
218 cit != clusters.end(); ++cit)
219 {
11fdf7f2 220 signed_size_type const cluster_id = cit->first;
b32b8144
FG
221
222 // If there are only self-turns in the cluster, the cluster should
223 // be located within the other geometry, for intersection
11fdf7f2
TL
224 if (! cit->second.turn_indices.empty()
225 && is_self_cluster(cluster_id, turns, clusters))
b32b8144
FG
226 {
227 cluster_info const& cinfo = cit->second;
11fdf7f2
TL
228 signed_size_type const index = *cinfo.turn_indices.begin();
229 if (! check_within<OverlayType>::apply(turns[index],
92f5a8d4
TL
230 geometry0, geometry1,
231 strategy))
b32b8144
FG
232 {
233 // Discard all turns in cluster
11fdf7f2
TL
234 for (std::set<signed_size_type>::const_iterator sit
235 = cinfo.turn_indices.begin();
b32b8144
FG
236 sit != cinfo.turn_indices.end(); ++sit)
237 {
238 turns[*sit].discarded = true;
239 }
240 }
241 }
242 }
243 }
244
245public :
246
247 template <typename Turns, typename Clusters,
92f5a8d4 248 typename Geometry0, typename Geometry1, typename Strategy>
b32b8144
FG
249 static inline
250 void apply(Turns& turns, Clusters const& clusters,
92f5a8d4
TL
251 Geometry0 const& geometry0, Geometry1 const& geometry1,
252 Strategy const& strategy)
b32b8144 253 {
92f5a8d4 254 discard_clusters(turns, clusters, geometry0, geometry1, strategy);
b32b8144
FG
255
256 typedef typename boost::range_value<Turns>::type turn_type;
257
258 for (typename boost::range_iterator<Turns>::type
259 it = boost::begin(turns);
260 it != boost::end(turns);
261 ++it)
262 {
263 turn_type& turn = *it;
264
b32b8144
FG
265 // It is a ii self-turn
266 // Check if it is within the other geometry
11fdf7f2
TL
267 if (! turn.discarded
268 && is_self_turn<overlay_intersection>(turn)
92f5a8d4
TL
269 && ! check_within<OverlayType>::apply(turn, geometry0,
270 geometry1, strategy))
b32b8144 271 {
11fdf7f2
TL
272 // It is not within another geometry, set it as non startable.
273 // It still might be traveled (#case_recursive_boxes_70)
274 turn.operations[0].enriched.startable = false;
275 turn.operations[1].enriched.startable = false;
b32b8144
FG
276 }
277 }
278 }
279};
280
11fdf7f2 281
b32b8144
FG
282template <overlay_type OverlayType, operation_type OperationType>
283struct discard_open_turns : discard_turns {};
284
11fdf7f2 285// Handler for intersection
b32b8144
FG
286template <>
287struct discard_open_turns<overlay_intersection, operation_intersection>
11fdf7f2 288 : discard_self_intersection_turns<overlay_intersection> {};
b32b8144 289
11fdf7f2
TL
290// Handler for difference, with different meaning of 'within'
291template <>
292struct discard_open_turns<overlay_difference, operation_intersection>
293 : discard_self_intersection_turns<overlay_difference> {};
b32b8144
FG
294
295}} // namespace detail::overlay
296#endif //DOXYGEN_NO_DETAIL
297
298
299}} // namespace boost::geometry
300
301#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_HANDLE_SELF_TURNS_HPP