1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2 // Unit Test
3 
4 // Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
5 // Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
6 // Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
7 // Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
8 
9 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
10 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
11 
12 // Use, modification and distribution is subject to the Boost Software License,
13 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
14 // http://www.boost.org/LICENSE_1_0.txt)
15 
16 
17 #include <algorithms/test_centroid.hpp>
18 
19 #include <boost/core/ignore_unused.hpp>
20 
21 #include <boost/geometry/core/point_order.hpp>
22 #include <boost/geometry/strategies/cartesian/centroid_average.hpp>
23 
24 #include <boost/geometry/geometries/geometries.hpp>
25 #include <boost/geometry/geometries/point_xy.hpp>
26 
27 
28 // #define REPORT_RESULTS
29 
30 
31 template <typename P>
test_2d(bool is_integer=false)32 void test_2d(bool is_integer = false)
33 {
34     typedef typename bg::coordinate_type<P>::type ct;
35     boost::ignore_unused<ct>();
36 
37 #ifdef REPORT_RESULTS
38     std::cout << std::endl << "type: " << typeid(ct).name() << " size: " << sizeof(ct) << std::endl;
39 #endif
40 
41     test_centroid<bg::model::multi_point<P> >(
42             "MULTIPOINT((1 1),(3 3))",
43             2.0, 2.0);
44 
45     test_centroid<bg::model::multi_point<P> >(
46             "MULTIPOINT((-1 -1),(-3 -3))",
47             -2.0, -2.0);
48 
49     if (! is_integer)
50     {
51         // Only working for floating point:
52 
53         test_centroid<bg::model::multi_point<P> >(
54             "MULTIPOINT((1 1),(2 3),(5 0))",
55             2.666666666666667, 1.33333);
56 
57         test_centroid<bg::model::multi_linestring<bg::model::linestring<P> > >(
58             "MULTILINESTRING((0 0,0 2),(1 0,1 2))",
59             0.5, 1.0);
60 
61         // degenerated
62         test_centroid<bg::model::multi_linestring<bg::model::linestring<P> > >(
63             "MULTILINESTRING((1 1,1 1))",
64             1.0, 1.0);
65 
66 
67         test_centroid<bg::model::multi_polygon<bg::model::polygon<P> > >(
68             "MULTIPOLYGON(((1 1,1 3,3 3,3 1,1 1)),((4 1,4 3,8 3,8 1,4 1)))",
69             4.666666666666667, 2.0);
70 
71         test_centroid<bg::model::multi_polygon<bg::model::polygon<P> > >(
72             "MULTIPOLYGON(((2 1.3,2.4 1.7,2.8 1.8,3.4 1.2"
73             ",3.7 1.6,3.4 2,4.1 3,5.3 2.6,5.4 1.2,4.9 0.8,2.9 0.7,2 1.3)),"
74             "((10 10,10 12,12 12,12 10,10 10)))",
75             7.338463104108615, 6.0606722055552407);
76 
77         // degenerated
78         test_centroid<bg::model::multi_polygon<bg::model::polygon<P> > >(
79             "MULTIPOLYGON(((1 1,1 1,1 1,1 1,1 1)))",
80             1.0, 1.0);
81         test_centroid<bg::model::multi_polygon<bg::model::polygon<P> > >(
82             "MULTIPOLYGON(((1 1)))",
83             1.0, 1.0);
84     }
85 
86 
87 
88     // Test using real-world polygon with large (Y) coordinates
89     // (coordinates can be used for integer and floating point point-types)
90     // Note that this will fail (overflow) if centroid calculation uses float
91     test_centroid<bg::model::multi_polygon<bg::model::polygon<P> > >(
92         "MULTIPOLYGON(((426062 4527794,426123 4527731"
93             ",426113 4527700,426113 4527693,426115 4527671"
94             ",426133 4527584,426135 4527569,426124 4527558"
95             ",426103 4527547,426072 4527538,426003 4527535"
96             ",425972 4527532,425950 4527531,425918 4527528"
97             ",425894 4527517,425876 4527504,425870 4527484"
98             ",425858 4527442,425842 4527414,425816 4527397"
99             ",425752 4527384,425692 4527369,425658 4527349"
100             ",425624 4527307,425605 4527260,425598 4527213"
101             ",425595 4527167,425582 4527125,425548 4527064"
102             ",425535 4527027,425537 4526990,425534 4526943"
103             ",425525 4526904,425500 4526856,425461 4526811"
104             ",425450 4526798,425381 4526823,425362 4526830"
105             ",425329 4526848,425298 4526883,425291 4526897"
106             ",425268 4526923,425243 4526945,425209 4526971"
107             ",425172 4526990,425118 4527028,425104 4527044"
108             ",425042 4527090,424980 4527126,424925 4527147"
109             ",424881 4527148,424821 4527147,424698 4527125"
110             ",424610 4527121,424566 4527126,424468 4527139"
111             ",424426 4527141,424410 4527142,424333 4527130"
112             ",424261 4527110,424179 4527073,424024 4527012"
113             ",423947 4526987,423902 4526973,423858 4526961"
114             ",423842 4526951,423816 4526935,423799 4526910"
115             ",423776 4526905,423765 4526911,423739 4526927"
116             ",423692 4526946,423636 4526976,423608 4527008"
117             ",423570 4527016,423537 4527011,423505 4526996"
118             ",423480 4526994,423457 4527012,423434 4527021"
119             ",423367 4527008,423263 4526998,423210 4526993"
120             ",423157 4526996,423110 4526994,423071 4526984"
121             ",423048 4526984,423032 4526994,423254 4527613"
122             ",423889 4528156,424585 4528050,425479 4527974"
123             ",425795 4527867,426062 4527794)))",
124         424530.6059719588, 4527519.619367547);
125 }
126 
127 template <typename P>
test_exceptions()128 void test_exceptions()
129 {
130     using namespace bg::model;
131     typedef multi_polygon<polygon<P> > multi_polygon;
132     typedef multi_linestring<linestring<P> > multi_linestring;
133 
134     // Empty multi-polygon
135     test_centroid_exception<multi_polygon>("MULTIPOLYGON()");
136     test_centroid_exception<multi_polygon>("MULTIPOLYGON(())");
137     test_centroid_exception<multi_polygon>("MULTIPOLYGON((), ())");
138     test_centroid_exception<multi_polygon>("MULTIPOLYGON((()), ())");
139     test_centroid_exception<multi_polygon>("MULTIPOLYGON(((), ()))");
140 
141     // Empty multi-linestring
142     test_centroid_exception<multi_linestring>("MULTILINESTRING()");
143     test_centroid_exception<multi_linestring>("MULTILINESTRING(())");
144     test_centroid_exception<multi_linestring>("MULTILINESTRING((), ())");
145 }
146 
147 template <typename P>
test_empty()148 void test_empty()
149 {
150     using namespace bg::model;
151     typedef multi_polygon<polygon<P> > multi_polygon;
152     typedef multi_linestring<linestring<P> > multi_linestring;
153 
154     // Multi-linestring with empty linestring
155     test_centroid<multi_linestring>(
156         "MULTILINESTRING((), (0 0))",
157         0.0, 0.0);
158     test_centroid<multi_linestring>(
159         "MULTILINESTRING((0 0, 1 0), ())",
160         0.5, 0.0);
161 
162     // Multi-polygon with empty polygon
163     test_centroid<multi_polygon>(
164         "MULTIPOLYGON((()), ((0 0)))",
165         0.0, 0.0);
166     test_centroid<multi_polygon>(
167         "MULTIPOLYGON(((0 0, 1 0, 1 1, 0 1, 0 0)), (()))",
168         0.5, 0.5);
169 
170     // Multi-polygon with empty interior ring
171     test_centroid<multi_polygon>(
172         "MULTIPOLYGON(((0 0, 1 0, 1 1, 0 1, 0 0), ()))",
173         0.5, 0.5);
174     test_centroid<multi_polygon>(
175         "MULTIPOLYGON((()), ((0 0, 1 0, 1 1, 0 1, 0 0), ()))",
176         0.5, 0.5);
177 }
178 
179 
180 
test_main(int,char * [])181 int test_main(int, char* [])
182 {
183     test_2d<bg::model::d2::point_xy<float> >();
184     test_2d<bg::model::d2::point_xy<double> >();
185     test_2d<bg::model::d2::point_xy<long int> >(true);
186     //test_2d<bg::model::d2::point_xy<long long> >(true);
187     //test_2d<bg::model::d2::point_xy<long double> >();
188 
189     test_exceptions<bg::model::d2::point_xy<double> >();
190     test_empty<bg::model::d2::point_xy<double> >();
191 
192     return 0;
193 }
194