1 //
2 // Test Suite for geos::operation::geounion::UnaryUnionOp class.
3 
4 // tut
5 #include <tut/tut.hpp>
6 // geos
7 #include <geos/operation/union/UnaryUnionOp.h>
8 #include <geos/geom/GeometryFactory.h>
9 #include <geos/geom/Geometry.h>
10 #include <geos/geom/Polygon.h>
11 #include <geos/geom/Point.h>
12 #include <geos/io/WKTReader.h>
13 #include <geos/io/WKTWriter.h>
14 // std
15 #include <memory>
16 #include <string>
17 #include <vector>
18 #include <iostream>
19 
20 namespace tut {
21 //
22 // Test Group
23 //
24 
25 // Common data used by tests
26 struct test_unaryuniontest_data {
27     typedef geos::geom::GeometryFactory GeometryFactory;
28     GeometryFactory::Ptr gf;
29     geos::io::WKTReader wktreader;
30     geos::io::WKTWriter wktwriter;
31 
32     typedef geos::geom::Geometry::Ptr GeomPtr;
33     typedef geos::geom::Geometry Geom;
34     typedef geos::operation::geounion::UnaryUnionOp UnaryUnionOp;
35 
test_unaryuniontest_datatut::test_unaryuniontest_data36     test_unaryuniontest_data()
37         : gf(GeometryFactory::create()),
38           wktreader(gf.get())
39     {
40         wktwriter.setTrim(true);
41     }
42 
43     void
delAlltut::test_unaryuniontest_data44     delAll(std::vector<Geom*>& geoms)
45     {
46         for(size_t i = 0; i < geoms.size(); ++i) {
47             delete geoms[i];
48         }
49     }
50 
51     GeomPtr
readWKTtut::test_unaryuniontest_data52     readWKT(const std::string& inputWKT)
53     {
54         return GeomPtr(wktreader.read(inputWKT));
55     }
56 
57     void
readWKTtut::test_unaryuniontest_data58     readWKT(const char* const* inputWKT, std::vector<Geom*>& geoms)
59     {
60         for(const char* const* ptr = inputWKT; *ptr; ++ptr) {
61             geoms.push_back(readWKT(*ptr).release());
62         }
63     }
64 
65     static GeomPtr
normalizetut::test_unaryuniontest_data66     normalize(const Geom& g)
67     {
68         GeomPtr g2(g.clone());
69         g2->normalize();
70         return g2;
71     }
72 
73     bool
isEqualtut::test_unaryuniontest_data74     isEqual(const Geom& a, const Geom& b)
75     {
76         using std::cout;
77         using std::endl;
78         GeomPtr a2 = normalize(a);
79         GeomPtr b2 = normalize(b);
80         bool eq = a2->equalsExact(b2.get());
81         if(! eq) {
82             cout << "OBTAINED: " << wktwriter.write(b2.get()) << endl;
83         }
84         return eq;
85     }
86 
87     void
doTesttut::test_unaryuniontest_data88     doTest(const char* const* inputWKT, const std::string& expectedWKT)
89     {
90         std::vector<Geom*> geoms;
91         readWKT(inputWKT, geoms);
92 
93         GeomPtr result;
94         if(geoms.empty()) {
95             result = UnaryUnionOp::Union(geoms, *gf);
96         }
97         else {
98             result = UnaryUnionOp::Union(geoms);
99         }
100 
101         bool ok = isEqual(*readWKT(expectedWKT), *result);
102         delAll(geoms);
103 
104         ensure(ok);
105     }
106 
107 };
108 
109 typedef test_group<test_unaryuniontest_data> group;
110 typedef group::object object;
111 
112 group test_unaryuniontest_group("geos::operation::geounion::UnaryUnionOp");
113 
114 template<>
115 template<>
test()116 void object::test<1>
117 ()
118 {
119     static char const* const geoms[] = { nullptr };
120     doTest(geoms, "GEOMETRYCOLLECTION EMPTY");
121 }
122 
123 template<>
124 template<>
test()125 void object::test<2>
126 ()
127 {
128     static char const* const geoms[] = {
129         "POINT (1 1)", "POINT (2 2)",
130         nullptr
131     };
132     doTest(geoms, "MULTIPOINT ((1 1), (2 2))");
133 }
134 
135 template<>
136 template<>
test()137 void object::test<3>
138 ()
139 {
140     static char const* const geoms[] = {
141         "GEOMETRYCOLLECTION (POLYGON ((0 0, 0 90, 90 90, 90 0, 0 0)),   POLYGON ((120 0, 120 90, 210 90, 210 0, 120 0)),  LINESTRING (40 50, 40 140),  LINESTRING (160 50, 160 140),  POINT (60 50),  POINT (60 140),  POINT (40 140))",
142         nullptr
143     };
144     doTest(geoms,
145            "GEOMETRYCOLLECTION (POINT (60 140),   LINESTRING (40 90, 40 140), LINESTRING (160 90, 160 140), POLYGON ((0 0, 0 90, 40 90, 90 90, 90 0, 0 0)), POLYGON ((120 0, 120 90, 160 90, 210 90, 210 0, 120 0)))");
146 }
147 
148 template<>
149 template<>
test()150 void object::test<4>
151 ()
152 {
153     static char const* const geoms[] = {
154         "POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0))",
155         "MULTIPOLYGON (((20 0, 20 10, 40 10, 40 0, 20 0)),((5 5, 5 8, 8 8, 8 5, 5 5)))",
156         "POINT (5 5)",
157         "POINT (-5 5)",
158         "LINESTRING (-10 -10, -10 0, -10 20)",
159         "LINESTRING (-10 2, 10 2)",
160         nullptr
161     };
162     doTest(geoms,
163            "GEOMETRYCOLLECTION (POLYGON ((0 0, 0 2, 0 10, 10 10, 10 2, 10 0, 0 0)), POLYGON ((20 0, 20 10, 40 10, 40 0, 20 0)), LINESTRING (-10 -10, -10 0, -10 2), LINESTRING (-10 2, 0 2), LINESTRING (-10 2, -10 20), POINT (-5 5))");
164 
165 }
166 
167 template<>
168 template<>
test()169 void object::test<5>
170 ()
171 {
172     static char const* const geoms[] = {
173         "LINESTRING (40 60, 120 110)",
174         "POINT (120 110)",
175         "POINT (40 60)",
176         "POINT (100 70)",
177         "POINT (80 50)",
178         nullptr
179     };
180     doTest(geoms, "GEOMETRYCOLLECTION (POINT (80 50), POINT (100 70), LINESTRING (40 60, 120 110))");
181 }
182 
183 template<>
184 template<>
test()185 void object::test<6>
186 ()
187 {
188     static char const* const geoms[] = {
189         "LINESTRING (0 0, 10 0, 5 -5, 5 5)",
190         nullptr
191     };
192     doTest(geoms, "MULTILINESTRING ((0 0, 5 0), (5 0, 10 0, 5 -5, 5 0), (5 0, 5 5))");
193 }
194 
195 template<>
196 template<>
test()197 void object::test<7>
198 ()
199 {
200     static char const* const geoms[] = {
201         "LINESTRING EMPTY",
202         nullptr
203     };
204     doTest(geoms, "LINESTRING EMPTY");
205 }
206 
207 } // namespace tut
208 
209