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/QGeoPath>
33
34QT_USE_NAMESPACE
35
36class tst_QGeoPath : public QObject
37{
38 Q_OBJECT
39
40private slots:
41 void defaultConstructor();
42 void listConstructor();
43 void assignment();
44
45 void comparison();
46 void type();
47
48 void path();
49 void width();
50 void size();
51
52 void translate_data();
53 void translate();
54
55 void valid_data();
56 void valid();
57
58 void contains_data();
59 void contains();
60
61 void boundingGeoRectangle_data();
62 void boundingGeoRectangle();
63
64 void extendShape();
65 void extendShape_data();
66};
67
68void tst_QGeoPath::defaultConstructor()
69{
70 QGeoPath p;
71 QVERIFY(!p.path().size());
72 QCOMPARE(p.width(), qreal(0.0));
73 QCOMPARE(p.length(), double(0.0));
74}
75
76void tst_QGeoPath::listConstructor()
77{
78 QList<QGeoCoordinate> coords;
79 coords.append(t: QGeoCoordinate(1,1));
80 coords.append(t: QGeoCoordinate(2,2));
81 coords.append(t: QGeoCoordinate(3,0));
82
83 QGeoPath p(coords, 1.0);
84 QCOMPARE(p.width(), qreal(1.0));
85 QCOMPARE(p.path().size(), 3);
86
87 for (const QGeoCoordinate &c : coords) {
88 QCOMPARE(p.path().contains(c), true);
89 }
90}
91
92void tst_QGeoPath::assignment()
93{
94 QGeoPath p1;
95 QList<QGeoCoordinate> coords;
96 coords.append(t: QGeoCoordinate(1,1));
97 coords.append(t: QGeoCoordinate(2,2));
98 coords.append(t: QGeoCoordinate(3,0));
99 QGeoPath p2(coords, 1.0);
100
101 QVERIFY(p1 != p2);
102
103 p1 = p2;
104 QCOMPARE(p1.path(), coords);
105 QCOMPARE(p1.width(), 1.0);
106 QCOMPARE(p1, p2);
107
108 // Assign c1 to an area
109 QGeoShape area = p1;
110 QCOMPARE(area.type(), p1.type());
111 QVERIFY(area == p1);
112
113 // Assign the area back to a bounding circle
114 QGeoPath p3 = area;
115 QCOMPARE(p3.path(), coords);
116 QCOMPARE(p3.width(), 1.0);
117
118 // Check that the copy is not modified when modifying the original.
119 p1.setWidth(2.0);
120 QVERIFY(p3.width() != p1.width());
121 QVERIFY(p3 != p1);
122}
123
124void tst_QGeoPath::comparison()
125{
126 QList<QGeoCoordinate> coords;
127 coords.append(t: QGeoCoordinate(1,1));
128 coords.append(t: QGeoCoordinate(2,2));
129 coords.append(t: QGeoCoordinate(3,0));
130 QList<QGeoCoordinate> coords2;
131 coords2.append(t: QGeoCoordinate(3,1));
132 coords2.append(t: QGeoCoordinate(4,2));
133 coords2.append(t: QGeoCoordinate(3,0));
134 QGeoPath c1(coords, qreal(50.0));
135 QGeoPath c2(coords, qreal(50.0));
136 QGeoPath c3(coords, qreal(35.0));
137 QGeoPath c4(coords2, qreal(50.0));
138
139 QVERIFY(c1 == c2);
140 QVERIFY(!(c1 != c2));
141
142 QVERIFY(!(c1 == c3));
143 QVERIFY(c1 != c3);
144
145 QVERIFY(!(c1 == c4));
146 QVERIFY(c1 != c4);
147
148 QVERIFY(!(c2 == c3));
149 QVERIFY(c2 != c3);
150
151 QGeoRectangle b1(QGeoCoordinate(20,20),QGeoCoordinate(10,30));
152 QVERIFY(!(c1 == b1));
153 QVERIFY(c1 != b1);
154
155 QGeoShape *c2Ptr = &c2;
156 QVERIFY(c1 == *c2Ptr);
157 QVERIFY(!(c1 != *c2Ptr));
158
159 QGeoShape *c3Ptr = &c3;
160 QVERIFY(!(c1 == *c3Ptr));
161 QVERIFY(c1 != *c3Ptr);
162}
163
164void tst_QGeoPath::type()
165{
166 QGeoPath c;
167 QCOMPARE(c.type(), QGeoShape::PathType);
168}
169
170void tst_QGeoPath::path()
171{
172 QList<QGeoCoordinate> coords;
173 coords.append(t: QGeoCoordinate(1,1));
174 coords.append(t: QGeoCoordinate(2,2));
175 coords.append(t: QGeoCoordinate(3,0));
176
177 QGeoPath p;
178 p.setPath(coords);
179 QCOMPARE(p.path().size(), 3);
180
181 for (const QGeoCoordinate &c : coords) {
182 QCOMPARE(p.path().contains(c), true);
183 }
184
185 p.clearPath();
186 QCOMPARE(p.path().size(), 0);
187 QVERIFY(p.boundingGeoRectangle().isEmpty());
188}
189
190void tst_QGeoPath::width()
191{
192 QGeoPath p;
193 p.setWidth(10.0);
194 QCOMPARE(p.width(), qreal(10.0));
195}
196
197void tst_QGeoPath::size()
198{
199 QList<QGeoCoordinate> coords;
200
201 QGeoPath p1(coords, 3);
202 QCOMPARE(p1.size(), coords.size());
203
204 coords.append(t: QGeoCoordinate(1,1));
205 QGeoPath p2(coords, 3);
206 QCOMPARE(p2.size(), coords.size());
207
208 coords.append(t: QGeoCoordinate(2,2));
209 QGeoPath p3(coords, 3);
210 QCOMPARE(p3.size(), coords.size());
211
212 coords.append(t: QGeoCoordinate(3,0));
213 QGeoPath p4(coords, 3);
214 QCOMPARE(p4.size(), coords.size());
215
216 p4.removeCoordinate(index: 2);
217 QCOMPARE(p4.size(), coords.size() - 1);
218
219 p4.removeCoordinate(coordinate: coords.first());
220 QCOMPARE(p4.size(), coords.size() - 2);
221}
222
223void tst_QGeoPath::translate_data()
224{
225 QTest::addColumn<QGeoCoordinate>(name: "c1");
226 QTest::addColumn<QGeoCoordinate>(name: "c2");
227 QTest::addColumn<QGeoCoordinate>(name: "c3");
228 QTest::addColumn<double>(name: "lat");
229 QTest::addColumn<double>(name: "lon");
230
231 QTest::newRow(dataTag: "Simple") << QGeoCoordinate(1,1) << QGeoCoordinate(2,2) <<
232 QGeoCoordinate(3,0) << 5.0 << 4.0;
233 QTest::newRow(dataTag: "Backward") << QGeoCoordinate(1,1) << QGeoCoordinate(2,2) <<
234 QGeoCoordinate(3,0) << -5.0 << -4.0;
235}
236
237void tst_QGeoPath::translate()
238{
239 QFETCH(QGeoCoordinate, c1);
240 QFETCH(QGeoCoordinate, c2);
241 QFETCH(QGeoCoordinate, c3);
242 QFETCH(double, lat);
243 QFETCH(double, lon);
244
245 QList<QGeoCoordinate> coords;
246 coords.append(t: c1);
247 coords.append(t: c2);
248 coords.append(t: c3);
249 QGeoPath p(coords);
250
251 p.translate(degreesLatitude: lat, degreesLongitude: lon);
252
253 for (int i = 0; i < p.path().size(); i++) {
254 QCOMPARE(coords[i].latitude(), p.path()[i].latitude() - lat );
255 QCOMPARE(coords[i].longitude(), p.path()[i].longitude() - lon );
256 }
257}
258
259void tst_QGeoPath::valid_data()
260{
261 QTest::addColumn<QGeoCoordinate>(name: "c1");
262 QTest::addColumn<QGeoCoordinate>(name: "c2");
263 QTest::addColumn<QGeoCoordinate>(name: "c3");
264 QTest::addColumn<qreal>(name: "width");
265 QTest::addColumn<bool>(name: "valid");
266
267 QTest::newRow(dataTag: "empty coords") << QGeoCoordinate() << QGeoCoordinate() << QGeoCoordinate() << qreal(5.0) << false;
268 QTest::newRow(dataTag: "invalid coord") << QGeoCoordinate(50, 50) << QGeoCoordinate(60, 60) << QGeoCoordinate(700, 700) << qreal(5.0) << false;
269 QTest::newRow(dataTag: "bad width") << QGeoCoordinate(10, 10) << QGeoCoordinate(11, 11) << QGeoCoordinate(10, 12) << qreal(-5.0) << true;
270 QTest::newRow(dataTag: "NaN width") << QGeoCoordinate(10, 10) << QGeoCoordinate(11, 11) << QGeoCoordinate(10, 12) << qreal(qQNaN()) << true;
271 QTest::newRow(dataTag: "zero width") << QGeoCoordinate(10, 10) << QGeoCoordinate(11, 11) << QGeoCoordinate(10, 12) << qreal(0) << true;
272 QTest::newRow(dataTag: "good") << QGeoCoordinate(10, 10) << QGeoCoordinate(11, 11) << QGeoCoordinate(10, 12) << qreal(5) << true;
273}
274
275void tst_QGeoPath::valid()
276{
277 QFETCH(QGeoCoordinate, c1);
278 QFETCH(QGeoCoordinate, c2);
279 QFETCH(QGeoCoordinate, c3);
280 QFETCH(qreal, width);
281 QFETCH(bool, valid);
282
283 QList<QGeoCoordinate> coords;
284 coords.append(t: c1);
285 coords.append(t: c2);
286 coords.append(t: c3);
287 QGeoPath p(coords, width);
288
289 QCOMPARE(p.isValid(), valid);
290
291 QGeoShape area = p;
292 QCOMPARE(area.isValid(), valid);
293}
294
295void tst_QGeoPath::contains_data()
296{
297 QTest::addColumn<QGeoCoordinate>(name: "c1");
298 QTest::addColumn<QGeoCoordinate>(name: "c2");
299 QTest::addColumn<QGeoCoordinate>(name: "c3");
300 QTest::addColumn<qreal>(name: "width");
301 QTest::addColumn<QGeoCoordinate>(name: "probe");
302 QTest::addColumn<bool>(name: "result");
303
304 QList<QGeoCoordinate> c;
305 c.append(t: QGeoCoordinate(1,1));
306 c.append(t: QGeoCoordinate(2,2));
307 c.append(t: QGeoCoordinate(3,0));
308
309 QTest::newRow(dataTag: "One of the points") << c[0] << c[1] << c[2] << 0.0 << QGeoCoordinate(2, 2) << true;
310 QTest::newRow(dataTag: "Not so far away") << c[0] << c[1] << c[2] << 0.0 << QGeoCoordinate(0.8, 0.8) << false;
311 QTest::newRow(dataTag: "Not so far away and large line") << c[0] << c[1] << c[2] << 100000.0 << QGeoCoordinate(0.8, 0.8) << true;
312}
313
314void tst_QGeoPath::contains()
315{
316 QFETCH(QGeoCoordinate, c1);
317 QFETCH(QGeoCoordinate, c2);
318 QFETCH(QGeoCoordinate, c3);
319 QFETCH(qreal, width);
320 QFETCH(QGeoCoordinate, probe);
321 QFETCH(bool, result);
322
323 QList<QGeoCoordinate> coords;
324 coords.append(t: c1);
325 coords.append(t: c2);
326 coords.append(t: c3);
327 QGeoPath p(coords, width);
328
329 QCOMPARE(p.contains(probe), result);
330
331 QGeoShape area = p;
332 QCOMPARE(area.contains(probe), result);
333}
334
335void tst_QGeoPath::boundingGeoRectangle_data()
336{
337 QTest::addColumn<QGeoCoordinate>(name: "c1");
338 QTest::addColumn<QGeoCoordinate>(name: "c2");
339 QTest::addColumn<QGeoCoordinate>(name: "c3");
340 QTest::addColumn<qreal>(name: "width");
341 QTest::addColumn<QGeoCoordinate>(name: "probe");
342 QTest::addColumn<bool>(name: "result");
343
344 QList<QGeoCoordinate> c;
345 c.append(t: QGeoCoordinate(1,1));
346 c.append(t: QGeoCoordinate(2,2));
347 c.append(t: QGeoCoordinate(3,0));
348
349 QTest::newRow(dataTag: "One of the points") << c[0] << c[1] << c[2] << 0.0 << QGeoCoordinate(2, 2) << true;
350 QTest::newRow(dataTag: "Not so far away") << c[0] << c[1] << c[2] << 0.0 << QGeoCoordinate(0, 0) << false;
351 QTest::newRow(dataTag: "Inside the bounds") << c[0] << c[1] << c[2] << 100.0 << QGeoCoordinate(1, 0) << true;
352 QTest::newRow(dataTag: "Inside the bounds") << c[0] << c[1] << c[2] << 100.0 << QGeoCoordinate(1.1, 0.1) << true;
353}
354
355void tst_QGeoPath::boundingGeoRectangle()
356{
357 QFETCH(QGeoCoordinate, c1);
358 QFETCH(QGeoCoordinate, c2);
359 QFETCH(QGeoCoordinate, c3);
360 QFETCH(qreal, width);
361 QFETCH(QGeoCoordinate, probe);
362 QFETCH(bool, result);
363
364 QList<QGeoCoordinate> coords;
365 coords.append(t: c1);
366 coords.append(t: c2);
367 coords.append(t: c3);
368 QGeoPath p(coords, width);
369
370 QGeoRectangle box = p.boundingGeoRectangle();
371 QCOMPARE(box.contains(probe), result);
372}
373
374void tst_QGeoPath::extendShape()
375{
376 QFETCH(QGeoCoordinate, c1);
377 QFETCH(QGeoCoordinate, c2);
378 QFETCH(QGeoCoordinate, c3);
379 QFETCH(qreal, width);
380 QFETCH(QGeoCoordinate, probe);
381 QFETCH(bool, before);
382 QFETCH(bool, after);
383
384 QList<QGeoCoordinate> coords;
385 coords.append(t: c1);
386 coords.append(t: c2);
387 coords.append(t: c3);
388 QGeoPath p(coords, width);
389
390
391 QCOMPARE(p.contains(probe), before);
392 p.extendShape(coordinate: probe);
393 QCOMPARE(p.contains(probe), after);
394}
395
396void tst_QGeoPath::extendShape_data()
397{
398 QTest::addColumn<QGeoCoordinate>(name: "c1");
399 QTest::addColumn<QGeoCoordinate>(name: "c2");
400 QTest::addColumn<QGeoCoordinate>(name: "c3");
401 QTest::addColumn<qreal>(name: "width");
402 QTest::addColumn<QGeoCoordinate>(name: "probe");
403 QTest::addColumn<bool>(name: "before");
404 QTest::addColumn<bool>(name: "after");
405
406 QList<QGeoCoordinate> c;
407 c.append(t: QGeoCoordinate(1,1));
408 c.append(t: QGeoCoordinate(2,2));
409 c.append(t: QGeoCoordinate(3,0));
410
411 QTest::newRow(dataTag: "One of the points") << c[0] << c[1] << c[2] << 0.0 << QGeoCoordinate(2, 2) << true << true;
412 QTest::newRow(dataTag: "Not so far away") << c[0] << c[1] << c[2] << 0.0 << QGeoCoordinate(0, 0) << false << true;
413 QTest::newRow(dataTag: "Not so far away and large line") << c[0] << c[1] << c[2] << 100000.0 << QGeoCoordinate(0.8, 0.8) << true << true;
414}
415
416QTEST_MAIN(tst_QGeoPath)
417#include "tst_qgeopath.moc"
418

source code of qtlocation/tests/auto/qgeopath/tst_qgeopath.cpp