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