Imported Upstream version 1.72.0
[platform/upstream/boost.git] / libs / geometry / test / algorithms / buffer / buffer_multi_point.cpp
1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2 // Unit Test
3
4 // Copyright (c) 2012-2019 Barend Gehrels, Amsterdam, the Netherlands.
5
6 // Use, modification and distribution is subject to the Boost Software License,
7 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
8 // http://www.boost.org/LICENSE_1_0.txt)
9
10 #include "test_buffer.hpp"
11
12 static std::string const simplex = "MULTIPOINT((5 5),(7 7))";
13 static std::string const three = "MULTIPOINT((5 8),(9 8),(7 11))";
14
15 // Generated error (extra polygon on top of rest) at distance 14.0:
16 static std::string const multipoint_a = "MULTIPOINT((39 44),(38 37),(41 29),(15 33),(58 39))";
17
18 // Just one with holes at distance ~ 15
19 static std::string const multipoint_b = "MULTIPOINT((5 56),(98 67),(20 7),(58 60),(10 4),(75 68),(61 68),(75 62),(92 26),(74 6),(67 54),(20 43),(63 30),(45 7))";
20
21 // Grid, U-form, generates error for square point at 0.54 (top cells to control rescale)
22 static std::string const grid_a = "MULTIPOINT(5 0,6 0,7 0,  5 1,7 1,  0 13,8 13)";
23
24 static std::string const mysql_report_2015_02_25_1 = "MULTIPOINT(-9 19,9 -6,-4 4,16 -14,-3 16,14 9)";
25 static std::string const mysql_report_2015_02_25_2 = "MULTIPOINT(-2 11,-15 3,6 4,-14 0,20 -7,-17 -1)";
26
27 static std::string const mysql_report_3 = "MULTIPOINT(0 0,0 0,0 0,0 0,0 0)";
28
29 template <bool Clockwise, typename P>
30 void test_all()
31 {
32     typedef bg::model::polygon<P, Clockwise> polygon;
33     typedef bg::model::multi_point<P> multi_point_type;
34
35     bg::strategy::buffer::join_round join;
36     bg::strategy::buffer::end_flat end_flat;
37     typedef bg::strategy::buffer::distance_symmetric
38     <
39         typename bg::coordinate_type<P>::type
40     > distance_strategy;
41     bg::strategy::buffer::side_straight side_strategy;
42
43     double const pi = boost::geometry::math::pi<double>();
44
45     test_one<multi_point_type, polygon>("simplex1", simplex, join, end_flat, 2.0 * pi, 1.0);
46     test_one<multi_point_type, polygon>("simplex2", simplex, join, end_flat, 22.8372, 2.0);
47     test_one<multi_point_type, polygon>("simplex3", simplex, join, end_flat, 44.5692, 3.0);
48
49     test_one<multi_point_type, polygon>("three1", three, join, end_flat, 3.0 * pi, 1.0);
50 #if defined(BOOST_GEOMETRY_USE_RESCALING) || defined(BOOST_GEOMETRY_TEST_FAILURES)
51     // For no-rescaling, fails in CCW mode
52     test_one<multi_point_type, polygon>("three2", three, join, end_flat, 36.7592, 2.0);
53 #endif
54     test_one<multi_point_type, polygon>("three19", three, join, end_flat, 33.6914, 1.9);
55     test_one<multi_point_type, polygon>("three21", three, join, end_flat, 39.6394, 2.1);
56     test_one<multi_point_type, polygon>("three3", three, join, end_flat, 65.533, 3.0);
57
58     test_one<multi_point_type, polygon>("multipoint_a", multipoint_a, join, end_flat, 2049.98, 14.0);
59     test_one<multi_point_type, polygon>("multipoint_b", multipoint_b, join, end_flat, 7109.88, 15.0);
60     test_one<multi_point_type, polygon>("multipoint_b1", multipoint_b, join, end_flat, 6911.89, 14.7);
61     test_one<multi_point_type, polygon>("multipoint_b2", multipoint_b, join, end_flat, 7174.79, 15.1);
62
63     // Grid tests
64     {
65         bg::strategy::buffer::point_square point_strategy;
66
67         test_with_custom_strategies<multi_point_type, polygon>("grid_a50",
68                 grid_a, join, end_flat,
69                 distance_strategy(0.5), side_strategy, point_strategy, 7.0);
70
71         test_with_custom_strategies<multi_point_type, polygon>("grid_a54",
72                 grid_a, join, end_flat,
73                 distance_strategy(0.54), side_strategy, point_strategy, 7.819);
74     }
75
76     test_with_custom_strategies<multi_point_type, polygon>("mysql_report_2015_02_25_1_800",
77             mysql_report_2015_02_25_1, join, end_flat,
78             distance_strategy(6051788), side_strategy,
79             bg::strategy::buffer::point_circle(800),
80             115057490003226.125, ut_settings(1.0));
81
82     {
83         typename bg::strategy::area::services::default_strategy
84             <
85                 typename bg::cs_tag<P>::type
86             >::type area_strategy;
87
88         multi_point_type g;
89         bg::read_wkt(mysql_report_3, g);
90         bg::model::multi_polygon<polygon> buffered;
91         test_buffer<polygon>("mysql_report_3", buffered, g,
92             bg::strategy::buffer::join_round(36),
93             bg::strategy::buffer::end_round(36),
94             distance_strategy(1),
95             side_strategy,
96             bg::strategy::buffer::point_circle(36),
97             area_strategy,
98             1, 0, 3.12566719800474635, ut_settings(1.0));
99     }
100 }
101
102 template <typename P>
103 void test_many_points_per_circle()
104 {
105     // Tests for large distances / many points in circles.
106     // Before Boost 1.58, this would (seem to) hang. It is solved by using monotonic sections in get_turns for buffer
107     // This is more time consuming, only calculate this for counter clockwise
108     // Reported by MySQL 2015-02-25
109     //   SELECT ST_ASTEXT(ST_BUFFER(ST_GEOMFROMTEXT(''), 6051788, ST_BUFFER_STRATEGY('point_circle', 83585)));
110     //   SELECT ST_ASTEXT(ST_BUFFER(ST_GEOMFROMTEXT(''), 5666962, ST_BUFFER_STRATEGY('point_circle', 46641))) ;
111
112     typedef bg::model::polygon<P, false> polygon;
113     typedef bg::model::multi_point<P> multi_point_type;
114
115     bg::strategy::buffer::join_round join;
116     bg::strategy::buffer::end_flat end_flat;
117     typedef bg::strategy::buffer::distance_symmetric
118     <
119         typename bg::coordinate_type<P>::type
120     > distance_strategy;
121     bg::strategy::buffer::side_straight side_strategy;
122
123     using bg::strategy::buffer::point_circle;
124
125 #if ! defined(BOOST_GEOMETRY_USE_RESCALING)
126     double const tolerance = 1000.0;
127 #else
128     double const tolerance = 1.0;
129 #endif
130
131     // Area should be somewhat larger (~>) than pi*distance^2
132     // 6051788: area ~> 115058122875258
133
134     // Strategies with many points, which are (very) slow in debug mode
135     test_with_custom_strategies<multi_point_type, polygon>(
136             "mysql_report_2015_02_25_1_8000",
137             mysql_report_2015_02_25_1, join, end_flat,
138             distance_strategy(6051788), side_strategy, point_circle(8000),
139             115058661065242.812, ut_settings(10.0 * tolerance));
140
141     // Expectations:
142     // 115058672785641.031
143     // 115058672785680.281
144     // 115058672785679.922
145     test_with_custom_strategies<multi_point_type, polygon>(
146             "mysql_report_2015_02_25_1",
147             mysql_report_2015_02_25_1, join, end_flat,
148             distance_strategy(6051788), side_strategy, point_circle(83585),
149             115058672785660.0, ut_settings(25.0 * tolerance));
150
151     // Takes about 7 seconds in release mode
152     // Expectations:
153     // 115058672880035.391
154     // 115058672879944.547
155     // 115058672879920.484
156     test_with_custom_strategies<multi_point_type, polygon>(
157             "mysql_report_2015_02_25_1_250k",
158             mysql_report_2015_02_25_1, join, end_flat,
159             distance_strategy(6051788), side_strategy, point_circle(250000),
160             115058672879977.0, ut_settings(150.0 * tolerance));
161
162 #if defined(BOOST_GEOMETRY_BUFFER_INCLUDE_SLOW_TESTS)
163     // Takes about 110 seconds in release mode
164     test_with_custom_strategies<multi_point_type, polygon>(
165             "mysql_report_2015_02_25_1_800k",
166             mysql_report_2015_02_25_1, join, end_flat,
167             distance_strategy(6051788), side_strategy, point_circle(800000),
168             115058672871849.219, ut_settings(tolerance));
169 #endif
170
171     // 5666962: area ~> 100890546298964
172     // Expectations:
173     // 100891031341796.875
174     // 100891031341794.766
175     // 100891031341794.078
176     test_with_custom_strategies<multi_point_type, polygon>(
177             "mysql_report_2015_02_25_2",
178             mysql_report_2015_02_25_2, join, end_flat,
179             distance_strategy(5666962), side_strategy, point_circle(46641),
180             100891031341795.0, ut_settings(200.0 * tolerance));
181
182     // Multipoint b with large distances/many points
183     // Area ~> pi * 10x
184
185     // Expectations:
186     // 3141871558222.398
187     // 3141871558231.5166
188     // 3141871558231.48926
189
190     test_with_custom_strategies<multi_point_type, polygon>(
191             "multipoint_b_50k",
192             multipoint_b, join, end_flat,
193             distance_strategy(1000000), side_strategy, point_circle(50000),
194             3141871558227.0, ut_settings(40.0 * tolerance));
195
196 #if defined(BOOST_GEOMETRY_BUFFER_INCLUDE_SLOW_TESTS)
197     // Tests optimization min/max radius
198     // Takes about 55 seconds in release mode
199     test_with_custom_strategies<multi_point_type, polygon>(
200             "multipoint_b_500k",
201             multipoint_b, join, end_flat,
202             distance_strategy(10000000), side_strategy, point_circle(500000),
203             314162054419515.562, ut_settings((tolerance));
204 #endif
205 }
206
207 int test_main(int, char* [])
208 {
209     BoostGeometryWriteTestConfiguration();
210
211     test_all<true, bg::model::point<default_test_type, 2, bg::cs::cartesian> >();
212
213 #if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_ORDER)
214     test_all<false, bg::model::point<default_test_type, 2, bg::cs::cartesian> >();
215 #endif
216
217 #if defined(BOOST_GEOMETRY_COMPILER_MODE_RELEASE) && ! defined(BOOST_GEOMETRY_COMPILER_MODE_DEBUG)
218     test_many_points_per_circle<bg::model::point<double, 2, bg::cs::cartesian> >();
219 #else
220     std::cout << "Skipping some tests in debug or unknown mode" << std::endl;
221 #endif
222
223     return 0;
224 }