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