17
17
# include < boost/geometry/io/svg/svg_mapper.hpp>
18
18
#endif
19
19
20
+ #include " quadtree_partition.hpp"
21
+
20
22
#include < chrono>
21
23
#include < random>
22
24
#include < fstream>
@@ -43,112 +45,41 @@ struct ring_item
43
45
44
46
BOOST_GEOMETRY_REGISTER_POINT_2D (point_item, double , cs::cartesian, x, y)
45
47
46
-
47
- struct expand_for_point
48
- {
49
- template <typename Box, typename InputItem>
50
- static inline void apply (Box& total, InputItem const & item)
51
- {
52
- bg::expand (total, item);
53
- }
54
- };
55
-
56
- struct overlaps_point
48
+ #if defined(TEST_WITH_SVG)
49
+ template <typename Points, typename Rings, typename Box, typename Boxes>
50
+ void create_svg (std::size_t size, Points const & points, Rings const & rings, std::size_t index,
51
+ Box const & box, int level,
52
+ Boxes& boxes)
57
53
{
58
- template <typename Box, typename InputItem>
59
- static inline bool apply (Box const & box, InputItem const & item)
60
- {
61
- return ! bg::disjoint (item, box);
62
- }
63
- };
54
+ std::ostringstream filename;
55
+ filename << " partition_demo_" << std::setfill (' 0' ) << std::setw (3 ) << index << " _" << level << " .svg" ;
56
+ std::ofstream svg (filename.str ());
64
57
58
+ bg::svg_mapper<point_item> mapper (svg, 800 , 800 );
65
59
66
- struct expand_for_ring
67
- {
68
- template <typename Box, typename InputItem>
69
- static inline void apply (Box& total, InputItem const & item)
70
60
{
71
- bg::expand (total, item.box );
61
+ point_item p;
62
+ p.x = -1 ; p.y = -1 ; mapper.add (p);
63
+ p.x = size + 1 ; p.y = size + 1 ; mapper.add (p);
72
64
}
73
- };
74
65
75
- struct overlaps_ring
76
- {
77
- template <typename Box, typename InputItem>
78
- static inline bool apply (Box const & box, InputItem const & item)
66
+ for (auto const & item : rings)
79
67
{
80
- typename bg::strategy::disjoint::services::default_strategy
81
- <
82
- Box, Box
83
- >::type strategy;
84
-
85
- return ! bg::detail::disjoint::disjoint_box_box (box, item.box , strategy);
68
+ mapper.map (item.ring , " opacity:0.6;fill:rgb(0,255,0);stroke:rgb(0,0,0);stroke-width:0.1" );
86
69
}
87
- };
88
-
89
- struct point_in_ring_visitor
90
- {
91
- std::size_t count = 0 ;
92
-
93
- template <typename Point , typename BoxItem>
94
- inline bool apply (Point const & point, BoxItem const & ring_item)
70
+ for (auto const & point : points)
95
71
{
96
- if (bg::within (point, ring_item.ring ))
97
- {
98
- count++;
99
- }
100
- return true ;
72
+ mapper.map (point, " fill:rgb(0,0,255);stroke:rgb(0,0,100);stroke-width:0.1" , 3 );
101
73
}
102
- };
103
74
104
- #if defined(TEST_WITH_SVG)
105
- template <typename Box, typename Points, typename Rings>
106
- struct svg_visitor
107
- {
108
- std::vector<Box> boxes;
109
- Points const & m_points;
110
- Rings const & m_rings;
111
- std::size_t m_size = 0 ;
112
- std::size_t m_index = 0 ;
113
-
114
- svg_visitor (std::size_t size, Points const & points, Rings const & rings)
115
- : m_points(points)
116
- , m_rings(rings)
117
- , m_size(size)
118
- {}
119
-
120
- inline void apply (Box const & box, int level)
75
+ for (auto const & b : boxes)
121
76
{
122
- std::ostringstream filename;
123
- filename << " partition_demo_" << std::setfill (' 0' ) << std::setw (3 ) << m_index++ << " _" << level << " .svg" ;
124
- std::ofstream svg (filename.str ());
125
-
126
- bg::svg_mapper<point_item> mapper (svg, 800 , 800 );
127
-
128
- {
129
- point_item p;
130
- p.x = -1 ; p.y = -1 ; mapper.add (p);
131
- p.x = m_size + 1 ; p.y = m_size + 1 ; mapper.add (p);
132
- }
133
-
134
- for (auto const & item : m_rings)
135
- {
136
- mapper.map (item.ring , " opacity:0.6;fill:rgb(0,255,0);stroke:rgb(0,0,0);stroke-width:0.1" );
137
- }
138
- for (auto const & point : m_points)
139
- {
140
- mapper.map (point, " fill:rgb(0,0,255);stroke:rgb(0,0,100);stroke-width:0.1" , 3 );
141
- }
142
-
143
- for (auto const & b : boxes)
144
- {
145
- mapper.map (b, " fill:none;stroke-width:2;stroke:rgb(64,64,64);" );
146
- }
147
- mapper.map (box, " fill:none;stroke-width:4;stroke:rgb(255, 0, 0);" );
148
-
149
- boxes.push_back (box);
77
+ mapper.map (b, " fill:none;stroke-width:2;stroke:rgb(64,64,64);" );
150
78
}
151
- };
79
+ mapper.map (box, " fill:none;stroke-width:4;stroke:rgb(255, 0, 0);" );
80
+
81
+ boxes.push_back (box);
82
+ }
152
83
#endif
153
84
154
85
@@ -311,27 +242,46 @@ void call_within(std::size_t size, std::size_t count)
311
242
return elapsed;
312
243
};
313
244
314
- point_in_ring_visitor count_visitor;
315
- {
316
245
#if defined(TEST_WITH_SVG)
317
-
318
- using partition_box_visitor_type = svg_visitor<box_type, std::vector<point_item>, std::vector<ring_item<ring_type>>>;
319
- partition_box_visitor_type partition_box_visitor (size, points, rings);
320
- #else
321
- using partition_box_visitor_type = bg::detail::partition::visit_no_policy;
322
- partition_box_visitor_type partition_box_visitor;
246
+ std::size_t index = 0 ;
247
+ std::vector<box_type> boxes;
248
+ auto box_visitor = [&](auto const & box, int level)
249
+ {
250
+ create_svg (size, points, rings, index ++, box, level, boxes);
251
+ };
252
+ #else
253
+ auto box_visitor = [&](auto const & , int ) {};
323
254
#endif
324
255
256
+ std::size_t quadtree_count = 0 ;
257
+ {
325
258
auto const start = std::chrono::steady_clock::now ();
326
259
327
- bg::partition
328
- <
329
- box_type,
330
- bg::detail::partition::include_all_policy,
331
- bg::detail::partition::include_all_policy
332
- >::apply (points, rings, count_visitor, expand_for_point (), overlaps_point (),
333
- expand_for_ring (), overlaps_ring (), 16 , partition_box_visitor);
334
- report (" Partition" , start, count_visitor.count );
260
+ bg::experimental::quadtree_partition<box_type>(points,
261
+ rings,
262
+ [](auto & box, auto const & point) { bg::expand (box, point); },
263
+ [](auto const & box, auto const & point) { return ! bg::disjoint (point, box); },
264
+ [](auto & box, auto const & item) { bg::expand (box, item.box ); },
265
+ [](auto const & box, auto const & item)
266
+ {
267
+ typename bg::strategy::disjoint::services::default_strategy
268
+ <
269
+ box_type, box_type
270
+ >::type strategy;
271
+ return ! bg::detail::disjoint::disjoint_box_box (box, item.box , strategy);
272
+ },
273
+ [&quadtree_count](auto const & p, auto const & ri)
274
+ {
275
+ if (bg::within (p, ri.ring ))
276
+ {
277
+ quadtree_count++;
278
+ }
279
+ return true ;
280
+ },
281
+ box_visitor
282
+ );
283
+
284
+ report (" Partition" , start, quadtree_count);
335
285
}
336
286
337
287
{
@@ -350,7 +300,7 @@ void call_within(std::size_t size, std::size_t count)
350
300
}
351
301
report (" Quadratic loop" , start, count);
352
302
353
- if (count != count_visitor. count )
303
+ if (count != quadtree_count )
354
304
{
355
305
std::cerr << " ERROR: counts are not equal" << std::endl;
356
306
}
0 commit comments