]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/geometry/test/io/wkt/wkt.cpp
1 // Boost.Geometry (aka GGL, Generic Geometry Library)
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.
8 // This file was modified by Oracle on 2014-2020.
9 // Modifications copyright (c) 2014-2020 Oracle and/or its affiliates.
11 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
13 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
14 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
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)
22 #include <type_traits>
24 #include <boost/algorithm/string.hpp>
26 #include <geometry_test_common.hpp>
28 #include <boost/geometry/geometries/geometries.hpp>
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>
42 void check_wkt(G
const& geometry
, std::string
const& expected
)
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
));
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)
56 bg::read_wkt(wkt
, geometry
);
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)
68 BOOST_CHECK_EQUAL(bg::num_points(geometry
), n
);
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);
76 check_wkt(geometry
, expected
);
77 check_wkt(boost::variant
<G
>(geometry
), expected
);
81 void test_wkt(std::string
const& wkt
,
82 std::size_t n
, double len
= 0, double ar
= 0, double peri
= 0)
84 test_wkt
<G
>(wkt
, wkt
, n
, len
, ar
, peri
);
88 void test_relaxed_wkt(std::string
const& wkt
, std::string
const& expected
)
92 bg::read_wkt(wkt
, geometry
);
93 std::ostringstream out
;
94 out
<< bg::wkt(geometry
);
96 BOOST_CHECK_EQUAL(boost::to_upper_copy(out
.str()), boost::to_upper_copy(expected
));
102 template <typename G
>
103 void test_wrong_wkt(std::string
const& wkt
, std::string
const& start
)
105 std::string
e("no exception");
109 bg::read_wkt(wkt
, geometry
);
111 catch(bg::read_wkt_exception
const& ex
)
118 e
= "other exception";
121 BOOST_CHECK_MESSAGE(boost::starts_with(e
, start
), " Expected:"
122 << start
<< " Got:" << e
<< " with WKT: " << wkt
);
125 template <typename G
>
126 void test_wkt_output_iterator(std::string
const& wkt
)
129 bg::read_wkt
<G
>(wkt
, std::back_inserter(geometry
));
134 #ifndef GEOMETRY_TEST_MULTI
135 template <typename T
>
136 void test_order_closure()
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
;
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))";
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);
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))";
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);
173 template <typename T
>
176 using namespace boost::geometry
;
177 typedef bg::model::point
<T
, 2, bg::cs::cartesian
> P
;
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);
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);
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.
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))");
205 test_relaxed_wkt
<bg::model::linestring
<P
> >("LINESTRING EMPTY", "LINESTRING()");
207 test_relaxed_wkt
<bg::model::polygon
<P
> >("POLYGON( ( ) , ( ) , ( ) )",
208 "POLYGON((),(),())");
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");
220 test_wrong_wkt
<P
>("PIONT (1 2)", "should start with 'point'");
222 test_wrong_wkt
<bg::model::linestring
<P
> >("LINESTRING())", "too many tokens");
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");
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");
230 if ( BOOST_GEOMETRY_CONDITION(std::is_floating_point
<T
>::value
231 || ! std::is_fundamental
<T
>::value
) )
233 test_wkt
<P
>("POINT(1.1 2.1)", 1);
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))");
240 test_order_closure
<T
>();
244 int test_main(int, char* [])
254 Results can be checked in PostGIS by query below,
255 or by MySQL (but replace length by glength and remove the perimeter)
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()
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)'))
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)'))
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))'))