]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/geometry/test/io/wkt/wkt.cpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / libs / geometry / test / io / wkt / wkt.cpp
1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2 // Unit Test
3
4 // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
5 // Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
6 // Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
7
8 // This file was modified by Oracle on 2014-2020.
9 // Modifications copyright (c) 2014-2020 Oracle and/or its affiliates.
10
11 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
12
13 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
14 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
15
16 // Use, modification and distribution is subject to the Boost Software License,
17 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
18 // http://www.boost.org/LICENSE_1_0.txt)
19
20 #include <sstream>
21 #include <string>
22 #include <type_traits>
23
24 #include <boost/algorithm/string.hpp>
25
26 #include <geometry_test_common.hpp>
27
28 #include <boost/geometry/geometries/geometries.hpp>
29
30 #include <boost/geometry/algorithms/area.hpp>
31 #include <boost/geometry/algorithms/length.hpp>
32 #include <boost/geometry/algorithms/num_points.hpp>
33 #include <boost/geometry/algorithms/perimeter.hpp>
34 #include <boost/geometry/strategies/strategies.hpp>
35 #include <boost/geometry/core/point_type.hpp>
36 #include <boost/geometry/core/topological_dimension.hpp>
37 #include <boost/geometry/io/wkt/read.hpp>
38 #include <boost/geometry/io/wkt/write.hpp>
39 #include <boost/variant/variant.hpp>
40
41 template <typename G>
42 void check_wkt(G const& geometry, std::string const& expected)
43 {
44 std::ostringstream out;
45 out << bg::wkt(geometry);
46 BOOST_CHECK_EQUAL(boost::to_upper_copy(out.str()),
47 boost::to_upper_copy(expected));
48 }
49
50 template <typename G>
51 void test_wkt(std::string const& wkt, std::string const& expected,
52 std::size_t n, double len = 0, double ar = 0, double peri = 0)
53 {
54 G geometry;
55
56 bg::read_wkt(wkt, geometry);
57
58 /*
59 std::cout << "n=" << bg::num_points(geometry)
60 << " dim=" << bg::topological_dimension<G>::value
61 << " length=" << bg::length(geometry)
62 << " area=" << bg::area(geometry)
63 << " perimeter=" << bg::perimeter(geometry)
64 << std::endl << "\t\tgeometry=" << dsv(geometry)
65 << std::endl;
66 */
67
68 BOOST_CHECK_EQUAL(bg::num_points(geometry), n);
69 if (n > 0)
70 {
71 BOOST_CHECK_CLOSE(double(bg::length(geometry)), len, 0.0001);
72 BOOST_CHECK_CLOSE(double(bg::area(geometry)), ar, 0.0001);
73 BOOST_CHECK_CLOSE(double(bg::perimeter(geometry)), peri, 0.0001);
74 }
75
76 check_wkt(geometry, expected);
77 check_wkt(boost::variant<G>(geometry), expected);
78 }
79
80 template <typename G>
81 void test_wkt(std::string const& wkt,
82 std::size_t n, double len = 0, double ar = 0, double peri = 0)
83 {
84 test_wkt<G>(wkt, wkt, n, len, ar, peri);
85 }
86
87 template <typename G>
88 void test_relaxed_wkt(std::string const& wkt, std::string const& expected)
89 {
90 std::string e;
91 G geometry;
92 bg::read_wkt(wkt, geometry);
93 std::ostringstream out;
94 out << bg::wkt(geometry);
95
96 BOOST_CHECK_EQUAL(boost::to_upper_copy(out.str()), boost::to_upper_copy(expected));
97 }
98
99
100
101
102 template <typename G>
103 void test_wrong_wkt(std::string const& wkt, std::string const& start)
104 {
105 std::string e("no exception");
106 G geometry;
107 try
108 {
109 bg::read_wkt(wkt, geometry);
110 }
111 catch(bg::read_wkt_exception const& ex)
112 {
113 e = ex.what();
114 boost::to_lower(e);
115 }
116 catch(...)
117 {
118 e = "other exception";
119 }
120
121 BOOST_CHECK_MESSAGE(boost::starts_with(e, start), " Expected:"
122 << start << " Got:" << e << " with WKT: " << wkt);
123 }
124
125 template <typename G>
126 void test_wkt_output_iterator(std::string const& wkt)
127 {
128 G geometry;
129 bg::read_wkt<G>(wkt, std::back_inserter(geometry));
130 }
131
132
133
134 #ifndef GEOMETRY_TEST_MULTI
135 template <typename T>
136 void test_order_closure()
137 {
138 using namespace boost::geometry;
139 typedef bg::model::point<T, 2, bg::cs::cartesian> Pt;
140 typedef bg::model::polygon<Pt, true, true> PCWC;
141 typedef bg::model::polygon<Pt, true, false> PCWO;
142 typedef bg::model::polygon<Pt, false, true> PCCWC;
143 typedef bg::model::polygon<Pt, false, false> PCCWO;
144
145 {
146 std::string wkt_cwc = "POLYGON((0 0,0 2,2 2,2 0,0 0))";
147 std::string wkt_cwo = "POLYGON((0 0,0 2,2 2,2 0))";
148 std::string wkt_ccwc = "POLYGON((0 0,2 0,2 2,0 2,0 0))";
149 std::string wkt_ccwo = "POLYGON((0 0,2 0,2 2,0 2))";
150
151 test_wkt<PCWC>(wkt_cwc, 5, 0, 4, 8);
152 test_wkt<PCWO>(wkt_cwc, 4, 0, 4, 8);
153 test_wkt<PCWO>(wkt_cwo, wkt_cwc, 4, 0, 4, 8);
154 test_wkt<PCCWC>(wkt_ccwc, 5, 0, 4, 8);
155 test_wkt<PCCWO>(wkt_ccwc, 4, 0, 4, 8);
156 test_wkt<PCCWO>(wkt_ccwo, wkt_ccwc, 4, 0, 4, 8);
157 }
158 {
159 std::string wkt_cwc = "POLYGON((0 0,0 3,3 3,3 0,0 0),(1 1,2 1,2 2,1 2,1 1))";
160 std::string wkt_cwo = "POLYGON((0 0,0 3,3 3,3 0),(1 1,2 1,2 2,1 2))";
161 std::string wkt_ccwc = "POLYGON((0 0,3 0,3 3,0 3,0 0),(1 1,1 2,2 2,2 1,1 1))";
162 std::string wkt_ccwo = "POLYGON((0 0,3 0,3 3,0 3),(1 1,1 2,2 2,2 1,1 1))";
163
164 test_wkt<PCWC>(wkt_cwc, 10, 0, 8, 16);
165 test_wkt<PCWO>(wkt_cwc, 8, 0, 8, 16);
166 test_wkt<PCWO>(wkt_cwo, wkt_cwc, 8, 0, 8, 16);
167 test_wkt<PCCWC>(wkt_ccwc, 10, 0, 8, 16);
168 test_wkt<PCCWO>(wkt_ccwc, 8, 0, 8, 16);
169 test_wkt<PCCWO>(wkt_ccwo, wkt_ccwc, 8, 0, 8, 16);
170 }
171 }
172
173 template <typename T>
174 void test_all()
175 {
176 using namespace boost::geometry;
177 typedef bg::model::point<T, 2, bg::cs::cartesian> P;
178
179 test_wkt<P>("POINT(1 2)", 1);
180 test_wkt<bg::model::linestring<P> >("LINESTRING(1 1,2 2,3 3)", 3, 2 * sqrt(2.0));
181 test_wkt<bg::model::polygon<P> >("POLYGON((0 0,0 4,4 4,4 0,0 0)"
182 ",(1 1,1 2,2 2,2 1,1 1),(1 1,1 2,2 2,2 1,1 1))", 15, 0, 18, 24);
183
184 // Non OGC: a box defined by a polygon
185 //test_wkt<box<P> >("POLYGON((0 0,0 1,1 1,1 0,0 0))", 4, 0, 1, 4);
186 test_wkt<bg::model::ring<P> >("POLYGON((0 0,0 1,1 1,1 0,0 0))", 5, 0, 1, 4);
187
188 // We accept empty sequences as well (much better than EMPTY)...
189 // ...or even POINT() (see below)
190 test_wkt<bg::model::linestring<P> >("LINESTRING()", 0, 0);
191 test_wkt<bg::model::polygon<P> >("POLYGON(())", 0);
192 // ... or even with empty holes
193 test_wkt<bg::model::polygon<P> >("POLYGON((),(),())", 0);
194 // which all make no valid geometries, but they can exist.
195
196 // These WKT's are incomplete or abnormal but they are considered OK
197 test_relaxed_wkt<P>("POINT(1)", "POINT(1 0)");
198 test_relaxed_wkt<P>("POINT()", "POINT(0 0)");
199 test_relaxed_wkt<bg::model::linestring<P> >("LINESTRING(1,2,3)",
200 "LINESTRING(1 0,2 0,3 0)");
201 test_relaxed_wkt<P>("POINT ( 1 2) ", "POINT(1 2)");
202 test_relaxed_wkt<P>("POINT M ( 1 2)", "POINT(1 2)");
203 test_relaxed_wkt<bg::model::box<P> >("BOX(1 1,2 2)", "POLYGON((1 1,1 2,2 2,2 1,1 1))");
204
205 test_relaxed_wkt<bg::model::linestring<P> >("LINESTRING EMPTY", "LINESTRING()");
206
207 test_relaxed_wkt<bg::model::polygon<P> >("POLYGON( ( ) , ( ) , ( ) )",
208 "POLYGON((),(),())");
209
210 // Wrong WKT's
211 test_wrong_wkt<P>("POINT(1 2", "expected ')'");
212 test_wrong_wkt<P>("POINT 1 2)", "expected '('");
213 test_wrong_wkt<P>("POINT(1 2,)", "expected ')'");
214 test_wrong_wkt<P>("POINT(1 2)foo", "too many tokens at 'foo'");
215 test_wrong_wkt<P>("POINT(1 2 3)", "expected ')'");
216 test_wrong_wkt<P>("POINT(a 2 3)", "bad lexical cast");
217 test_wrong_wkt<P>("POINT 2 3", "expected '('");
218 test_wrong_wkt<P>("POINT Z (1 2 3)", "z only allowed");
219
220 test_wrong_wkt<P>("PIONT (1 2)", "should start with 'point'");
221
222 test_wrong_wkt<bg::model::linestring<P> >("LINESTRING())", "too many tokens");
223
224 test_wrong_wkt<bg::model::polygon<P> >("POLYGON((1 1,1 4,4 4,4 1,1 1)"
225 ",((2 2,2 3,3 3,3 2,2 2))", "bad lexical cast");
226
227 test_wrong_wkt<bg::model::box<P> >("BOX(1 1,2 2,3 3)", "box should have 2");
228 test_wrong_wkt<bg::model::box<P> >("BOX(1 1,2 2) )", "too many tokens");
229
230 if ( BOOST_GEOMETRY_CONDITION(std::is_floating_point<T>::value
231 || ! std::is_fundamental<T>::value ) )
232 {
233 test_wkt<P>("POINT(1.1 2.1)", 1);
234 }
235
236 // Deprecated:
237 // test_wkt_output_iterator<bg::model::linestring<P> >("LINESTRING(1 1,2 2,3 3)");
238 // test_wkt_output_iterator<bg::model::ring<P> >("POLYGON((1 1,2 2,3 3))");
239
240 test_order_closure<T>();
241 }
242 #endif
243
244 int test_main(int, char* [])
245 {
246 test_all<double>();
247 test_all<int>();
248
249 return 0;
250 }
251
252 /*
253
254 Results can be checked in PostGIS by query below,
255 or by MySQL (but replace length by glength and remove the perimeter)
256
257 Note:
258 - PostGIS gives "3" for a numpoints of a multi-linestring of 6 points in total (!)
259 --> "npoints" should be taken for all geometries
260 - SQL Server 2008 gives "6"
261 select geometry::STGeomFromText('MULTILINESTRING((1 1,2 2,3 3),(4 4,5 5,6 6))',0).STNumPoints()
262 - MySQL gives "NULL"
263
264 select 1 as code,'np p' as header,npoints(geomfromtext('POINT(1 2)')) as contents
265 union select 2,'length point', length(geomfromtext('POINT(1 2)'))
266 union select 3,'peri point', perimeter(geomfromtext('POINT(1 2)'))
267 union select 4,'area point',area(geomfromtext('POINT(1 2)'))
268
269
270 union select 5,'# ls',npoints(geomfromtext('LINESTRING(1 1,2 2,3 3)'))
271 union select 6,'length ls',length(geomfromtext('LINESTRING(1 1,2 2,3 3)'))
272 union select 7,'peri ls',perimeter(geomfromtext('LINESTRING(1 1,2 2,3 3)'))
273 union select 8,'aera ls',area(geomfromtext('LINESTRING(1 1,2 2,3 3)'))
274
275 union select 9,'# poly',npoints(geomfromtext('POLYGON((0 0,0 4,4 4,4 0,0 0),(1 1,1 2,2 2,2 1,1 1),(1 1,1 2,2 2,2 1,1 1))'))
276 union select 10,'length poly',length(geomfromtext('POLYGON((0 0,0 4,4 4,4 0,0 0),(1 1,1 2,2 2,2 1,1 1),(1 1,1 2,2 2,2 1,1 1))'))
277 union select 11,'peri poly',perimeter(geomfromtext('POLYGON((0 0,0 4,4 4,4 0,0 0),(1 1,1 2,2 2,2 1,1 1),(1 1,1 2,2 2,2 1,1 1))'))
278 union select 12,'area poly',area(geomfromtext('POLYGON((0 0,0 4,4 4,4 0,0 0),(1 1,1 2,2 2,2 1,1 1),(1 1,1 2,2 2,2 1,1 1))'))
279
280 */