]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/geometry/algorithms/detail/overlay/add_rings.hpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / boost / geometry / algorithms / detail / overlay / add_rings.hpp
CommitLineData
7c673cae
FG
1// Boost.Geometry (aka GGL, Generic Geometry Library)
2
3// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
11fdf7f2
TL
4// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
5
20effc67
TL
6// This file was modified by Oracle on 2017-2020.
7// Modifications copyright (c) 2017-2020, Oracle and/or its affiliates.
11fdf7f2
TL
8
9// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
7c673cae
FG
10
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_ADD_RINGS_HPP
16#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_ADD_RINGS_HPP
17
20effc67
TL
18#include <boost/range/begin.hpp>
19#include <boost/range/end.hpp>
20#include <boost/range/value_type.hpp>
11fdf7f2 21#include <boost/throw_exception.hpp>
7c673cae
FG
22
23#include <boost/geometry/core/closure.hpp>
11fdf7f2 24#include <boost/geometry/core/exception.hpp>
7c673cae
FG
25#include <boost/geometry/algorithms/area.hpp>
26#include <boost/geometry/algorithms/detail/overlay/convert_ring.hpp>
27#include <boost/geometry/algorithms/detail/overlay/get_ring.hpp>
28
29
30namespace boost { namespace geometry
31{
32
33
34#ifndef DOXYGEN_NO_DETAIL
35namespace detail { namespace overlay
36{
37
38template
39<
40 typename GeometryOut,
41 typename Geometry1,
42 typename Geometry2,
43 typename RingCollection
44>
45inline void convert_and_add(GeometryOut& result,
46 Geometry1 const& geometry1, Geometry2 const& geometry2,
47 RingCollection const& collection,
48 ring_identifier id,
49 bool reversed, bool append)
50{
51 typedef typename geometry::tag<Geometry1>::type tag1;
52 typedef typename geometry::tag<Geometry2>::type tag2;
53 typedef typename geometry::tag<GeometryOut>::type tag_out;
54
55 if (id.source_index == 0)
56 {
57 convert_ring<tag_out>::apply(result,
58 get_ring<tag1>::apply(id, geometry1),
59 append, reversed);
60 }
61 else if (id.source_index == 1)
62 {
63 convert_ring<tag_out>::apply(result,
64 get_ring<tag2>::apply(id, geometry2),
65 append, reversed);
66 }
67 else if (id.source_index == 2)
68 {
69 convert_ring<tag_out>::apply(result,
70 get_ring<void>::apply(id, collection),
71 append, reversed);
72 }
73}
74
b32b8144
FG
75enum add_rings_error_handling
76{
77 add_rings_ignore_unordered,
78 add_rings_add_unordered,
79 add_rings_throw_if_reversed
80};
81
7c673cae
FG
82template
83<
84 typename GeometryOut,
85 typename SelectionMap,
86 typename Geometry1,
87 typename Geometry2,
88 typename RingCollection,
b32b8144 89 typename OutputIterator,
1e59de90 90 typename Strategy
7c673cae
FG
91>
92inline OutputIterator add_rings(SelectionMap const& map,
93 Geometry1 const& geometry1, Geometry2 const& geometry2,
94 RingCollection const& collection,
b32b8144 95 OutputIterator out,
1e59de90 96 Strategy const& strategy,
b32b8144 97 add_rings_error_handling error_handling = add_rings_ignore_unordered)
7c673cae
FG
98{
99 typedef typename SelectionMap::const_iterator iterator;
7c673cae 100
7c673cae
FG
101 std::size_t const min_num_points = core_detail::closure::minimum_ring_size
102 <
103 geometry::closure
104 <
105 typename boost::range_value
106 <
107 RingCollection const
108 >::type
109 >::value
110 >::value;
111
112
113 for (iterator it = boost::begin(map);
114 it != boost::end(map);
115 ++it)
116 {
117 if (! it->second.discarded
118 && it->second.parent.source_index == -1)
119 {
120 GeometryOut result;
121 convert_and_add(result, geometry1, geometry2, collection,
122 it->first, it->second.reversed, false);
123
124 // Add children
125 for (typename std::vector<ring_identifier>::const_iterator child_it
126 = it->second.children.begin();
127 child_it != it->second.children.end();
128 ++child_it)
129 {
130 iterator mit = map.find(*child_it);
131 if (mit != map.end()
132 && ! mit->second.discarded)
133 {
134 convert_and_add(result, geometry1, geometry2, collection,
135 *child_it, mit->second.reversed, true);
136 }
137 }
138
139 // Only add rings if they satisfy minimal requirements.
140 // This cannot be done earlier (during traversal), not
141 // everything is figured out yet (sum of positive/negative rings)
b32b8144 142 if (geometry::num_points(result) >= min_num_points)
7c673cae 143 {
1e59de90
TL
144 typedef typename geometry::area_result<GeometryOut, Strategy>::type area_type;
145 area_type const area = geometry::area(result, strategy);
146 area_type const zero = 0;
b32b8144
FG
147 // Ignore if area is 0
148 if (! math::equals(area, zero))
149 {
150 if (error_handling == add_rings_add_unordered
151 || area > zero)
152 {
153 *out++ = result;
154 }
155 else if (error_handling == add_rings_throw_if_reversed)
156 {
157 BOOST_THROW_EXCEPTION(invalid_output_exception());
158 }
159 }
7c673cae
FG
160 }
161 }
162 }
163 return out;
164}
165
166
167template
168<
169 typename GeometryOut,
170 typename SelectionMap,
171 typename Geometry,
172 typename RingCollection,
b32b8144 173 typename OutputIterator,
1e59de90 174 typename Strategy
7c673cae
FG
175>
176inline OutputIterator add_rings(SelectionMap const& map,
177 Geometry const& geometry,
178 RingCollection const& collection,
b32b8144 179 OutputIterator out,
1e59de90 180 Strategy const& strategy)
7c673cae
FG
181{
182 Geometry empty;
1e59de90 183 return add_rings<GeometryOut>(map, geometry, empty, collection, out, strategy);
7c673cae
FG
184}
185
186
187}} // namespace detail::overlay
188#endif // DOXYGEN_NO_DETAIL
189
190
191}} // namespace geometry
192
193
194#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_ADD_RINGS_HPP