1 #ifndef UNITTEST_GUNIT_GIS_TESTSHAPES_H_INCLUDED
2 #define UNITTEST_GUNIT_GIS_TESTSHAPES_H_INCLUDED
3
4 // Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
5 //
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License, version 2.0,
8 // as published by the Free Software Foundation.
9 //
10 // This program is also distributed with certain software (including
11 // but not limited to OpenSSL) that is licensed under separate terms,
12 // as designated in a particular file or component or in included license
13 // documentation. The authors of MySQL hereby grant you an additional
14 // permission to link the program and your derivative works with the
15 // separately licensed software that they have included with MySQL.
16 //
17 // This program is distributed in the hope that it will be useful,
18 // but WITHOUT ANY WARRANTY; without even the implied warranty of
19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 // GNU General Public License, version 2.0, for more details.
21 //
22 // You should have received a copy of the GNU General Public License
23 // along with this program; if not, write to the Free Software
24 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
25
26 #include <exception>
27 #include <vector>
28 #include "sql/gis/geometries.h"
29 #include "sql/gis/geometries_cs.h"
30
31 struct Cartesian_types {
32 typedef gis::Cartesian_point Point;
33 typedef gis::Cartesian_linestring Linestring;
34 typedef gis::Cartesian_linearring Linearring;
35 typedef gis::Cartesian_polygon Polygon;
36 typedef gis::Cartesian_geometrycollection Geometrycollection;
37 typedef gis::Cartesian_multipoint Multipoint;
38 typedef gis::Cartesian_multilinestring Multilinestring;
39 typedef gis::Cartesian_multipolygon Multipolygon;
40
coordinate_systemCartesian_types41 static gis::Coordinate_system coordinate_system() {
42 return gis::Coordinate_system::kCartesian;
43 }
44 };
45
46 struct Geographic_types {
47 typedef gis::Geographic_point Point;
48 typedef gis::Geographic_linestring Linestring;
49 typedef gis::Geographic_linearring Linearring;
50 typedef gis::Geographic_polygon Polygon;
51 typedef gis::Geographic_geometrycollection Geometrycollection;
52 typedef gis::Geographic_multipoint Multipoint;
53 typedef gis::Geographic_multilinestring Multilinestring;
54 typedef gis::Geographic_multipolygon Multipolygon;
55
coordinate_systemGeographic_types56 static gis::Coordinate_system coordinate_system() {
57 return gis::Coordinate_system::kGeographic;
58 }
59 };
60 template <typename T>
linearringFromVector(std::vector<double> data)61 typename T::Linearring linearringFromVector(std::vector<double> data) {
62 if (data.size() % 2 != 0) {
63 throw std::exception(); /* purecov: dead code */
64 }
65 typename T::Linearring lr;
66 for (size_t i = 0; i + 1 < data.size(); i += 2) {
67 lr.push_back(typename T::Point(data[i], data[i + 1]));
68 }
69 return lr;
70 }
71
72 template <typename T, typename U>
polygonFromVector(std::vector<double> data)73 T polygonFromVector(std::vector<double> data) {
74 T py;
75 py.push_back(linearringFromVector<U>(data));
76 return py;
77 }
78
79 template <typename T>
selfTouchingPolygon()80 typename T::Polygon selfTouchingPolygon() {
81 typename T::Polygon py;
82 py.push_back(linearringFromVector<T>(
83 {0, 0, 1, 0, 0, 0.5, 0.5, 0.25, 0.25, 0.5, 0.5, 0.5, 0, 1, 0, 0}));
84 return py;
85 }
86
87 template <typename U>
polygonWithTouchingHole()88 typename U::Polygon polygonWithTouchingHole() {
89 typename U::Polygon py;
90 py.push_back(linearringFromVector<U>({0, 0, 1, 0, 0, 1, 0, 0}));
91 py.push_back(
92 linearringFromVector<U>({0.5, 0.5, 0.5, 0.25, 0.25, 0.5, 0.5, 0.5}));
93 return py;
94 }
95 template <typename U>
polygon_reverse()96 typename U::Polygon polygon_reverse() {
97 typename U::Polygon py;
98 py.push_back(linearringFromVector<U>({0, 0, 0, 1, 1, 0, 0, 0}));
99 py.push_back(
100 linearringFromVector<U>({0.5, 0.5, 0.25, 0.5, 0.5, 0.25, 0.5, 0.5}));
101 return py;
102 }
103 template <typename U>
polygon_reverse_touching_hole()104 typename U::Polygon polygon_reverse_touching_hole() {
105 typename U::Polygon py;
106 py.push_back(linearringFromVector<U>({0, 0, 1, 0, 0, 1, 0, 0}));
107 py.push_back(
108 linearringFromVector<U>({0.5, 0.5, 0.25, 0.5, 0.5, 0.25, 0.5, 0.5}));
109 return py;
110 }
111 template <typename T>
linearring_2xsquare_around_origin()112 typename T::Linearring linearring_2xsquare_around_origin() {
113 return linearringFromVector<T>({-1, -1, 1, -1, 1, 1, -1, 1, -1, -1});
114 }
115 template <typename U>
polygon_with_touching_hole_vertice_vertice()116 typename U::Polygon polygon_with_touching_hole_vertice_vertice() {
117 typename U::Polygon py;
118 py.push_back(linearring_2xsquare_around_origin<U>());
119 py.push_back(
120 linearringFromVector<U>({-1., 0.0, 0.5, 0.25, 0.5, -0.25, -1, 0.0}));
121 return py;
122 }
123
124 template <typename T>
125 typename T::Polygon polygon_hourglass();
126
127 template <>
128 gis::Geographic_polygon polygon_hourglass<Geographic_types>() {
129 gis::Geographic_polygon py;
130 py.push_back(linearringFromVector<Geographic_types>(
131 {-0.5, 1, 0.5, 1, -0.5 + M_PI, 1, 0.5 - M_PI, 1}));
132 return py;
133 }
134 template <>
135 gis::Cartesian_polygon polygon_hourglass<Cartesian_types>() {
136 gis::Cartesian_polygon py;
137 py.push_back(linearringFromVector<Cartesian_types>(
138 {-1, -1, 1, -1, -1, 1, 1, 1, -1, -1}));
139 return py;
140 }
141
142 template <typename T>
polygonSelfTouchEdgeVertice()143 typename T::Polygon polygonSelfTouchEdgeVertice() {
144 typename T::Polygon py;
145 py.push_back(linearringFromVector<T>(
146 {0, 0, 0.2, -0.2, 0, -0.4, 0, 0.2, -0.4, -0.6, 0.6, 0, 0, 0}));
147 return py;
148 }
149
150 template <typename T>
polygonDisconnectedLimit()151 typename T::Polygon polygonDisconnectedLimit() {
152 typename T::Polygon py;
153 py.push_back(linearringFromVector<T>({0, 0, 0.2, 0, 0.2, 0.3, 0, 0.3, 0, 0}));
154 py.push_back(linearringFromVector<T>({0, 0.4, 0.4, 0.4, 0.2, 0.2, 0, 0.4}));
155 return py;
156 }
157 template <typename T>
polygon_empty_hole()158 typename T::Polygon polygon_empty_hole() {
159 typename T::Polygon py;
160 py.push_back(linearringFromVector<T>({0, 0, 1, 0, 0, 1, 0, 0}));
161 py.push_back(linearringFromVector<T>(std::vector<double>()));
162 return py;
163 }
164
165 template <typename T>
polygon_open()166 typename T::Polygon polygon_open() {
167 typename T::Polygon py;
168 py.push_back(linearringFromVector<T>({0, 0, 1, 0, 1, 0}));
169 return py;
170 }
171 template <typename T>
polygon_inner_partially_outside()172 typename T::Polygon polygon_inner_partially_outside() {
173 typename T::Polygon py;
174 py.push_back(linearringFromVector<T>({0, 0, 1, 0, 1, 0, 0, 0}));
175 py.push_back(
176 linearringFromVector<T>({0.25, 0.25, 1, .25, .25, 1, 0.25, 0.25}));
177 return py;
178 }
179 template <typename T>
polygon_inner_wholly_outside()180 typename T::Polygon polygon_inner_wholly_outside() {
181 typename T::Polygon py;
182 py.push_back(linearringFromVector<T>({0, 0, 1, 0, 1, 0, 0, 0}));
183 py.push_back(linearringFromVector<T>({1, 0.5, 0.5, 1, 1, 1, 1, 0.5}));
184 return py;
185 }
186 template <typename T>
polygon_inner_intersecting()187 typename T::Polygon polygon_inner_intersecting() {
188 typename T::Polygon py;
189 py.push_back(linearringFromVector<T>({0, 0, 1, 0, 1, 1, 1, 0, 0, 0}));
190 py.push_back(linearringFromVector<T>({.2, 0.2, 0.2, .8, .8, .2, .2, .2}));
191 py.push_back(linearringFromVector<T>({.4, 0.4, 0.4, .8, .8, .4, .4, .4}));
192 return py;
193 }
194 template <typename T>
linearring_unit_square()195 typename T::Linearring linearring_unit_square() {
196 return linearringFromVector<T>({0, 0, 1, 0, 1, 1, 0, 1, 0, 0});
197 }
198 template <typename T>
polygon_2_inner()199 typename T::Polygon polygon_2_inner() {
200 typename T::Polygon py;
201 py.push_back(linearring_unit_square<T>());
202 py.push_back(
203 linearringFromVector<T>({0.2, 0.2, 0.2, 0.8, 0.8, 0.2, 0.2, 0.2}));
204 py.push_back(
205 linearringFromVector<T>({0.8, 0.4, 0.4, 0.8, 0.8, 0.8, 0.8, 0.4}));
206 return py;
207 }
208 template <typename T>
polygon_2_inner_edge_to_edge0()209 typename T::Polygon polygon_2_inner_edge_to_edge0() {
210 typename T::Polygon py;
211 py.push_back(linearring_unit_square<T>());
212 py.push_back(
213 linearringFromVector<T>({0.2, 0.2, 0.2, 0.8, 0.8, 0.2, 0.2, 0.2}));
214 py.push_back(
215 linearringFromVector<T>({0.8, 0.2, 0.2, 0.8, 0.8, 0.8, 0.8, 0.2}));
216 return py;
217 }
218 template <typename T>
polygon_2_inner_edge_to_edge1()219 typename T::Polygon polygon_2_inner_edge_to_edge1() {
220 typename T::Polygon py;
221 py.push_back(linearring_unit_square<T>());
222 py.push_back(
223 linearringFromVector<T>({0.2, 0.2, 0.2, 0.8, 0.8, 0.2, 0.2, 0.2}));
224 py.push_back(
225 linearringFromVector<T>({0.8, 0.2, 0.4, 0.6, 0.8, 0.6, 0.8, 0.2}));
226 return py;
227 }
228 template <typename T>
polygon_2_inner_edge_to_vertice()229 typename T::Polygon polygon_2_inner_edge_to_vertice() {
230 typename T::Polygon py;
231 py.push_back(linearringFromVector<T>({-1, -1, 1, -1, 1, 1, -1, 1, -1, -1}));
232 py.push_back(
233 linearringFromVector<T>({-0.5, 0.0, 0.0, 0.5, 0.0, -0.5, -0.5, 0.0}));
234 py.push_back(
235 linearringFromVector<T>({0.0, 0.0, 0.5, 0.5, 0.5, -0.5, 0.0, 0.0}));
236 return py;
237 }
238 template <typename T>
polygon_2_inner_vertice_to_vertice()239 typename T::Polygon polygon_2_inner_vertice_to_vertice() {
240 typename T::Polygon py;
241 py.push_back(linearring_2xsquare_around_origin<T>());
242 py.push_back(
243 linearringFromVector<T>({-0.5, -0.5, -0.5, 0.5, 0.0, 0.0, -0.5, -0.5}));
244 py.push_back(
245 linearringFromVector<T>({0.0, 0.0, 0.5, 0.5, 0.5, -0.5, 0.0, 0.0}));
246 return py;
247 }
248 template <typename T>
polygon_1_1_bug26476445()249 typename T::Polygon polygon_1_1_bug26476445() {
250 typename T::Polygon py;
251 py.push_back(linearringFromVector<T>(
252 {0.15707963267948966, 0.19198621771937624, 2.4958208303518914,
253 0.9250245035569946, 0.24434609527920614, 0.6632251157578452,
254 0.15707963267948966, 0.19198621771937624}));
255 return py;
256 }
257 template <typename T>
polygon_1_2_bug26476445()258 typename T::Polygon polygon_1_2_bug26476445() {
259 typename T::Polygon py;
260 py.push_back(linearringFromVector<T>(
261 {-2.5132741228718345, -1.0122909661567112, -0.06981317007977318,
262 -1.2217304763960306, -2.478367537831948, -0.10471975511965977,
263 -2.5132741228718345, -1.0122909661567112}));
264 return py;
265 }
266 template <typename T>
multipolygon_1_bug26476445()267 typename T::Multipolygon multipolygon_1_bug26476445() {
268 typename T::Multipolygon mpy;
269 mpy.push_back(polygon_1_1_bug26476445<T>());
270 mpy.push_back(polygon_1_2_bug26476445<T>());
271 return mpy;
272 }
273
274 template <typename T>
polygon_2_1_bug26476445()275 typename T::Polygon polygon_2_1_bug26476445() {
276 typename T::Polygon py;
277 py.push_back(linearringFromVector<T>(
278 {0.15707963267948966, 0.19198621771937624, 0.7504915783575616,
279 0.9424777960769379, 0.24434609527920614, 1.4660765716752369,
280 0.15707963267948966, 0.19198621771937624}));
281 return py;
282 }
283 template <typename T>
polygon_2_2_bug26476445()284 typename T::Polygon polygon_2_2_bug26476445() {
285 typename T::Polygon py;
286 py.push_back(linearringFromVector<T>(
287 {-2.5132741228718345, -1.0122909661567112, -0.06981317007977318,
288 -1.2217304763960306, -2.478367537831948, -0.10471975511965977,
289 -2.5132741228718345, -1.0122909661567112}));
290 return py;
291 }
292 template <typename T>
multipolygon_2_bug26476445()293 typename T::Multipolygon multipolygon_2_bug26476445() {
294 typename T::Multipolygon mpy;
295 mpy.push_back(polygon_2_1_bug26476445<T>());
296 mpy.push_back(polygon_2_2_bug26476445<T>());
297 return mpy;
298 }
299
300 template <typename T>
linestringFromVector(std::vector<double> data)301 typename T::Linestring linestringFromVector(std::vector<double> data) {
302 if (data.size() % 2 != 0) {
303 throw std::exception();
304 }
305 typename T::Linearring ls;
306 for (size_t i = 0; i + 1 < data.size(); i += 2) {
307 ls.push_back(typename T::Point(data[i], data[i + 1]));
308 }
309 return ls;
310 }
311
312 template <typename T>
linestring_3pt_normal()313 typename T::Linestring linestring_3pt_normal() {
314 return linestringFromVector<T>({0.0, 0.0, 0.56, 0.99, -.66, 2.0});
315 }
316
317 template <typename T>
linestring_ring()318 typename T::Linestring linestring_ring() {
319 return linestringFromVector<T>({0.0, 0.0, 0.56, 0.99, 0.0, 2.0, 0.0, 0.0});
320 }
321
322 template <typename T>
linestring_selfcrossing()323 typename T::Linestring linestring_selfcrossing() {
324 return linestringFromVector<T>({0.0, 0.0, 1.0, 0.0, 0.1, 1.0, 0.0, -2.0});
325 }
326
327 #endif // UNITTEST_GUNIT_GIS_TESTSHAPES_H_INCLUDED
328