1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the test suite of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21 ** included in the packaging of this file. Please review the following
22 ** information to ensure the GNU General Public License requirements will
23 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24 **
25 ** $QT_END_LICENSE$
26 **
27 ****************************************************************************/
28
29 #include <QtTest/QtTest>
30 #include <QtPositioning/QGeoCoordinate>
31 #include <QtPositioning/QGeoRectangle>
32 #include <QtPositioning/QGeoPolygon>
33
34 QT_USE_NAMESPACE
35
36 class tst_QGeoPolygon : public QObject
37 {
38 Q_OBJECT
39
40 private slots:
41 void defaultConstructor();
42 void listConstructor();
43 void assignment();
44
45 void comparison();
46 void type();
47
48 void path();
49 void size();
50
51 void translate_data();
52 void translate();
53
54 void valid_data();
55 void valid();
56
57 void contains_data();
58 void contains();
59
60 void boundingGeoRectangle_data();
61 void boundingGeoRectangle();
62
63 void extendShape();
64 void extendShape_data();
65 };
66
defaultConstructor()67 void tst_QGeoPolygon::defaultConstructor()
68 {
69 QGeoPolygon p;
70 QVERIFY(!p.path().size());
71 QVERIFY(!p.size());
72 QVERIFY(!p.isValid());
73 QVERIFY(p.isEmpty());
74 }
75
listConstructor()76 void tst_QGeoPolygon::listConstructor()
77 {
78 QList<QGeoCoordinate> coords;
79 coords.append(QGeoCoordinate(1,1));
80 coords.append(QGeoCoordinate(2,2));
81 QGeoPolygon p2(coords);
82 QCOMPARE(p2.path().size(), 2);
83 QCOMPARE(p2.size(), 2);
84 QVERIFY(!p2.isValid()); // a polygon can't have only 2 coords
85 QVERIFY(!p2.isEmpty());
86
87 coords.append(QGeoCoordinate(3,0));
88
89 QGeoPolygon p(coords);
90 QCOMPARE(p.path().size(), 3);
91 QCOMPARE(p.size(), 3);
92 QVERIFY(p.isValid());
93 QVERIFY(!p.isEmpty());
94
95
96 for (const QGeoCoordinate &c : coords) {
97 QCOMPARE(p.path().contains(c), true);
98 QCOMPARE(p.containsCoordinate(c), true);
99 }
100 }
101
assignment()102 void tst_QGeoPolygon::assignment()
103 {
104 QGeoPolygon p1;
105 QList<QGeoCoordinate> coords;
106 coords.append(QGeoCoordinate(1,1));
107 coords.append(QGeoCoordinate(2,2));
108 coords.append(QGeoCoordinate(3,0));
109 QGeoPolygon p2(coords);
110
111 QVERIFY(p1 != p2);
112
113 p1 = p2;
114 QCOMPARE(p1.path(), coords);
115 QCOMPARE(p1, p2);
116
117 // Assign c1 to an area
118 QGeoShape area = p1;
119 QCOMPARE(area.type(), p1.type());
120 QVERIFY(area == p1);
121
122 // Assign the area back to a polygon
123 QGeoPolygon p3 = area;
124 QCOMPARE(p3.path(), coords);
125 QVERIFY(p3 == p1);
126
127 // Check that the copy is not modified when modifying the original.
128 p1.addCoordinate(QGeoCoordinate(4,0));
129 QVERIFY(p3 != p1);
130 }
131
comparison()132 void tst_QGeoPolygon::comparison()
133 {
134 QList<QGeoCoordinate> coords;
135 coords.append(QGeoCoordinate(1,1));
136 coords.append(QGeoCoordinate(2,2));
137 coords.append(QGeoCoordinate(3,0));
138 QList<QGeoCoordinate> coords2;
139 coords2.append(QGeoCoordinate(3,1));
140 coords2.append(QGeoCoordinate(4,2));
141 coords2.append(QGeoCoordinate(3,0));
142 QGeoPolygon c1(coords);
143 QGeoPolygon c2(coords);
144 QGeoPolygon c3(coords2);
145
146 QVERIFY(c1 == c2);
147 QVERIFY(!(c1 != c2));
148
149 QVERIFY(!(c1 == c3));
150 QVERIFY(c1 != c3);
151
152 QVERIFY(!(c2 == c3));
153 QVERIFY(c2 != c3);
154
155 QGeoRectangle b1(QGeoCoordinate(20,20),QGeoCoordinate(10,30));
156 QVERIFY(!(c1 == b1));
157 QVERIFY(c1 != b1);
158
159 QGeoShape *c2Ptr = &c2;
160 QVERIFY(c1 == *c2Ptr);
161 QVERIFY(!(c1 != *c2Ptr));
162
163 QGeoShape *c3Ptr = &c3;
164 QVERIFY(!(c1 == *c3Ptr));
165 QVERIFY(c1 != *c3Ptr);
166 }
167
type()168 void tst_QGeoPolygon::type()
169 {
170 QGeoPolygon c;
171 QCOMPARE(c.type(), QGeoShape::PolygonType);
172 }
173
path()174 void tst_QGeoPolygon::path()
175 {
176 QList<QGeoCoordinate> coords;
177 coords.append(QGeoCoordinate(1,1));
178 coords.append(QGeoCoordinate(2,2));
179 coords.append(QGeoCoordinate(3,0));
180
181 QGeoPolygon p;
182 p.setPath(coords);
183 QCOMPARE(p.path().size(), 3);
184 QCOMPARE(p.size(), 3);
185
186 for (const QGeoCoordinate &c : coords) {
187 QCOMPARE(p.path().contains(c), true);
188 QCOMPARE(p.containsCoordinate(c), true);
189 }
190 }
191
size()192 void tst_QGeoPolygon::size()
193 {
194 QList<QGeoCoordinate> coords;
195
196 QGeoPolygon p1(coords);
197 QCOMPARE(p1.size(), coords.size());
198
199 coords.append(QGeoCoordinate(1,1));
200 QGeoPolygon p2(coords);
201 QCOMPARE(p2.size(), coords.size());
202
203 coords.append(QGeoCoordinate(2,2));
204 QGeoPolygon p3(coords);
205 QCOMPARE(p3.size(), coords.size());
206
207 coords.append(QGeoCoordinate(3,0));
208 QGeoPolygon p4(coords);
209 QCOMPARE(p4.size(), coords.size());
210
211 p4.removeCoordinate(2);
212 QCOMPARE(p4.size(), coords.size() - 1);
213
214 p4.removeCoordinate(coords.first());
215 QCOMPARE(p4.size(), coords.size() - 2);
216 }
217
translate_data()218 void tst_QGeoPolygon::translate_data()
219 {
220 QTest::addColumn<QGeoCoordinate>("c1");
221 QTest::addColumn<QGeoCoordinate>("c2");
222 QTest::addColumn<QGeoCoordinate>("c3");
223 QTest::addColumn<double>("lat");
224 QTest::addColumn<double>("lon");
225
226 QTest::newRow("Simple") << QGeoCoordinate(1,1) << QGeoCoordinate(2,2) <<
227 QGeoCoordinate(3,0) << 5.0 << 4.0;
228 QTest::newRow("Backward") << QGeoCoordinate(1,1) << QGeoCoordinate(2,2) <<
229 QGeoCoordinate(3,0) << -5.0 << -4.0;
230 }
231
translate()232 void tst_QGeoPolygon::translate()
233 {
234 QFETCH(QGeoCoordinate, c1);
235 QFETCH(QGeoCoordinate, c2);
236 QFETCH(QGeoCoordinate, c3);
237 QFETCH(double, lat);
238 QFETCH(double, lon);
239
240 QList<QGeoCoordinate> coords;
241 coords.append(c1);
242 coords.append(c2);
243 coords.append(c3);
244 QGeoPolygon p(coords);
245
246 p.translate(lat, lon);
247
248 for (int i = 0; i < p.path().size(); i++) {
249 QCOMPARE(coords[i].latitude(), p.path()[i].latitude() - lat );
250 QCOMPARE(coords[i].longitude(), p.path()[i].longitude() - lon );
251 }
252 }
253
valid_data()254 void tst_QGeoPolygon::valid_data()
255 {
256 QTest::addColumn<QGeoCoordinate>("c1");
257 QTest::addColumn<QGeoCoordinate>("c2");
258 QTest::addColumn<QGeoCoordinate>("c3");
259 QTest::addColumn<bool>("valid");
260
261 QTest::newRow("empty coords") << QGeoCoordinate() << QGeoCoordinate() << QGeoCoordinate() << false;
262 QTest::newRow("invalid coord") << QGeoCoordinate(50, 50) << QGeoCoordinate(60, 60) << QGeoCoordinate(700, 700) << false;
263 QTest::newRow("good") << QGeoCoordinate(10, 10) << QGeoCoordinate(11, 11) << QGeoCoordinate(10, 12) << true;
264 }
265
valid()266 void tst_QGeoPolygon::valid()
267 {
268 QFETCH(QGeoCoordinate, c1);
269 QFETCH(QGeoCoordinate, c2);
270 QFETCH(QGeoCoordinate, c3);
271 QFETCH(bool, valid);
272
273 QList<QGeoCoordinate> coords;
274 coords.append(c1);
275 coords.append(c2);
276 coords.append(c3);
277 QGeoPolygon p(coords);
278
279 QCOMPARE(p.isValid(), valid);
280
281 QGeoShape area = p;
282 QCOMPARE(area.isValid(), valid);
283 }
284
contains_data()285 void tst_QGeoPolygon::contains_data()
286 {
287 QTest::addColumn<QGeoCoordinate>("c1");
288 QTest::addColumn<QGeoCoordinate>("c2");
289 QTest::addColumn<QGeoCoordinate>("c3");
290 QTest::addColumn<QGeoCoordinate>("probe");
291 QTest::addColumn<bool>("result");
292
293 QList<QGeoCoordinate> c;
294 c.append(QGeoCoordinate(1,1));
295 c.append(QGeoCoordinate(2,2));
296 c.append(QGeoCoordinate(3,0));
297
298 QTest::newRow("One of the points") << c[0] << c[1] << c[2] << QGeoCoordinate(2, 2) << true;
299 QTest::newRow("Not so far away") << c[0] << c[1] << c[2] << QGeoCoordinate(0.8, 0.8) << false;
300 QTest::newRow("Not so far away and large line") << c[0] << c[1] << c[2] << QGeoCoordinate(0.8, 0.8) << false;
301 QTest::newRow("Inside") << c[0] << c[1] << c[2] << QGeoCoordinate(2.0, 1.0) << true;
302 }
303
contains()304 void tst_QGeoPolygon::contains()
305 {
306 QFETCH(QGeoCoordinate, c1);
307 QFETCH(QGeoCoordinate, c2);
308 QFETCH(QGeoCoordinate, c3);
309 QFETCH(QGeoCoordinate, probe);
310 QFETCH(bool, result);
311
312 QList<QGeoCoordinate> coords;
313 coords.append(c1);
314 coords.append(c2);
315 coords.append(c3);
316 QGeoPolygon p(coords);
317
318 QCOMPARE(p.contains(probe), result);
319
320 QGeoShape area = p;
321 QCOMPARE(area.contains(probe), result);
322 }
323
boundingGeoRectangle_data()324 void tst_QGeoPolygon::boundingGeoRectangle_data()
325 {
326 QTest::addColumn<QGeoCoordinate>("c1");
327 QTest::addColumn<QGeoCoordinate>("c2");
328 QTest::addColumn<QGeoCoordinate>("c3");
329 QTest::addColumn<QGeoCoordinate>("probe");
330 QTest::addColumn<bool>("result");
331
332 QList<QGeoCoordinate> c;
333 c.append(QGeoCoordinate(1,1));
334 c.append(QGeoCoordinate(2,2));
335 c.append(QGeoCoordinate(3,0));
336
337 QTest::newRow("One of the points") << c[0] << c[1] << c[2] << QGeoCoordinate(2, 2) << true;
338 QTest::newRow("Not so far away") << c[0] << c[1] << c[2] << QGeoCoordinate(0, 0) << false;
339 QTest::newRow("Inside the bounds") << c[0] << c[1] << c[2] << QGeoCoordinate(1, 0) << true;
340 QTest::newRow("Inside the bounds") << c[0] << c[1] << c[2] << QGeoCoordinate(1.1, 0.1) << true;
341 }
342
boundingGeoRectangle()343 void tst_QGeoPolygon::boundingGeoRectangle()
344 {
345 QFETCH(QGeoCoordinate, c1);
346 QFETCH(QGeoCoordinate, c2);
347 QFETCH(QGeoCoordinate, c3);
348 QFETCH(QGeoCoordinate, probe);
349 QFETCH(bool, result);
350
351 QList<QGeoCoordinate> coords;
352 coords.append(c1);
353 coords.append(c2);
354 coords.append(c3);
355 QGeoPolygon p(coords);
356
357 QGeoRectangle box = p.boundingGeoRectangle();
358 QCOMPARE(box.contains(probe), result);
359 }
360
extendShape()361 void tst_QGeoPolygon::extendShape()
362 {
363 QFETCH(QGeoCoordinate, c1);
364 QFETCH(QGeoCoordinate, c2);
365 QFETCH(QGeoCoordinate, c3);
366 QFETCH(QGeoCoordinate, probe);
367 QFETCH(bool, before);
368 QFETCH(bool, after);
369
370 QList<QGeoCoordinate> coords;
371 coords.append(c1);
372 coords.append(c2);
373 coords.append(c3);
374 QGeoPolygon p(coords);
375
376
377 QCOMPARE(p.contains(probe), before);
378 p.extendShape(probe);
379 QCOMPARE(p.contains(probe), after);
380 }
381
extendShape_data()382 void tst_QGeoPolygon::extendShape_data()
383 {
384 QTest::addColumn<QGeoCoordinate>("c1");
385 QTest::addColumn<QGeoCoordinate>("c2");
386 QTest::addColumn<QGeoCoordinate>("c3");
387 QTest::addColumn<QGeoCoordinate>("probe");
388 QTest::addColumn<bool>("before");
389 QTest::addColumn<bool>("after");
390
391 QList<QGeoCoordinate> c;
392 c.append(QGeoCoordinate(1,1));
393 c.append(QGeoCoordinate(2,2));
394 c.append(QGeoCoordinate(3,0));
395
396 QTest::newRow("One of the points") << c[0] << c[1] << c[2] << QGeoCoordinate(2, 2) << true << true;
397 QTest::newRow("Not so far away") << c[0] << c[1] << c[2] << QGeoCoordinate(0, 0) << false << true;
398 QTest::newRow("Contained point") << c[0] << c[1] << c[2] << QGeoCoordinate(2.0, 1.0) << true << true;
399 }
400
401 QTEST_MAIN(tst_QGeoPolygon)
402 #include "tst_qgeopolygon.moc"
403