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/QGeoCircle> |
32 | #include <QtPositioning/QGeoRectangle> |
33 | |
34 | QT_USE_NAMESPACE |
35 | |
36 | class tst_QGeoCircle : public QObject |
37 | { |
38 | Q_OBJECT |
39 | |
40 | private slots: |
41 | void defaultConstructor(); |
42 | void centerRadiusConstructor(); |
43 | void assignment(); |
44 | |
45 | void comparison(); |
46 | void type(); |
47 | |
48 | void radius(); |
49 | void center(); |
50 | |
51 | void translate_data(); |
52 | void translate(); |
53 | |
54 | void valid_data(); |
55 | void valid(); |
56 | |
57 | void empty_data(); |
58 | void empty(); |
59 | |
60 | void contains_data(); |
61 | void contains(); |
62 | |
63 | void boundingGeoRectangle_data(); |
64 | void boundingGeoRectangle(); |
65 | |
66 | void extendCircle(); |
67 | void extendCircle_data(); |
68 | |
69 | void areaComparison(); |
70 | void areaComparison_data(); |
71 | |
72 | void boxComparison(); |
73 | void boxComparison_data(); |
74 | }; |
75 | |
76 | void tst_QGeoCircle::defaultConstructor() |
77 | { |
78 | QGeoCircle c; |
79 | QVERIFY(!c.center().isValid()); |
80 | QCOMPARE(c.radius(), qreal(-1.0)); |
81 | } |
82 | |
83 | void tst_QGeoCircle::centerRadiusConstructor() |
84 | { |
85 | QGeoCircle c(QGeoCoordinate(1,1), qreal(50.0)); |
86 | QCOMPARE(c.center(), QGeoCoordinate(1,1)); |
87 | QCOMPARE(c.radius(), qreal(50.0)); |
88 | } |
89 | |
90 | void tst_QGeoCircle::assignment() |
91 | { |
92 | QGeoCircle c1 = QGeoCircle(QGeoCoordinate(10.0, 0.0), 20.0); |
93 | QGeoCircle c2 = QGeoCircle(QGeoCoordinate(20.0, 0.0), 30.0); |
94 | |
95 | QVERIFY(c1 != c2); |
96 | |
97 | c2 = c1; |
98 | QCOMPARE(c2.center(), QGeoCoordinate(10.0, 0.0)); |
99 | QCOMPARE(c2.radius(), 20.0); |
100 | QCOMPARE(c1, c2); |
101 | |
102 | c2.setCenter(QGeoCoordinate(30.0, 0.0)); |
103 | c2.setRadius(15.0); |
104 | QCOMPARE(c1.center(), QGeoCoordinate(10.0, 0.0)); |
105 | QCOMPARE(c1.radius(), 20.0); |
106 | |
107 | // Assign c1 to an area |
108 | QGeoShape area = c1; |
109 | QCOMPARE(area.type(), c1.type()); |
110 | QVERIFY(area == c1); |
111 | |
112 | // Assign the area back to a bounding circle |
113 | QGeoCircle ca = area; |
114 | QCOMPARE(ca.center(), c1.center()); |
115 | QCOMPARE(ca.radius(), c1.radius()); |
116 | |
117 | // Check that the copy is not modified when modifying the original. |
118 | c1.setCenter(QGeoCoordinate(15.0, 15.0)); |
119 | QVERIFY(ca.center() != c1.center()); |
120 | QVERIFY(ca != c1); |
121 | } |
122 | |
123 | void tst_QGeoCircle::comparison() |
124 | { |
125 | QGeoCircle c1(QGeoCoordinate(1,1), qreal(50.0)); |
126 | QGeoCircle c2(QGeoCoordinate(1,1), qreal(50.0)); |
127 | QGeoCircle c3(QGeoCoordinate(1,1), qreal(35.0)); |
128 | QGeoCircle c4(QGeoCoordinate(1,2), qreal(50.0)); |
129 | |
130 | QVERIFY(c1 == c2); |
131 | QVERIFY(!(c1 != c2)); |
132 | |
133 | QVERIFY(!(c1 == c3)); |
134 | QVERIFY(c1 != c3); |
135 | |
136 | QVERIFY(!(c1 == c4)); |
137 | QVERIFY(c1 != c4); |
138 | |
139 | QVERIFY(!(c2 == c3)); |
140 | QVERIFY(c2 != c3); |
141 | |
142 | QGeoRectangle b1(QGeoCoordinate(20,20),QGeoCoordinate(10,30)); |
143 | QVERIFY(!(c1 == b1)); |
144 | QVERIFY(c1 != b1); |
145 | |
146 | QGeoShape *c2Ptr = &c2; |
147 | QVERIFY(c1 == *c2Ptr); |
148 | QVERIFY(!(c1 != *c2Ptr)); |
149 | |
150 | QGeoShape *c3Ptr = &c3; |
151 | QVERIFY(!(c1 == *c3Ptr)); |
152 | QVERIFY(c1 != *c3Ptr); |
153 | } |
154 | |
155 | void tst_QGeoCircle::type() |
156 | { |
157 | QGeoCircle c; |
158 | QCOMPARE(c.type(), QGeoShape::CircleType); |
159 | } |
160 | |
161 | void tst_QGeoCircle::radius() |
162 | { |
163 | QGeoCircle c; |
164 | c.setRadius(1.0); |
165 | QCOMPARE(c.radius(), qreal(1.0)); |
166 | c.setRadius(5.0); |
167 | QCOMPARE(c.radius(), qreal(5.0)); |
168 | } |
169 | |
170 | void tst_QGeoCircle::center() |
171 | { |
172 | QGeoCircle c; |
173 | c.setCenter(QGeoCoordinate(1,1)); |
174 | QCOMPARE(c.center(), QGeoCoordinate(1,1)); |
175 | |
176 | QGeoShape shape = c; |
177 | QCOMPARE(shape.center(), c.center()); |
178 | |
179 | c.setCenter(QGeoCoordinate(5,10)); |
180 | QCOMPARE(c.center(), QGeoCoordinate(5,10)); |
181 | } |
182 | |
183 | void tst_QGeoCircle::translate_data() |
184 | { |
185 | QTest::addColumn<QGeoCoordinate>(name: "center" ); |
186 | QTest::addColumn<qreal>(name: "radius" ); |
187 | QTest::addColumn<double>(name: "lat" ); |
188 | QTest::addColumn<double>(name: "lon" ); |
189 | QTest::addColumn<QGeoCoordinate>(name: "newCenter" ); |
190 | |
191 | QTest::newRow(dataTag: "from 0,0" ) << QGeoCoordinate(0,0) << qreal(10.0) << |
192 | 5.0 << 5.0 << QGeoCoordinate(5.0, 5.0); |
193 | QTest::newRow(dataTag: "across 0,0" ) << QGeoCoordinate(-2, -2) << qreal(20.0) << |
194 | 5.0 << 5.0 << QGeoCoordinate(3.0, 3.0); |
195 | QTest::newRow(dataTag: "backwards across 0,0" ) << QGeoCoordinate(5,5) << qreal(50.0) |
196 | << -13.0 << 5.0 |
197 | << QGeoCoordinate(-8.0, 10.0); |
198 | } |
199 | |
200 | void tst_QGeoCircle::translate() |
201 | { |
202 | QFETCH(QGeoCoordinate, center); |
203 | QFETCH(qreal, radius); |
204 | QFETCH(double, lat); |
205 | QFETCH(double, lon); |
206 | QFETCH(QGeoCoordinate, newCenter); |
207 | |
208 | QGeoCircle c(center, radius); |
209 | QGeoCircle d = c; |
210 | |
211 | c.translate(degreesLatitude: lat, degreesLongitude: lon); |
212 | |
213 | QCOMPARE(c.radius(), radius); |
214 | QCOMPARE(c.center(), newCenter); |
215 | |
216 | c = d.translated(degreesLatitude: lat, degreesLongitude: lon); |
217 | d.setRadius(1.0); |
218 | |
219 | QCOMPARE(c.radius(), radius); |
220 | QCOMPARE(d.center(), center); |
221 | QCOMPARE(c.center(), newCenter); |
222 | } |
223 | |
224 | void tst_QGeoCircle::valid_data() |
225 | { |
226 | QTest::addColumn<QGeoCoordinate>(name: "center" ); |
227 | QTest::addColumn<qreal>(name: "radius" ); |
228 | QTest::addColumn<bool>(name: "valid" ); |
229 | |
230 | QTest::newRow(dataTag: "default" ) << QGeoCoordinate() << qreal(-1.0) << false; |
231 | QTest::newRow(dataTag: "empty coord" ) << QGeoCoordinate() << qreal(5.0) << false; |
232 | QTest::newRow(dataTag: "NaN coord" ) << QGeoCoordinate(500, 500) << qreal(5.0) << false; |
233 | QTest::newRow(dataTag: "bad radius" ) << QGeoCoordinate(10, 10) << qreal(-5.0) << false; |
234 | QTest::newRow(dataTag: "NaN radius" ) << QGeoCoordinate(10, 10) << qreal(qQNaN()) << false; |
235 | QTest::newRow(dataTag: "zero radius" ) << QGeoCoordinate(10, 10) << qreal(0.0) << true; |
236 | QTest::newRow(dataTag: "good" ) << QGeoCoordinate(10, 10) << qreal(5.0) << true; |
237 | } |
238 | |
239 | void tst_QGeoCircle::valid() |
240 | { |
241 | QFETCH(QGeoCoordinate, center); |
242 | QFETCH(qreal, radius); |
243 | QFETCH(bool, valid); |
244 | |
245 | QGeoCircle c(center, radius); |
246 | QCOMPARE(c.isValid(), valid); |
247 | |
248 | QGeoShape area = c; |
249 | QCOMPARE(area.isValid(), valid); |
250 | } |
251 | |
252 | void tst_QGeoCircle::empty_data() |
253 | { |
254 | QTest::addColumn<QGeoCoordinate>(name: "center" ); |
255 | QTest::addColumn<qreal>(name: "radius" ); |
256 | QTest::addColumn<bool>(name: "empty" ); |
257 | |
258 | QTest::newRow(dataTag: "default" ) << QGeoCoordinate() << qreal(-1.0) << true; |
259 | QTest::newRow(dataTag: "empty coord" ) << QGeoCoordinate() << qreal(5.0) << true; |
260 | QTest::newRow(dataTag: "NaN coord" ) << QGeoCoordinate(500, 500) << qreal(5.0) << true; |
261 | QTest::newRow(dataTag: "bad radius" ) << QGeoCoordinate(10, 10) << qreal(-5.0) << true; |
262 | QTest::newRow(dataTag: "NaN radius" ) << QGeoCoordinate(10, 10) << qreal(qQNaN()) << true; |
263 | QTest::newRow(dataTag: "zero radius" ) << QGeoCoordinate(10, 10) << qreal(0.0) << true; |
264 | QTest::newRow(dataTag: "good" ) << QGeoCoordinate(10, 10) << qreal(5.0) << false; |
265 | } |
266 | |
267 | void tst_QGeoCircle::empty() |
268 | { |
269 | QFETCH(QGeoCoordinate, center); |
270 | QFETCH(qreal, radius); |
271 | QFETCH(bool, empty); |
272 | |
273 | QGeoCircle c(center, radius); |
274 | QCOMPARE(c.isEmpty(), empty); |
275 | |
276 | QGeoShape area = c; |
277 | QCOMPARE(area.isEmpty(), empty); |
278 | } |
279 | |
280 | void tst_QGeoCircle::contains_data() |
281 | { |
282 | QTest::addColumn<QGeoCoordinate>(name: "center" ); |
283 | QTest::addColumn<qreal>(name: "radius" ); |
284 | QTest::addColumn<QGeoCoordinate>(name: "probe" ); |
285 | QTest::addColumn<bool>(name: "result" ); |
286 | |
287 | QTest::newRow(dataTag: "own center" ) << QGeoCoordinate(1,1) << qreal(100.0) << |
288 | QGeoCoordinate(1,1) << true; |
289 | QTest::newRow(dataTag: "over the hills" ) << QGeoCoordinate(1,1) << qreal(100.0) << |
290 | QGeoCoordinate(30, 40) << false; |
291 | QTest::newRow(dataTag: "at 0.5*radius" ) << QGeoCoordinate(1,1) << qreal(100.0) << |
292 | QGeoCoordinate(1.00015374,1.00015274) << true; |
293 | QTest::newRow(dataTag: "at 0.99*radius" ) << QGeoCoordinate(1,1) << qreal(100.0) << |
294 | QGeoCoordinate(1.00077538, 0.99955527) << true; |
295 | QTest::newRow(dataTag: "at 1.01*radius" ) << QGeoCoordinate(1,1) << qreal(100.0) << |
296 | QGeoCoordinate(1.00071413, 0.99943423) << false; |
297 | // TODO: add tests for edge circle cases: cross 1 pole, cross both poles |
298 | } |
299 | |
300 | void tst_QGeoCircle::contains() |
301 | { |
302 | QFETCH(QGeoCoordinate, center); |
303 | QFETCH(qreal, radius); |
304 | QFETCH(QGeoCoordinate, probe); |
305 | QFETCH(bool, result); |
306 | |
307 | QGeoCircle c(center, radius); |
308 | QCOMPARE(c.contains(probe), result); |
309 | |
310 | QGeoShape area = c; |
311 | QCOMPARE(area.contains(probe), result); |
312 | } |
313 | |
314 | void tst_QGeoCircle::boundingGeoRectangle_data() |
315 | { |
316 | QTest::addColumn<QGeoCoordinate>(name: "center" ); |
317 | QTest::addColumn<qreal>(name: "radius" ); |
318 | QTest::addColumn<QGeoCoordinate>(name: "probe" ); |
319 | QTest::addColumn<bool>(name: "result" ); |
320 | |
321 | QTest::newRow(dataTag: "own center" ) << QGeoCoordinate(1,1) << qreal(100.0) << |
322 | QGeoCoordinate(1,1) << true; |
323 | QTest::newRow(dataTag: "over the hills" ) << QGeoCoordinate(1,1) << qreal(100.0) << |
324 | QGeoCoordinate(30, 40) << false; |
325 | QTest::newRow(dataTag: "at 0.5*radius" ) << QGeoCoordinate(1,1) << qreal(100.0) << |
326 | QGeoCoordinate(1.00015374,1.00015274) << true; |
327 | QTest::newRow(dataTag: "at 0.99*radius" ) << QGeoCoordinate(1,1) << qreal(100.0) << |
328 | QGeoCoordinate(1.00077538, 0.99955527) << true; |
329 | QTest::newRow(dataTag: "Outside the box" ) << QGeoCoordinate(1,1) << qreal(100.0) << |
330 | QGeoCoordinate(1.00071413, 0.99903423) << false; |
331 | // TODO: add tests for edge circle cases: cross 1 pole, cross both poles |
332 | } |
333 | |
334 | void tst_QGeoCircle::boundingGeoRectangle() |
335 | { |
336 | QFETCH(QGeoCoordinate, center); |
337 | QFETCH(qreal, radius); |
338 | QFETCH(QGeoCoordinate, probe); |
339 | QFETCH(bool, result); |
340 | |
341 | QGeoCircle c(center, radius); |
342 | QGeoRectangle box = c.boundingGeoRectangle(); |
343 | QCOMPARE(box.contains(probe), result); |
344 | } |
345 | |
346 | void tst_QGeoCircle::extendCircle() |
347 | { |
348 | QFETCH(QGeoCircle, circle); |
349 | QFETCH(QGeoCoordinate, coord); |
350 | QFETCH(bool, containsFirst); |
351 | QFETCH(bool, containsExtended); |
352 | |
353 | QCOMPARE(circle.contains(coord), containsFirst); |
354 | circle.extendCircle(coordinate: coord); |
355 | QCOMPARE(circle.contains(coord), containsExtended); |
356 | |
357 | } |
358 | |
359 | void tst_QGeoCircle::extendCircle_data() |
360 | { |
361 | QTest::addColumn<QGeoCircle>(name: "circle" ); |
362 | QTest::addColumn<QGeoCoordinate>(name: "coord" ); |
363 | QTest::addColumn<bool>(name: "containsFirst" ); |
364 | QTest::addColumn<bool>(name: "containsExtended" ); |
365 | |
366 | QGeoCoordinate co1(20.0, 20.0); |
367 | |
368 | QTest::newRow(dataTag: "own center" ) |
369 | << QGeoCircle(co1, 100) |
370 | << QGeoCoordinate(20.0, 20.0) |
371 | << true |
372 | << true; |
373 | QTest::newRow(dataTag: "inside" ) |
374 | << QGeoCircle(co1, 100) |
375 | << QGeoCoordinate(20.0001, 20.0001) |
376 | << true |
377 | << true; |
378 | QTest::newRow(dataTag: "far away" ) |
379 | << QGeoCircle(co1, 100) |
380 | << QGeoCoordinate(50.0001, 50.0001) |
381 | << false |
382 | << true; |
383 | QTest::newRow(dataTag: "invalid circle" ) |
384 | << QGeoCircle() |
385 | << QGeoCoordinate(20.0, 20.0) |
386 | << false |
387 | << false; |
388 | QTest::newRow(dataTag: "invalid coordinate" ) |
389 | << QGeoCircle(co1, 100) |
390 | << QGeoCoordinate(99.0, 190.0) |
391 | << false |
392 | << false; |
393 | } |
394 | |
395 | void tst_QGeoCircle::areaComparison_data() |
396 | { |
397 | QTest::addColumn<QGeoShape>(name: "area" ); |
398 | QTest::addColumn<QGeoCircle>(name: "circle" ); |
399 | QTest::addColumn<bool>(name: "equal" ); |
400 | |
401 | QGeoCircle c1(QGeoCoordinate(10.0, 0.0), 10.0); |
402 | QGeoCircle c2(QGeoCoordinate(20.0, 10.0), 20.0); |
403 | QGeoRectangle b(QGeoCoordinate(10.0, 0.0), QGeoCoordinate(0.0, 10.0)); |
404 | |
405 | QTest::newRow(dataTag: "default constructed" ) << QGeoShape() << QGeoCircle() << false; |
406 | QTest::newRow(dataTag: "c1 c1" ) << QGeoShape(c1) << c1 << true; |
407 | QTest::newRow(dataTag: "c1 c2" ) << QGeoShape(c1) << c2 << false; |
408 | QTest::newRow(dataTag: "c2 c1" ) << QGeoShape(c2) << c1 << false; |
409 | QTest::newRow(dataTag: "c2 c2" ) << QGeoShape(c2) << c2 << true; |
410 | QTest::newRow(dataTag: "b c1" ) << QGeoShape(b) << c1 << false; |
411 | } |
412 | |
413 | void tst_QGeoCircle::areaComparison() |
414 | { |
415 | QFETCH(QGeoShape, area); |
416 | QFETCH(QGeoCircle, circle); |
417 | QFETCH(bool, equal); |
418 | |
419 | QCOMPARE((area == circle), equal); |
420 | QCOMPARE((area != circle), !equal); |
421 | |
422 | QCOMPARE((circle == area), equal); |
423 | QCOMPARE((circle != area), !equal); |
424 | } |
425 | |
426 | void tst_QGeoCircle::boxComparison_data() |
427 | { |
428 | QTest::addColumn<QGeoRectangle>(name: "box" ); |
429 | QTest::addColumn<QGeoCircle>(name: "circle" ); |
430 | QTest::addColumn<bool>(name: "equal" ); |
431 | |
432 | QGeoCircle c(QGeoCoordinate(10.0, 0.0), 10.0); |
433 | QGeoRectangle b(QGeoCoordinate(10.0, 0.0), QGeoCoordinate(0.0, 10.0)); |
434 | |
435 | QTest::newRow(dataTag: "default constructed" ) << QGeoRectangle() << QGeoCircle() << false; |
436 | QTest::newRow(dataTag: "b c" ) << b << c << false; |
437 | } |
438 | |
439 | void tst_QGeoCircle::boxComparison() |
440 | { |
441 | QFETCH(QGeoRectangle, box); |
442 | QFETCH(QGeoCircle, circle); |
443 | QFETCH(bool, equal); |
444 | |
445 | QCOMPARE((box == circle), equal); |
446 | QCOMPARE((box != circle), !equal); |
447 | |
448 | QCOMPARE((circle == box), equal); |
449 | QCOMPARE((circle != box), !equal); |
450 | } |
451 | |
452 | QTEST_MAIN(tst_QGeoCircle) |
453 | #include "tst_qgeocircle.moc" |
454 | |