• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2 // Unit Test
3 
4 // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
5 
6 // This file was modified by Oracle 2017.
7 // Modifications copyright (c) 2017, Oracle and/or its affiliates.
8 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
9 
10 // Use, modification and distribution is subject to the Boost Software License,
11 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
12 // http://www.boost.org/LICENSE_1_0.txt)
13 
14 #include <geometry_test_common.hpp>
15 
16 #include <algorithm>
17 
18 #include <boost/geometry/algorithms/make.hpp>
19 #include <boost/geometry/io/dsv/write.hpp>
20 
21 #include <boost/geometry/policies/compare.hpp>
22 
23 #include <boost/geometry/strategies/strategies.hpp>
24 
25 #include <boost/geometry/geometries/point.hpp>
26 #include <boost/geometry/geometries/adapted/c_array.hpp>
27 #include <boost/geometry/geometries/adapted/boost_tuple.hpp>
28 
29 #include <test_common/test_point.hpp>
30 
31 BOOST_GEOMETRY_REGISTER_C_ARRAY_CS(cs::cartesian)
BOOST_GEOMETRY_REGISTER_BOOST_TUPLE_CS(cs::cartesian)32 BOOST_GEOMETRY_REGISTER_BOOST_TUPLE_CS(cs::cartesian)
33 
34 
35 template <typename Container>
36 inline std::string coordinates(Container const& points)
37 {
38     std::ostringstream out;
39     for (typename boost::range_const_iterator<Container>::type it = boost::begin(points);
40         it != boost::end(points);
41         ++it)
42     {
43         out << bg::dsv(*it);
44     }
45     return out.str();
46 }
47 
48 template <typename P>
test_2d_compare()49 void test_2d_compare()
50 {
51     P p1 = bg::make<P>(3, 1);
52     P p2 = bg::make<P>(3, 1);
53     P p3 = bg::make<P>(1, 3);
54     P p4 = bg::make<P>(5, 2);
55     P p5 = bg::make<P>(3, 2);
56 
57     // Test in all dimensions
58     {
59         bg::equal_to<P> et;
60         bg::less<P> lt;
61         bg::greater<P> gt;
62 
63         BOOST_CHECK_EQUAL(et(p1, p2), true);
64         BOOST_CHECK_EQUAL(et(p1, p3), false);
65         BOOST_CHECK_EQUAL(et(p1, p4), false);
66         BOOST_CHECK_EQUAL(et(p1, p5), false);
67         BOOST_CHECK_EQUAL(et(p3, p4), false);
68 
69         BOOST_CHECK_EQUAL(lt(p1, p2), false);
70         BOOST_CHECK_EQUAL(lt(p1, p3), false);
71         BOOST_CHECK_EQUAL(lt(p1, p4), true);
72         BOOST_CHECK_EQUAL(lt(p1, p5), true);
73         BOOST_CHECK_EQUAL(lt(p3, p4), true);
74 
75         BOOST_CHECK_EQUAL(gt(p1, p2), false);
76         BOOST_CHECK_EQUAL(gt(p1, p3), true);
77         BOOST_CHECK_EQUAL(gt(p1, p4), false);
78         BOOST_CHECK_EQUAL(gt(p1, p5), false);
79         BOOST_CHECK_EQUAL(gt(p3, p4), false);
80     }
81 
82 
83     // Test in dimension 0, X
84     {
85         bg::equal_to<P, 0> et;
86         bg::less<P, 0> lt;
87         bg::greater<P, 0> gt;
88 
89         BOOST_CHECK_EQUAL(et(p1, p2), true);
90         BOOST_CHECK_EQUAL(et(p1, p3), false);
91         BOOST_CHECK_EQUAL(et(p1, p4), false);
92         BOOST_CHECK_EQUAL(et(p1, p5), true);
93         BOOST_CHECK_EQUAL(et(p3, p4), false);
94 
95         BOOST_CHECK_EQUAL(lt(p1, p2), false);
96         BOOST_CHECK_EQUAL(lt(p1, p3), false);
97         BOOST_CHECK_EQUAL(lt(p1, p4), true);
98         BOOST_CHECK_EQUAL(lt(p1, p5), false);
99         BOOST_CHECK_EQUAL(lt(p3, p4), true);
100 
101         BOOST_CHECK_EQUAL(gt(p1, p2), false);
102         BOOST_CHECK_EQUAL(gt(p1, p3), true);
103         BOOST_CHECK_EQUAL(gt(p1, p4), false);
104         BOOST_CHECK_EQUAL(gt(p1, p5), false);
105         BOOST_CHECK_EQUAL(gt(p3, p4), false);
106     }
107 
108     // Test in dimension 1, Y
109     {
110         bg::equal_to<P, 1> et;
111         bg::less<P, 1> lt;
112         bg::greater<P, 1> gt;
113 
114         BOOST_CHECK_EQUAL(et(p1, p2), true);
115         BOOST_CHECK_EQUAL(et(p1, p3), false);
116         BOOST_CHECK_EQUAL(et(p1, p4), false);
117         BOOST_CHECK_EQUAL(et(p1, p5), false);
118         BOOST_CHECK_EQUAL(et(p3, p4), false);
119 
120         BOOST_CHECK_EQUAL(lt(p1, p2), false);
121         BOOST_CHECK_EQUAL(lt(p1, p3), true);
122         BOOST_CHECK_EQUAL(lt(p1, p4), true);
123         BOOST_CHECK_EQUAL(lt(p1, p5), true);
124         BOOST_CHECK_EQUAL(lt(p3, p4), false);
125 
126         BOOST_CHECK_EQUAL(gt(p1, p2), false);
127         BOOST_CHECK_EQUAL(gt(p1, p3), false);
128         BOOST_CHECK_EQUAL(gt(p1, p4), false);
129         BOOST_CHECK_EQUAL(gt(p1, p5), false);
130         BOOST_CHECK_EQUAL(gt(p3, p4), true);
131     }
132 }
133 
134 
135 template <typename P>
test_2d_sort()136 void test_2d_sort()
137 {
138     std::vector<P> v;
139     v.push_back(bg::make<P>(3, 1));
140     v.push_back(bg::make<P>(2, 3));
141     v.push_back(bg::make<P>(2, 2));
142     v.push_back(bg::make<P>(1, 3));
143 
144     // Sort on coordinates in order x,y,z
145     std::sort(v.begin(), v.end(), bg::less<P>());
146     std::string s = coordinates(v);
147     BOOST_CHECK_EQUAL(s, "(1, 3)(2, 2)(2, 3)(3, 1)");
148 
149     // Reverse sort
150     std::sort(v.begin(), v.end(), bg::greater<P>());
151     s = coordinates(v);
152     BOOST_CHECK_EQUAL(s, "(3, 1)(2, 3)(2, 2)(1, 3)");
153 
154     // Sort backwards on coordinates in order x,y,z
155     //std::sort(v.begin(), v.end(), bg::greater<P>());
156     //std::string s = coordinates(v);
157     //BOOST_CHECK_EQUAL(s, "(1, 3)(2, 2)(2, 3)(3, 1)");
158 
159     // Refill to remove duplicate coordinates
160     v.clear();
161     v.push_back(bg::make<P>(4, 1));
162     v.push_back(bg::make<P>(3, 2));
163     v.push_back(bg::make<P>(2, 3));
164     v.push_back(bg::make<P>(1, 4));
165 
166     // Sort ascending on only x-coordinate
167     std::sort(v.begin(), v.end(), bg::less<P, 0>());
168     s = coordinates(v);
169     BOOST_CHECK_EQUAL(s, "(1, 4)(2, 3)(3, 2)(4, 1)");
170 
171     // Sort ascending on only y-coordinate
172     std::sort(v.begin(), v.end(), bg::less<P, 1>());
173     s = coordinates(v);
174     BOOST_CHECK_EQUAL(s, "(4, 1)(3, 2)(2, 3)(1, 4)");
175 
176     // Sort descending on only x-coordinate
177     std::sort(v.begin(), v.end(), bg::greater<P, 0>());
178     s = coordinates(v);
179     //BOOST_CHECK_EQUAL(s, "(4, 1)(3, 2)(2, 3)(1, 4)");
180 
181     // Sort descending on only y-coordinate
182     std::sort(v.begin(), v.end(), bg::greater<P, 1>());
183     s = coordinates(v);
184     BOOST_CHECK_EQUAL(s, "(1, 4)(2, 3)(3, 2)(4, 1)");
185 
186     // Make non-unique vector
187     v.push_back(bg::make<P>(4, 1));
188     v.push_back(bg::make<P>(3, 2));
189     v.push_back(bg::make<P>(2, 3));
190     v.push_back(bg::make<P>(1, 4));
191     v.push_back(bg::make<P>(1, 5));
192     std::sort(v.begin(), v.end(), bg::less<P>());
193     s = coordinates(v);
194     BOOST_CHECK_EQUAL(s, "(1, 4)(1, 4)(1, 5)(2, 3)(2, 3)(3, 2)(3, 2)(4, 1)(4, 1)");
195 
196 
197     std::vector<P> v2;
198     std::unique_copy(v.begin(), v.end(), std::back_inserter(v2), bg::equal_to<P>());
199     s = coordinates(v2);
200     BOOST_CHECK_EQUAL(s, "(1, 4)(1, 5)(2, 3)(3, 2)(4, 1)");
201 }
202 
203 
204 template <typename P>
test_spherical()205 void test_spherical()
206 {
207     //typedef typename bg::coordinate_type<P>::type ct;
208 
209     std::vector<P> v;
210     v.push_back(bg::make<P>( 180.00, 70.56));
211     v.push_back(bg::make<P>( 179.73, 71.56)); // east
212     v.push_back(bg::make<P>( 177.47, 71.23)); // less east
213     v.push_back(bg::make<P>(-178.78, 72.78)); // further east, = west, this is the most left point
214     v.push_back(bg::make<P>(-180.00, 73.12));
215 
216     // Sort on coordinates in order x,y,z
217     std::sort(v.begin(), v.end(), bg::less<P>());
218     std::string s = coordinates(v);
219     BOOST_CHECK_EQUAL(s, "(-178.78, 72.78)(177.47, 71.23)(179.73, 71.56)(180, 70.56)(-180, 73.12)");
220 
221     // Sort ascending on only y-coordinate
222     std::sort(v.begin(), v.end(), bg::less<P, 1>());
223     s = coordinates(v);
224     BOOST_CHECK_EQUAL(s, "(180, 70.56)(177.47, 71.23)(179.73, 71.56)(-178.78, 72.78)(-180, 73.12)");
225 
226     // Sort ascending on only x-coordinate
227     std::sort(v.begin(), v.end(), bg::less<P, 0>());
228     s = coordinates(v);
229     BOOST_CHECK((s == "(-178.78, 72.78)(177.47, 71.23)(179.73, 71.56)(180, 70.56)(-180, 73.12)"
230               || s == "(-178.78, 72.78)(177.47, 71.23)(179.73, 71.56)(-180, 73.12)(180, 70.56)"));
231 
232     // Sort ascending on only x-coordinate, but override with std-comparison,
233     // (so this is the normal sorting behaviour that would have been used
234     // if it would not have been spherical)
235     //std::sort(v.begin(), v.end(), bg::less<P, 0, std::less<ct> >());
236     //s = coordinates(v);
237     //BOOST_CHECK_EQUAL(s, "(-178.78, 70.78)(177.47, 71.23)(179.73, 71.56)");
238 }
239 
240 
test_main(int,char * [])241 int test_main(int, char* [])
242 {
243     test_2d_compare<bg::model::point<int, 2, bg::cs::cartesian> >();
244     test_2d_compare<bg::model::point<double, 2, bg::cs::cartesian> >();
245 
246     test_2d_sort<bg::model::point<int, 2, bg::cs::cartesian> >();
247     test_2d_sort<bg::model::point<float, 2, bg::cs::cartesian> >();
248     test_2d_sort<boost::tuple<double, double> >();
249     test_2d_sort<bg::model::point<double, 2, bg::cs::cartesian> >();
250 
251     test_spherical<bg::model::point<double, 2, bg::cs::spherical<bg::degree> > >();
252     test_spherical<bg::model::point<double, 2, bg::cs::spherical_equatorial<bg::degree> > >();
253     test_spherical<bg::model::point<double, 2, bg::cs::geographic<bg::degree> > >();
254 
255     return 0;
256 }
257