Skip to content

Commit 98f33fa

Browse files
awulkiewtinko92
authored andcommitted
[setops] Add suport for tupled-output in difference, sym_difference and union_.
1 parent a45dd5c commit 98f33fa

File tree

3 files changed

+599
-98
lines changed

3 files changed

+599
-98
lines changed

include/boost/geometry/algorithms/difference.hpp

Lines changed: 161 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
44

5-
// This file was modified by Oracle on 2017, 2019.
6-
// Modifications copyright (c) 2017, 2019, Oracle and/or its affiliates.
5+
// This file was modified by Oracle on 2017, 2019, 2020.
6+
// Modifications copyright (c) 2017-2020, Oracle and/or its affiliates.
77

88
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
99

@@ -19,6 +19,7 @@
1919
#include <boost/variant/static_visitor.hpp>
2020
#include <boost/variant/variant_fwd.hpp>
2121

22+
#include <boost/geometry/algorithms/detail/intersection/multi.hpp>
2223
#include <boost/geometry/algorithms/detail/overlay/intersection_insert.hpp>
2324
#include <boost/geometry/policies/robustness/get_rescale_policy.hpp>
2425
#include <boost/geometry/strategies/default_strategy.hpp>
@@ -32,6 +33,146 @@ namespace boost { namespace geometry
3233
namespace detail { namespace difference
3334
{
3435

36+
template
37+
<
38+
typename Geometry1,
39+
typename Geometry2,
40+
typename SingleOut,
41+
typename OutTag = typename detail::setop_insert_output_tag<SingleOut>::type,
42+
bool ReturnGeometry1 = (topological_dimension<Geometry1>::value
43+
> topological_dimension<Geometry2>::value)
44+
>
45+
struct call_intersection_insert
46+
{
47+
template
48+
<
49+
typename OutputIterator,
50+
typename RobustPolicy,
51+
typename Strategy
52+
>
53+
static inline OutputIterator apply(Geometry1 const& geometry1,
54+
Geometry2 const& geometry2,
55+
RobustPolicy const& robust_policy,
56+
OutputIterator out,
57+
Strategy const& strategy)
58+
{
59+
return geometry::dispatch::intersection_insert
60+
<
61+
Geometry1, Geometry2,
62+
SingleOut,
63+
overlay_difference,
64+
geometry::detail::overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
65+
geometry::detail::overlay::do_reverse<geometry::point_order<Geometry2>::value, true>::value
66+
>::apply(geometry1, geometry2, robust_policy, out, strategy);
67+
}
68+
};
69+
70+
template
71+
<
72+
typename Geometry1,
73+
typename Geometry2,
74+
typename SingleOut
75+
>
76+
struct call_intersection_insert_tupled_base
77+
{
78+
typedef typename geometry::detail::casted_tag_to_single_tag
79+
<
80+
typename geometry::tag_cast
81+
<
82+
typename geometry::tag<Geometry1>::type,
83+
pointlike_tag, linear_tag, areal_tag
84+
>::type
85+
>::type single_tag;
86+
87+
typedef detail::expect_output
88+
<
89+
Geometry1, Geometry2, SingleOut, single_tag
90+
> expect_check;
91+
92+
typedef typename geometry::detail::output_geometry_access
93+
<
94+
SingleOut, single_tag, single_tag
95+
> access;
96+
};
97+
98+
template
99+
<
100+
typename Geometry1,
101+
typename Geometry2,
102+
typename SingleOut
103+
>
104+
struct call_intersection_insert
105+
<
106+
Geometry1, Geometry2, SingleOut,
107+
detail::tupled_output_tag,
108+
false
109+
>
110+
: call_intersection_insert_tupled_base<Geometry1, Geometry2, SingleOut>
111+
{
112+
typedef call_intersection_insert_tupled_base<Geometry1, Geometry2, SingleOut> base_t;
113+
114+
template
115+
<
116+
typename OutputIterator,
117+
typename RobustPolicy,
118+
typename Strategy
119+
>
120+
static inline OutputIterator apply(Geometry1 const& geometry1,
121+
Geometry2 const& geometry2,
122+
RobustPolicy const& robust_policy,
123+
OutputIterator out,
124+
Strategy const& strategy)
125+
{
126+
base_t::access::get(out) = call_intersection_insert
127+
<
128+
Geometry1, Geometry2,
129+
typename base_t::access::type
130+
>::apply(geometry1, geometry2, robust_policy,
131+
base_t::access::get(out), strategy);
132+
133+
return out;
134+
}
135+
};
136+
137+
template
138+
<
139+
typename Geometry1,
140+
typename Geometry2,
141+
typename SingleOut
142+
>
143+
struct call_intersection_insert
144+
<
145+
Geometry1, Geometry2, SingleOut,
146+
detail::tupled_output_tag,
147+
true
148+
>
149+
: call_intersection_insert_tupled_base<Geometry1, Geometry2, SingleOut>
150+
{
151+
typedef call_intersection_insert_tupled_base<Geometry1, Geometry2, SingleOut> base_t;
152+
153+
template
154+
<
155+
typename OutputIterator,
156+
typename RobustPolicy,
157+
typename Strategy
158+
>
159+
static inline OutputIterator apply(Geometry1 const& geometry1,
160+
Geometry2 const& geometry2,
161+
RobustPolicy const& robust_policy,
162+
OutputIterator out,
163+
Strategy const& strategy)
164+
{
165+
base_t::access::get(out) = geometry::detail::convert_to_output
166+
<
167+
Geometry1,
168+
typename base_t::access::type
169+
>::apply(geometry1, base_t::access::get(out));
170+
171+
return out;
172+
}
173+
};
174+
175+
35176
/*!
36177
\brief_calc2{difference} \brief_strategy
37178
\ingroup difference
@@ -65,7 +206,8 @@ inline OutputIterator difference_insert(Geometry1 const& geometry1,
65206
{
66207
concepts::check<Geometry1 const>();
67208
concepts::check<Geometry2 const>();
68-
concepts::check<GeometryOut>();
209+
//concepts::check<GeometryOut>();
210+
geometry::detail::output_geometry_concept_check<GeometryOut>::apply();
69211

70212
typedef typename geometry::rescale_overlay_policy_type
71213
<
@@ -75,16 +217,12 @@ inline OutputIterator difference_insert(Geometry1 const& geometry1,
75217
>::type rescale_policy_type;
76218

77219
rescale_policy_type robust_policy
78-
= geometry::get_rescale_policy<rescale_policy_type>(
79-
geometry1, geometry2, strategy);
220+
= geometry::get_rescale_policy<rescale_policy_type>(
221+
geometry1, geometry2, strategy);
80222

81-
return geometry::dispatch::intersection_insert
223+
return geometry::detail::difference::call_intersection_insert
82224
<
83-
Geometry1, Geometry2,
84-
GeometryOut,
85-
overlay_difference,
86-
geometry::detail::overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
87-
geometry::detail::overlay::do_reverse<geometry::point_order<Geometry2>::value, true>::value
225+
Geometry1, Geometry2, GeometryOut
88226
>::apply(geometry1, geometry2, robust_policy, out, strategy);
89227
}
90228

@@ -146,11 +284,14 @@ struct difference
146284
Collection & output_collection,
147285
Strategy const& strategy)
148286
{
149-
typedef typename boost::range_value<Collection>::type geometry_out;
287+
typedef typename geometry::detail::output_geometry_value
288+
<
289+
Collection
290+
>::type single_out;
150291

151-
detail::difference::difference_insert<geometry_out>(
292+
detail::difference::difference_insert<single_out>(
152293
geometry1, geometry2,
153-
range::back_inserter(output_collection),
294+
geometry::detail::output_geometry_back_inserter(output_collection),
154295
strategy);
155296
}
156297

@@ -165,11 +306,13 @@ struct difference
165306
Collection & output_collection,
166307
default_strategy)
167308
{
168-
typedef typename boost::range_value<Collection>::type geometry_out;
309+
typedef typename strategy::relate::services::default_strategy
310+
<
311+
Geometry1,
312+
Geometry2
313+
>::type strategy_type;
169314

170-
detail::difference::difference_insert<geometry_out>(
171-
geometry1, geometry2,
172-
range::back_inserter(output_collection));
315+
apply(geometry1, geometry2, output_collection, strategy_type());
173316
}
174317
};
175318

0 commit comments

Comments
 (0)