1 //
2 // Test Suite for C-API GEOSDelaunayTriangulation
3
4 #include <tut/tut.hpp>
5 // geos
6 #include <geos_c.h>
7 // std
8 #include <cstdarg>
9 #include <cstdio>
10 #include <cstdlib>
11 #include <memory>
12
13 namespace tut {
14 //
15 // Test Group
16 //
17
18 // Common data used in test cases.
19 struct test_capigeosdelaunaytriangulation_data {
20 GEOSGeometry* geom1_;
21 GEOSGeometry* geom2_;
22 GEOSWKTWriter* w_;
23
24 static void
noticetut::test_capigeosdelaunaytriangulation_data25 notice(const char* fmt, ...)
26 {
27 std::fprintf(stdout, "NOTICE: ");
28
29 va_list ap;
30 va_start(ap, fmt);
31 std::vfprintf(stdout, fmt, ap);
32 va_end(ap);
33
34 std::fprintf(stdout, "\n");
35 }
36
test_capigeosdelaunaytriangulation_datatut::test_capigeosdelaunaytriangulation_data37 test_capigeosdelaunaytriangulation_data()
38 : geom1_(nullptr), geom2_(nullptr)
39 {
40 initGEOS(notice, notice);
41 w_ = GEOSWKTWriter_create();
42 GEOSWKTWriter_setTrim(w_, 1);
43 }
44
45 void
ensure_equals_wkttut::test_capigeosdelaunaytriangulation_data46 ensure_equals_wkt(GEOSGeometry* g, const std::string& exp)
47 {
48 GEOSNormalize(g);
49 char* wkt_c = GEOSWKTWriter_write(w_, g);
50 std::string out(wkt_c);
51 free(wkt_c);
52 ensure_equals(out, exp);
53 }
54
~test_capigeosdelaunaytriangulation_datatut::test_capigeosdelaunaytriangulation_data55 ~test_capigeosdelaunaytriangulation_data()
56 {
57 GEOSGeom_destroy(geom1_);
58 GEOSGeom_destroy(geom2_);
59 GEOSWKTWriter_destroy(w_);
60 geom1_ = nullptr;
61 geom2_ = nullptr;
62 finishGEOS();
63 }
64
65 };
66
67 typedef test_group<test_capigeosdelaunaytriangulation_data> group;
68 typedef group::object object;
69
70 group test_capigeosdelaunaytriangulation_group("capi::GEOSDelaunayTriangulation");
71
72 //
73 // Test Cases
74 //
75
76 // Empty polygon
77 template<>
78 template<>
test()79 void object::test<1>
80 ()
81 {
82 geom1_ = GEOSGeomFromWKT("POLYGON EMPTY");
83
84 ensure_equals(GEOSisEmpty(geom1_), 1);
85
86 geom2_ = GEOSDelaunayTriangulation(geom1_, 0, 0);
87 ensure_equals(GEOSisEmpty(geom2_), 1);
88 ensure_equals(GEOSGeomTypeId(geom2_), GEOS_GEOMETRYCOLLECTION);
89
90 GEOSGeom_destroy(geom2_);
91 geom2_ = GEOSDelaunayTriangulation(geom1_, 0, 1);
92 ensure_equals(GEOSisEmpty(geom2_), 1);
93 ensure_equals(GEOSGeomTypeId(geom2_), GEOS_MULTILINESTRING);
94
95
96 }
97
98 // Single point
99 template<>
100 template<>
test()101 void object::test<2>
102 ()
103 {
104 geom1_ = GEOSGeomFromWKT("POINT(0 0)");
105
106 geom2_ = GEOSDelaunayTriangulation(geom1_, 0, 0);
107 ensure_equals(GEOSisEmpty(geom2_), 1);
108 ensure_equals(GEOSGeomTypeId(geom2_), GEOS_GEOMETRYCOLLECTION);
109
110 GEOSGeom_destroy(geom2_);
111 geom2_ = GEOSDelaunayTriangulation(geom1_, 0, 1);
112 ensure_equals(GEOSisEmpty(geom2_), 1);
113 ensure_equals(GEOSGeomTypeId(geom2_), GEOS_MULTILINESTRING);
114 }
115
116 // Three collinear points
117 template<>
118 template<>
test()119 void object::test<3>
120 ()
121 {
122 geom1_ = GEOSGeomFromWKT("MULTIPOINT(0 0, 5 0, 10 0)");
123
124 geom2_ = GEOSDelaunayTriangulation(geom1_, 0, 0);
125 ensure_equals(GEOSisEmpty(geom2_), 1);
126 ensure_equals(GEOSGeomTypeId(geom2_), GEOS_GEOMETRYCOLLECTION);
127
128 GEOSGeom_destroy(geom2_);
129 geom2_ = GEOSDelaunayTriangulation(geom1_, 0, 1);
130 char* wkt_c = GEOSWKTWriter_write(w_, geom2_);
131 std::string out(wkt_c);
132 free(wkt_c);
133 ensure_equals(out, "MULTILINESTRING ((5 0, 10 0), (0 0, 5 0))");
134 }
135
136 // Three points
137 template<>
138 template<>
test()139 void object::test<4>
140 ()
141 {
142 geom1_ = GEOSGeomFromWKT("MULTIPOINT(0 0, 5 0, 10 10)");
143
144 geom2_ = GEOSDelaunayTriangulation(geom1_, 0, 0);
145 ensure(geom2_ != nullptr);
146 ensure_equals_wkt(geom2_,
147 "GEOMETRYCOLLECTION (POLYGON ((0 0, 10 10, 5 0, 0 0)))"
148 );
149
150 GEOSGeom_destroy(geom2_);
151 geom2_ = GEOSDelaunayTriangulation(geom1_, 0, 1);
152 ensure_equals_wkt(geom2_,
153 "MULTILINESTRING ((5 0, 10 10), (0 0, 10 10), (0 0, 5 0))"
154 );
155 }
156
157 // A polygon with an hole
158 template<>
159 template<>
test()160 void object::test<5>
161 ()
162 {
163 geom1_ = GEOSGeomFromWKT("POLYGON((0 0, 8.5 1, 10 10, 0.5 9, 0 0),(2 2, 3 8, 7 8, 8 2, 2 2)))");
164
165 geom2_ = GEOSDelaunayTriangulation(geom1_, 0, 0);
166 ensure(geom2_ != nullptr);
167 ensure_equals_wkt(geom2_,
168 "GEOMETRYCOLLECTION (POLYGON ((8 2, 10 10, 8.5 1, 8 2)), POLYGON ((7 8, 10 10, 8 2, 7 8)), POLYGON ((3 8, 10 10, 7 8, 3 8)), POLYGON ((2 2, 8 2, 8.5 1, 2 2)), POLYGON ((2 2, 7 8, 8 2, 2 2)), POLYGON ((2 2, 3 8, 7 8, 2 2)), POLYGON ((0.5 9, 10 10, 3 8, 0.5 9)), POLYGON ((0.5 9, 3 8, 2 2, 0.5 9)), POLYGON ((0 0, 2 2, 8.5 1, 0 0)), POLYGON ((0 0, 0.5 9, 2 2, 0 0)))"
169 );
170
171 GEOSGeom_destroy(geom2_);
172 geom2_ = GEOSDelaunayTriangulation(geom1_, 0, 1);
173 ensure_equals_wkt(geom2_,
174 "MULTILINESTRING ((8.5 1, 10 10), (8 2, 10 10), (8 2, 8.5 1), (7 8, 10 10), (7 8, 8 2), (3 8, 10 10), (3 8, 7 8), (2 2, 8.5 1), (2 2, 8 2), (2 2, 7 8), (2 2, 3 8), (0.5 9, 10 10), (0.5 9, 3 8), (0.5 9, 2 2), (0 0, 8.5 1), (0 0, 2 2), (0 0, 0.5 9))"
175 );
176 }
177
178 // Four points with a tolerance making one collapse
179 template<>
180 template<>
test()181 void object::test<6>
182 ()
183 {
184 geom1_ = GEOSGeomFromWKT("MULTIPOINT(0 0, 10 0, 10 10, 11 10)");
185
186 GEOSGeom_destroy(geom2_);
187 geom2_ = GEOSDelaunayTriangulation(geom1_, 2, 1);
188 ensure_equals_wkt(geom2_,
189 "MULTILINESTRING ((10 0, 10 10), (0 0, 10 10), (0 0, 10 0))"
190 );
191 }
192
193 } // namespace tut
194
195