• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2 // Unit Test
3 
4 // Copyright (c) 2014-2019 Barend Gehrels, Amsterdam, the Netherlands.
5 
6 // Use, modification and distribution is subject to the Boost Software License,
7 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
8 // http://www.boost.org/LICENSE_1_0.txt)
9 
10 #include "test_buffer.hpp"
11 
12 
13 template <typename MultiPolygon>
read_from_file(std::string const & filename)14 std::string read_from_file(std::string const& filename)
15 {
16     MultiPolygon mp;
17     std::ifstream in(filename.c_str());
18     while (in.good())
19     {
20         std::string line;
21         std::getline(in, line);
22         if (! line.empty())
23         {
24             typename boost::range_value<MultiPolygon>::type pol;
25             bg::read_wkt(line, pol);
26             mp.push_back(pol);
27         }
28     }
29     std::ostringstream out;
30     if (! mp.empty())
31     {
32         out << std::fixed << std::setprecision(19) << bg::wkt(mp);
33     }
34 
35     BOOST_CHECK(! out.str().empty());
36 
37     return out.str();
38 }
39 
40 
41 /*
42 
43 Area's from PostGIS:
44 
45 query:
46     with viewy as
47     (
48       select ST_GeomFromText((insert WKT here from data),0) as p1
49     )
50               select 10 as w,ST_NumGeometries(p1),ST_Area(ST_Buffer(p1, 10.0 * 1000, 25)),ST_NumGeometries(ST_Buffer(p1, 10.0 * 1000, 25))from viewy
51     union all select 20 as w,ST_NumGeometries(p1),ST_Area(ST_Buffer(p1, 20.0 * 1000, 25)),ST_NumGeometries(ST_Buffer(p1, 20.0 * 1000, 25))from viewy
52     union all select 50 as w,ST_NumGeometries(p1),ST_Area(ST_Buffer(p1, 50.0 * 1000, 25)),ST_NumGeometries(ST_Buffer(p1, 50.0 * 1000, 25))from viewy
53     union all select 100 as w,ST_NumGeometries(p1),ST_Area(ST_Buffer(p1, 100.0 * 1000, 25)),ST_NumGeometries(ST_Buffer(p1, 100.0 * 1000, 25))from viewy
54     union all select -10 as w,ST_NumGeometries(p1),ST_Area(ST_Buffer(p1, -10.0 * 1000, 25)),ST_NumGeometries(ST_Buffer(p1, -10.0 * 1000, 25))from viewy
55     union all select -20 as w,ST_NumGeometries(p1),ST_Area(ST_Buffer(p1, -20.0 * 1000, 25)),ST_NumGeometries(ST_Buffer(p1, -20.0 * 1000, 25))from viewy
56     union all select -50 as w,ST_NumGeometries(p1),ST_Area(ST_Buffer(p1, -50.0 * 1000, 25)),ST_NumGeometries(ST_Buffer(p1, -50.0 * 1000, 25))from viewy
57     union all select -100 as w,ST_NumGeometries(p1),ST_Area(ST_Buffer(p1, -100.0 * 1000, 25)),ST_NumGeometries(ST_Buffer(p1, -100.0 * 1000, 25))from viewy
58 
59 Checked are 10,20,50,100 kilometer, inflate/deflate
60 
61 But for many, in the unit tests below, distance of 1,2,5 k are kept too
62 because they could cause self-intersections in the past
63 
64 Values are not identical. We might check area with less precision.
65 
66 gr:
67     336277774579
68     442312549699
69     680433051228
70     910463608938
71 
72     139313936462
73      96993175731
74      31392586710
75       2033070670
76 
77 it:
78      655017269701
79      749348852219
80     1018311961402
81     1436442592714
82 
83     477946399339
84     404696093915
85     238752534654
86      69771921799
87 
88 nl:
89     123407901256
90     145045853638
91     201203536326
92     303295187184
93 
94     64669284652
95     46684337476
96     10245330928
97     0
98 
99 no:
100     2102032030338
101     2292165016326
102     2725461758029
103     3374949015149
104 
105     1361202945650
106     1089854028969
107      649632754053
108      306749522531
109 
110 uk:
111     857680535981
112     970483182932
113    1247820319617
114    1659854829029
115 
116     572557777232
117     479260087245
118     274834862993
119      78209736228
120 
121 */
122 
123 template <typename MP, typename P>
test_one(std::string const & caseid,std::string const & wkt,double expected_area,double distance,ut_settings settings=ut_settings ())124 void test_one(std::string const& caseid, std::string const& wkt, double expected_area, double distance,
125               ut_settings settings = ut_settings())
126 {
127     bg::strategy::buffer::join_round join_round(100);
128     bg::strategy::buffer::end_flat end_flat;
129 
130     // Test with a high tolerance, even a difference of 1000 is only ~1.0e-6%
131 
132     settings.tolerance = 10000.0;
133 
134 #if ! defined(BOOST_GEOMETRY_USE_RESCALING)
135     // in case robustness policies are changed, areas should be adapted
136     settings.tolerance = boost::starts_with(caseid, "no") ? 200000.0 : 100000.0;
137 #endif
138 
139     test_one<MP, P>(caseid, wkt, join_round, end_flat,
140         expected_area, distance * 1000.0, settings);
141 }
142 
143 
144 template <bool Clockwise, typename P>
test_all()145 void test_all()
146 {
147     typedef bg::model::polygon<P, Clockwise> pt;
148     typedef bg::model::multi_polygon<pt> mpt;
149 
150     std::string base_folder = "data/";
151     std::string gr = read_from_file<mpt>(base_folder + "gr.wkt");
152     std::string it = read_from_file<mpt>(base_folder + "it.wkt");
153     std::string nl = read_from_file<mpt>(base_folder + "nl.wkt");
154     std::string no = read_from_file<mpt>(base_folder + "no.wkt");
155     std::string uk = read_from_file<mpt>(base_folder + "uk.wkt");
156 
157     test_one<mpt, pt>("gr10", gr,    336279815682, 10);
158     test_one<mpt, pt>("gr20", gr,    442317491749, 20);
159     test_one<mpt, pt>("gr50", gr,    680442278645, 50);
160     test_one<mpt, pt>("gr100", gr,   910474621215, 100);
161 
162     test_one<mpt, pt>("gr10", gr,    139313156846, -10);
163     test_one<mpt, pt>("gr20", gr,     96991350242, -20);
164     test_one<mpt, pt>("gr50", gr,     31391928002, -50);
165     test_one<mpt, pt>("gr100", gr,     2035400805, -100);
166 
167     test_one<mpt, pt>("it1", it,     569862998347, 1);
168     test_one<mpt, pt>("it2", it,     579239208963, 2);
169     test_one<mpt, pt>("it5", it,     607625463736, 5);
170     test_one<mpt, pt>("it10", it,    655018578530, 10);
171     test_one<mpt, pt>("it20", it,    749353305743, 20);
172     test_one<mpt, pt>("it50", it,   1018323115670, 50);
173     test_one<mpt, pt>("it100", it,  1436451405439, 100);
174 
175     test_one<mpt, pt>("it1", it,     551474421881, -1);
176     test_one<mpt, pt>("it2", it,     542617730624, -2);
177     test_one<mpt, pt>("it5", it,     517402445790, -5);
178     test_one<mpt, pt>("it10", it,    477945510429, -10);
179     test_one<mpt, pt>("it20", it,    404693983797, -20);
180     test_one<mpt, pt>("it50", it,    238748449624, -50);
181     test_one<mpt, pt>("it100", it,    69768648896, -100);
182     test_one<mpt, pt>("it200", it,              0, -200);
183 
184     test_one<mpt, pt>("nl1", nl,      97391170774, 1);
185     test_one<mpt, pt>("nl2", nl,     100816707832, 2);
186     test_one<mpt, pt>("nl5", nl,     110239801028, 5);
187     test_one<mpt, pt>("nl10", nl,    123408274536, 10);
188     test_one<mpt, pt>("nl20", nl,    145046915403, 20);
189     test_one<mpt, pt>("nl50", nl,    201207309002, 50);
190     test_one<mpt, pt>("nl100", nl,   303300936340, 100);
191 
192     test_one<mpt, pt>("nl1", nl,      90095050333, -1);
193     test_one<mpt, pt>("nl2", nl,      86601861798, -2);
194     test_one<mpt, pt>("nl5", nl,      77307843754, -5);
195     test_one<mpt, pt>("nl10", nl,     64668870425, -10);
196     test_one<mpt, pt>("nl20", nl,     46683531062, -20);
197     test_one<mpt, pt>("nl50", nl,     10244523910, -50);
198     test_one<mpt, pt>("nl100", nl,              0, -100);
199 
200     test_one<mpt, pt>("no1", no,    1819566570720, 1);
201     test_one<mpt, pt>("no2", no,    1865041238129, 2, ut_settings::ignore_validity());
202     test_one<mpt, pt>("no5", no,    1973615533600, 5);
203     test_one<mpt, pt>("no10", no,   2102034240506, 10);
204     test_one<mpt, pt>("no20", no,   2292171257647, 20);
205     test_one<mpt, pt>("no50", no,   2725475403816, 50);
206     test_one<mpt, pt>("no100", no,  3374987120112, 100);
207 
208     test_one<mpt, pt>("no1", no,    1725145487969, -1);
209     test_one<mpt, pt>("no2", no,    1678942603503, -2);
210     test_one<mpt, pt>("no5", no,    1547329249723, -5);
211     test_one<mpt, pt>("no10", no,   1361198873951, -10);
212     test_one<mpt, pt>("no20", no,   1089847815351, -20);
213     test_one<mpt, pt>("no50", no,    649622162382, -50);
214     test_one<mpt, pt>("no100", no,   306739133606, -100);
215 
216     test_one<mpt, pt>("uk1", uk,     733080790315, 1);
217     test_one<mpt, pt>("uk2", uk,     749555939251, 2);
218     test_one<mpt, pt>("uk5", uk,     793752660191, 5);
219     test_one<mpt, pt>("uk10", uk,    857682286960, 10);
220     test_one<mpt, pt>("uk20", uk,    970488082763, 20);
221     test_one<mpt, pt>("uk50", uk,   1247830325401, 50);
222     test_one<mpt, pt>("uk100", uk,  1659861958875, 100);
223 
224     test_one<mpt, pt>("uk1", uk,     699378146599, -1);
225     test_one<mpt, pt>("uk2", uk,     683086442146, -2);
226     test_one<mpt, pt>("uk5", uk,     637325279340, -5);
227     test_one<mpt, pt>("uk10", uk,    572556625332, -10);
228     test_one<mpt, pt>("uk20", uk,    479258129205, -20);
229     test_one<mpt, pt>("uk50", uk,    274828071591, -50);
230     test_one<mpt, pt>("uk100", uk,    78205461294, -100);
231 }
232 
test_main(int,char * [])233 int test_main(int, char* [])
234 {
235     BoostGeometryWriteTestConfiguration();
236 
237     test_all<true, bg::model::point<default_test_type, 2, bg::cs::cartesian> >();
238 
239 #if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_ORDER)
240     test_all<false, bg::model::point<default_test_type, 2, bg::cs::cartesian> >();
241 #endif
242 
243 #if defined(BOOST_GEOMETRY_TEST_FAILURES)
244     BoostGeometryWriteExpectedFailures(1, BG_NO_FAILURES);
245 #endif
246 
247     return 0;
248 }
249 
250