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 //TESTED_COMPONENT=src/location/maps
30 
31 #include <QtLocation/private/qgeotilespec_p.h>
32 #include <QtLocation/private/qgeocameratiles_p.h>
33 #include <QtLocation/private/qgeocameradata_p.h>
34 #include <QtLocation/private/qgeomaptype_p.h>
35 
36 #include <QtPositioning/private/qwebmercator_p.h>
37 #include <QtPositioning/private/qdoublevector2d_p.h>
38 #include <QtTest/QtTest>
39 #include <QtCore/QList>
40 #include <QtCore/QPair>
41 #include <QtCore/qmath.h>
42 
43 QT_USE_NAMESPACE
44 
45 struct PositionTestInfo {
46     QString xyString;
47     QString zoomString;
48     QString wString;
49     QString hString;
50     double x;
51     double y;
52     double zoom;
53     double w;
54     double h;
55 };
56 
57 class tst_QGeoCameraTiles : public QObject
58 {
59     Q_OBJECT
60 
61 private:
62 
63     void row(const PositionTestInfo &pti, int xOffset, int yOffset, int tileX, int tileY, int tileW, int tileH);
64     void test_group(const PositionTestInfo &pti, QList<int> &xVals, QList<int> &wVals, QList<int> &yVals, QList<int> &hVals);
65 
66 private slots:
67 
68     void tilesPlugin();
69     void tilesMapType();
70     void tilesPositions();
71     void tilesPositions_data();
72     void test_tilted_frustum();
73 };
74 
row(const PositionTestInfo & pti,int xOffset,int yOffset,int tileX,int tileY,int tileW,int tileH)75 void tst_QGeoCameraTiles::row(const PositionTestInfo &pti, int xOffset, int yOffset, int tileX, int tileY, int tileW, int tileH)
76 {
77     double step = 1 / (qPow(2.0, 4.0) * 4);
78 
79     QString row = pti.xyString;
80     row += QStringLiteral(" - ");
81     row += pti.zoomString;
82     row += QStringLiteral(" - (");
83     row += QString::number(xOffset);
84     row += QStringLiteral(",");
85     row += QString::number(yOffset);
86     row += QStringLiteral(") - ");
87     row += pti.wString;
88     row += QStringLiteral(" x ");
89     row += pti.hString;
90 
91     QList<int> xRow;
92     QList<int> yRow;
93 
94     for (int y = 0; y < tileH; ++y) {
95         for (int x = 0; x < tileW; ++x) {
96             if (tileX + x < 16)
97                 xRow << tileX + x;
98             else
99                 xRow << tileX + x - 16;
100             yRow << tileY + y;
101         }
102     }
103 
104     QTest::newRow(qPrintable(row))
105             << pti.x + step * xOffset << pti.y + step * yOffset
106             << pti.zoom << pti.w << pti.h
107             << xRow
108             << yRow;
109 }
110 
test_group(const PositionTestInfo & pti,QList<int> & xVals,QList<int> & wVals,QList<int> & yVals,QList<int> & hVals)111 void tst_QGeoCameraTiles::test_group(const PositionTestInfo &pti, QList<int> &xVals, QList<int> &wVals, QList<int> &yVals, QList<int> &hVals)
112 {
113     for (int x = 0; x < 5; ++x) {
114         for (int y = 0; y < 5; ++y) {
115             row(pti, x, y, xVals.at(x), yVals.at(y), wVals.at(x), hVals.at(y));
116         }
117     }
118 }
119 
test_tilted_frustum()120 void tst_QGeoCameraTiles::test_tilted_frustum()
121 {
122     // ctFull : Full map in the view, all 16 zl2 tiles visible. Using this as control.
123     QGeoCameraData cameraFull;
124     cameraFull.setZoomLevel(2);
125     cameraFull.setCenter(QGeoCoordinate(0,0));
126     QGeoCameraTiles ctFull;
127     ctFull.setTileSize(64);
128     ctFull.setCameraData(cameraFull);
129     ctFull.setScreenSize(QSize(256, 256));
130 
131     QGeoCameraData camera;
132     camera.setZoomLevel(2.322);
133     camera.setTilt(30);
134     camera.setCenter(QWebMercator::mercatorToCoord(QDoubleVector2D(0.75, 0.5)));
135     QGeoCameraTiles ct;
136     ct.setTileSize(64);
137     ct.setScreenSize(QSize(320, 180));
138     ct.setCameraData(camera);
139 
140     QCOMPARE(ct.createTiles(), ctFull.createTiles());
141 }
142 
tilesPlugin()143 void tst_QGeoCameraTiles::tilesPlugin()
144 {
145     QGeoCameraData camera;
146     camera.setZoomLevel(4.0);
147     camera.setCenter(QGeoCoordinate(0.0, 0.0));
148 
149     QGeoCameraTiles ct;
150     ct.setTileSize(16);
151     ct.setCameraData(camera);
152     ct.setScreenSize(QSize(32, 32));
153     ct.setMapType(QGeoMapType(QGeoMapType::StreetMap, "street map", "street map", false, false, 1, QByteArrayLiteral(""), QGeoCameraCapabilities()));
154 
155     QSet<QGeoTileSpec> tiles1 = ct.createTiles();
156 
157     ct.setPluginString("pluginA");
158 
159     QSet<QGeoTileSpec> tiles2 = ct.createTiles();
160 
161     typedef QSet<QGeoTileSpec>::const_iterator iter;
162     iter i1 = tiles1.constBegin();
163     iter end1 = tiles1.constEnd();
164 
165     QSet<QGeoTileSpec> tiles2_check;
166 
167     for (; i1 != end1; ++i1) {
168         QGeoTileSpec tile = *i1;
169         tiles2_check.insert(QGeoTileSpec("pluginA", tile.mapId(), tile.zoom(), tile.x(), tile.y()));
170     }
171 
172     QCOMPARE(tiles2, tiles2_check);
173 
174     ct.setPluginString("pluginB");
175 
176     QSet<QGeoTileSpec> tiles3 = ct.createTiles();
177 
178     iter i2 = tiles2.constBegin();
179     iter end2 = tiles2.constEnd();
180 
181     QSet<QGeoTileSpec> tiles3_check;
182 
183     for (; i2 != end2; ++i2) {
184         QGeoTileSpec tile = *i2;
185         tiles3_check.insert(QGeoTileSpec("pluginB", tile.mapId(), tile.zoom(), tile.x(), tile.y()));
186     }
187 
188     QCOMPARE(tiles3, tiles3_check);
189 }
190 
tilesMapType()191 void tst_QGeoCameraTiles::tilesMapType()
192 {
193     QGeoCameraData camera;
194     camera.setZoomLevel(4.0);
195     camera.setCenter(QGeoCoordinate(0.0, 0.0));
196 
197     QGeoCameraTiles ct;
198     ct.setTileSize(16);
199     ct.setCameraData(camera);
200     ct.setScreenSize(QSize(32, 32));
201     ct.setPluginString("pluginA");
202 
203     QSet<QGeoTileSpec> tiles1 = ct.createTiles();
204 
205     QGeoMapType mapType1 = QGeoMapType(QGeoMapType::StreetMap, "street map", "street map", false, false, 1, QByteArrayLiteral(""), QGeoCameraCapabilities());
206     ct.setMapType(mapType1);
207 
208     QSet<QGeoTileSpec> tiles2 = ct.createTiles();
209 
210     typedef QSet<QGeoTileSpec>::const_iterator iter;
211     iter i1 = tiles1.constBegin();
212     iter end1 = tiles1.constEnd();
213 
214     QSet<QGeoTileSpec> tiles2_check;
215 
216     for (; i1 != end1; ++i1) {
217         QGeoTileSpec tile = *i1;
218         tiles2_check.insert(QGeoTileSpec(tile.plugin(), mapType1.mapId(), tile.zoom(), tile.x(), tile.y()));
219     }
220 
221     QCOMPARE(tiles2, tiles2_check);
222 
223     QGeoMapType mapType2 = QGeoMapType(QGeoMapType::StreetMap, "satellite map", "satellite map", false, false, 2, QByteArrayLiteral(""), QGeoCameraCapabilities());
224     ct.setMapType(mapType2);
225 
226     QSet<QGeoTileSpec> tiles3 = ct.createTiles();
227 
228     iter i2 = tiles2.constBegin();
229     iter end2 = tiles2.constEnd();
230 
231     QSet<QGeoTileSpec> tiles3_check;
232 
233     for (; i2 != end2; ++i2) {
234         QGeoTileSpec tile = *i2;
235         tiles3_check.insert(QGeoTileSpec(tile.plugin(), mapType2.mapId(), tile.zoom(), tile.x(), tile.y()));
236     }
237 
238     QCOMPARE(tiles3, tiles3_check);
239 }
240 
tilesPositions()241 void tst_QGeoCameraTiles::tilesPositions()
242 {
243     QFETCH(double, mercatorX);
244     QFETCH(double, mercatorY);
245     QFETCH(double, zoom);
246     QFETCH(double, width);
247     QFETCH(double, height);
248     QFETCH(QList<int> , tilesX);
249     QFETCH(QList<int> , tilesY);
250 
251     QGeoCameraData camera;
252     camera.setZoomLevel(zoom);
253     camera.setCenter(QWebMercator::mercatorToCoord(QDoubleVector2D(mercatorX, mercatorY)));
254 
255     QGeoCameraTiles ct;
256     ct.setTileSize(16);
257     ct.setCameraData(camera);
258     ct.setScreenSize(QSize(qCeil(width), qCeil(height)));
259 
260     QSet<QGeoTileSpec> tiles;
261 
262     QVERIFY2(tilesX.size() == tilesY.size(), "tilesX and tilesY have different size");
263 
264     for (int i = 0; i < tilesX.size(); ++i)
265         tiles.insert(QGeoTileSpec("", 0, static_cast<int>(qFloor(zoom)), tilesX.at(i), tilesY.at(i)));
266 
267     QCOMPARE(ct.createTiles(), tiles);
268 }
269 
tilesPositions_data()270 void tst_QGeoCameraTiles::tilesPositions_data()
271 {
272     QTest::addColumn<double>("mercatorX");
273     QTest::addColumn<double>("mercatorY");
274     QTest::addColumn<double>("zoom");
275     QTest::addColumn<double>("width");
276     QTest::addColumn<double>("height");
277     QTest::addColumn<QList<int> >("tilesX");
278     QTest::addColumn<QList<int> >("tilesY");
279 
280     int t = 16;
281 
282     PositionTestInfo pti;
283 
284     /*
285             This test sets up various viewports onto a 16x16 map,
286             and checks which tiles are visible against those that
287             are expected to be visible.
288 
289             The tests are run in 5 groups, corresponding to where
290             the viewport is centered on the map.
291 
292             The groups are named as follows, with the tile in
293             which the viewport is centered listed in parenthesis:
294               - mid (8, 8)
295               - top (8, 0)
296               - bottom (8, 15)
297               - left (0, 8)
298               - right (15, 8)
299 
300             For each of these groups a number of tests are run,
301             which involve modifying various parameters.
302 
303             If "t" is the width of a tile, the width and height
304             of the viewport take on values including:
305               - (t - 1)
306               - t
307               - (t + 1)
308               - (2t - 1)
309               - 2t
310               - (2t + 1)
311 
312             The viewport is also offset by fractions of a tile
313             in both the x and y directions.  The offsets are in
314             quarters of a tile.
315 
316             The diagrams below present a justification for our
317             test expectations.
318 
319             The diagrams show variations in viewport width and
320             x offset into the target tile , although can easily
321             be taken to be the variations in viewport height and
322             y offset into the target tile.
323 
324             The symbols have the following meanings:
325               "+" - tile boundaries
326               "*" - viewport boundary
327               "T" - boundary of tile the viewport is centered on
328               "O" - same as "T" but coincident with the viewport boundary
329 
330             Whenever the viewport boundary is coincident with a tile boundary,
331             the tiles on both sides of the boundary are expected to be fetched.
332 
333             Those tiles are needed in case we perform bilinear antialiasing,
334             provide us with at least a pixel width of tolerance for errors in
335             other parts of the code or the system.  There is a decent chance
336             that some or all of those extra tiles will need to be fetched before
337             long, so getting them into the cache sooner rather than later is
338             likely to be beneficial on average.
339 
340             The tests are carried out per viewport height / width.
341 
342             Lists are created of the first tile along an axis that is expected to
343             be in the viewport and for the number of tiles along an axis that
344             are expected to be in the viewport.
345 
346             These lists are used for both the x and y axes, although alternative
347             lists are created for the x axis when the viewport spans the dateline
348             and for the y axis when the viewport is clipped by the top or bottom of
349             the map.
350 
351             These 5 areas are checked at an integral zoom level to see that the
352             expected visible tiles match the actual visible tiles generated by
353             the code under test.
354 
355             After that a fractional zoom level is set and the width and height of
356             the viewport are scaled such that the same tiles should be visible,
357             and the tests are repeated.
358         */
359 
360     // TODO
361     // nail down semantics, modify tests and code to suite
362     // add corners of the map
363 
364     /*
365             width = t - 1
366         */
367 
368     QList<int> mid_tm1x;
369     QList<int> mid_tm1w;
370     QList<int> top_tm1x;
371     QList<int> top_tm1w;
372     QList<int> bottom_tm1x;
373     QList<int> bottom_tm1w;
374     QList<int> left_tm1x;
375     QList<int> left_tm1w;
376     QList<int> right_tm1x;
377     QList<int> right_tm1w;
378 
379     pti.w = t - 1;
380     pti.h = t - 1;
381     pti.wString = QStringLiteral("(1T - 1)");
382     pti.hString = QStringLiteral("(1T - 1)");
383 
384     /*
385 
386                 offset = 0
387                 + + + + + + + + + + + + + + + + + + + + +
388                 +       +       +       +       +       +
389                 +       +    * *+* *    +       +       +
390                 +       +    *  +  *    +       +       +
391                 + + + + + + +*+ T T*T T T + + + + + + + +
392                 +       +    *  T  *    T       +       +
393                 +       +    * *T* *    T       +       +
394                 +       +       T       T       +       +
395                 + + + + + + + + T T T T T + + + + + + + +
396 
397                 Starts at:  T - 1
398                 Covers:     2 tiles
399         */
400 
401     mid_tm1x << 7;
402     mid_tm1w << 2;
403 
404     top_tm1x << 0;
405     top_tm1w << 1;
406 
407     bottom_tm1x << 14;
408     bottom_tm1w << 2;
409 
410     left_tm1x << 15;
411     left_tm1w << 2;
412 
413     right_tm1x << 14;
414     right_tm1w << 2;
415 
416     /*
417                 offset = 1
418                 + + + + + + + + + + + + + + + + + + + + +
419                 +       +       +       +       +       +
420                 +       +      *+* * *  +       +       +
421                 +       +      *+    *  +       +       +
422                 + + + + + + + +*T T T*T T + + + + + + + +
423                 +       +      *T    *  T       +       +
424                 +       +      *T* * *  T       +       +
425                 +       +       T       T       +       +
426                 + + + + + + + + T T T T T + + + + + + + +
427 
428                 Starts at:  T - 1
429                 Covers:     2 tiles
430         */
431 
432     mid_tm1x << 7;
433     mid_tm1w << 2;
434 
435     top_tm1x << 0;
436     top_tm1w << 1;
437 
438     bottom_tm1x << 14;
439     bottom_tm1w << 2;
440 
441     left_tm1x << 15;
442     left_tm1w << 2;
443 
444     right_tm1x << 14;
445     right_tm1w << 2;
446 
447     /*
448                 offset = 2
449                 + + + + + + + + + + + + + + + + + + + + +
450                 +       +       +       +       +       +
451                 +       +       +* * * *+       +       +
452                 +       +       +*     *+       +       +
453                 + + + + + + + + T*T T T*T + + + + + + + +
454                 +       +       T*     *T       +       +
455                 +       +       T* * * *T       +       +
456                 +       +       T       T       +       +
457                 + + + + + + + + T T T T T + + + + + + + +
458 
459                 Starts at:  T
460                 Covers:     1 tile
461         */
462 
463     mid_tm1x << 8;
464     mid_tm1w << 1;
465 
466     top_tm1x << 0;
467     top_tm1w << 1;
468 
469     bottom_tm1x << 15;
470     bottom_tm1w << 1;
471 
472     left_tm1x << 0;
473     left_tm1w << 1;
474 
475     right_tm1x << 15;
476     right_tm1w << 1;
477 
478     /*
479                 offset = 3
480                 + + + + + + + + + + + + + + + + + + + + +
481                 +       +       +       +       +       +
482                 +       +       +  * * *+*      +       +
483                 +       +       +  *    +*      +       +
484                 + + + + + + + + T T*T T T*+ + + + + + + +
485                 +       +       T  *    T*      +       +
486                 +       +       T  * * *T*      +       +
487                 +       +       T       T       +       +
488                 + + + + + + + + T T T T T + + + + + + + +
489 
490                 Starts at:  T
491                 Covers:     2 tiles
492         */
493 
494     mid_tm1x << 8;
495     mid_tm1w << 2;
496 
497     top_tm1x << 0;
498     top_tm1w << 2;
499 
500     bottom_tm1x << 15;
501     bottom_tm1w << 1;
502 
503     left_tm1x << 0;
504     left_tm1w << 2;
505 
506     right_tm1x << 15;
507     right_tm1w << 2;
508 
509     /*
510                 offset = 4
511                 + + + + + + + + + + + + + + + + + + + + +
512                 +       +       +       +       +       +
513                 +       +       +    * *+* *    +       +
514                 +       +       +    *  +  *    +       +
515                 + + + + + + + + T T T*T T +*+ + + + + + +
516                 +       +       T    *  T  *    +       +
517                 +       +       T    * *T* *    +       +
518                 +       +       T       T       +       +
519                 + + + + + + + + T T T T T + + + + + + + +
520 
521                 Starts at:  T
522                 Covers:     2 tiles
523         */
524 
525     mid_tm1x << 8;
526     mid_tm1w << 2;
527 
528     top_tm1x << 0;
529     top_tm1w << 2;
530 
531     bottom_tm1x << 15;
532     bottom_tm1w << 1;
533 
534     left_tm1x << 0;
535     left_tm1w << 2;
536 
537     right_tm1x << 15;
538     right_tm1w << 2;
539 
540     pti.zoom = 4.0;
541     pti.zoomString = QStringLiteral("int zoom");
542 
543     pti.x = 0.5;
544     pti.y = 0.5;
545     pti.xyString = QStringLiteral("middle");
546 
547     test_group(pti, mid_tm1x, mid_tm1w, mid_tm1x, mid_tm1w);
548 
549     pti.x = 0.5;
550     pti.y = 0.0;
551     pti.xyString = QStringLiteral("top");
552 
553     test_group(pti, mid_tm1x, mid_tm1w, top_tm1x, top_tm1w);
554 
555     pti.x = 0.5;
556     pti.y = 15.0 / 16.0;
557     pti.xyString = QStringLiteral("bottom");
558 
559     test_group(pti, mid_tm1x, mid_tm1w, bottom_tm1x, bottom_tm1w);
560 
561     pti.x = 0.0;
562     pti.y = 0.5;
563     pti.xyString = QStringLiteral("left");
564 
565     test_group(pti, left_tm1x, left_tm1w, mid_tm1x, mid_tm1w);
566 
567     pti.x = 15.0 / 16.0;
568     pti.y = 0.5;
569     pti.xyString = QStringLiteral("right");
570 
571     test_group(pti, right_tm1x, right_tm1w, mid_tm1x, mid_tm1w);
572 
573     pti.zoom = 4.5;
574     pti.zoomString = QStringLiteral("frac zoom");
575     pti.w = pti.w * qPow(2.0, 0.5);
576     pti.h = pti.h * qPow(2.0, 0.5);
577 
578     pti.x = 0.5;
579     pti.y = 0.5;
580     pti.xyString = QStringLiteral("middle");
581 
582     test_group(pti, mid_tm1x, mid_tm1w, mid_tm1x, mid_tm1w);
583 
584     pti.x = 0.5;
585     pti.y = 0.0;
586     pti.xyString = QStringLiteral("top");
587 
588     test_group(pti, mid_tm1x, mid_tm1w, top_tm1x, top_tm1w);
589 
590     pti.x = 0.5;
591     pti.y = 15.0 / 16.0;
592     pti.xyString = QStringLiteral("bottom");
593 
594     test_group(pti, mid_tm1x, mid_tm1w, bottom_tm1x, bottom_tm1w);
595 
596     pti.x = 0.0;
597     pti.y = 0.5;
598     pti.xyString = QStringLiteral("left");
599 
600     test_group(pti, left_tm1x, left_tm1w, mid_tm1x, mid_tm1w);
601 
602     pti.x = 15.0 / 16.0;
603     pti.y = 0.5;
604     pti.xyString = QStringLiteral("right");
605 
606     test_group(pti, right_tm1x, right_tm1w, mid_tm1x, mid_tm1w);
607 
608     /*
609             width = t
610         */
611 
612     QList<int> mid_tx;
613     QList<int> mid_tw;
614     QList<int> top_tx;
615     QList<int> top_tw;
616     QList<int> bottom_tx;
617     QList<int> bottom_tw;
618     QList<int> left_tx;
619     QList<int> left_tw;
620     QList<int> right_tx;
621     QList<int> right_tw;
622 
623     pti.w = t;
624     pti.h = t;
625     pti.wString = QStringLiteral("1T");
626     pti.hString = QStringLiteral("1T");
627 
628     /*
629 
630                 offset = 0
631                 + + + + + + + + + + + + + + + + + + + + +
632                 +       +       +       +       +       +
633                 +       +   * * * * *   +       +       +
634                 +       +   *   +   *   +       +       +
635                 + + + + + + * + T T O T T + + + + + + + +
636                 +       +   *   T   *   T       +       +
637                 +       +   * * O * *   T       +       +
638                 +       +       T       T       +       +
639                 + + + + + + + + T T T T T + + + + + + + +
640 
641                 Starts at:  T - 1
642                 Covers:     2 tiles
643         */
644 
645     mid_tx << 7;
646     mid_tw << 2;
647 
648     top_tx << 0;
649     top_tw << 1;
650 
651     bottom_tx << 14;
652     bottom_tw << 2;
653 
654     left_tx << 15;
655     left_tw << 2;
656 
657     right_tx << 14;
658     right_tw << 2;
659 
660     /*
661                 offset = 1
662                 + + + + + + + + + + + + + + + + + + + + +
663                 +       +       +       +       +       +
664                 +       +     * * * * * +       +       +
665                 +       +     * +     * +       +       +
666                 + + + + + + + * T T T O T + + + + + + + +
667                 +       +     * T     * T       +       +
668                 +       +     * O * * * T       +       +
669                 +       +       T       T       +       +
670                 + + + + + + + + T T T T T + + + + + + + +
671 
672                 Starts at:  T - 1
673                 Covers:     2 tiles
674         */
675 
676     mid_tx << 7;
677     mid_tw << 2;
678 
679     top_tx << 0;
680     top_tw << 1;
681 
682     bottom_tx << 14;
683     bottom_tw << 2;
684 
685     left_tx << 15;
686     left_tw << 2;
687 
688     right_tx << 14;
689     right_tw << 2;
690 
691     /*
692                 offset = 2
693                 + + + + + + + + + + + + + + + + + + + + +
694                 +       +       +       +       +       +
695                 +       +       * * * * *       +       +
696                 +       +       *       *       +       +
697                 + + + + + + + + O T T T O + + + + + + + +
698                 +       +       O       O       +       +
699                 +       +       O * * * O       +       +
700                 +       +       T       T       +       +
701                 + + + + + + + + T T T T T + + + + + + + +
702 
703                 Starts at:  T - 1
704                 Covers:     3 tiles
705         */
706 
707     mid_tx << 7;
708     mid_tw << 3;
709 
710     top_tx << 0;
711     top_tw << 2;
712 
713     bottom_tx << 14;
714     bottom_tw << 2;
715 
716     left_tx << 15;
717     left_tw << 3;
718 
719     right_tx << 14;
720     right_tw << 3;
721 
722     /*
723                 offset = 3
724                 + + + + + + + + + + + + + + + + + + + + +
725                 +       +       +       +       +       +
726                 +       +       + * * * * *     +       +
727                 +       +       + *       *     +       +
728                 + + + + + + + + T O T T T * + + + + + + +
729                 +       +       T *     T *     +       +
730                 +       +       T * * * O *     +       +
731                 +       +       T       T       +       +
732                 + + + + + + + + T T T T T + + + + + + + +
733 
734                 Starts at:  T
735                 Covers:     2 tiles
736         */
737 
738     mid_tx << 8;
739     mid_tw << 2;
740 
741     top_tx << 0;
742     top_tw << 2;
743 
744     bottom_tx << 15;
745     bottom_tw << 1;
746 
747     left_tx << 0;
748     left_tw << 2;
749 
750     right_tx << 15;
751     right_tw << 2;
752 
753     /*
754                 offset = 4
755                 + + + + + + + + + + + + + + + + + + + + +
756                 +       +       +       +       +       +
757                 +       +       +   * * * * *   +       +
758                 +       +       +   *   +   *   +       +
759                 + + + + + + + + T T O T T + * + + + + + +
760                 +       +       T   *   T   *   +       +
761                 +       +       T   * * O * *   +       +
762                 +       +       T       T       +       +
763                 + + + + + + + + T T T T T + + + + + + + +
764 
765                 Starts at:  T
766                 Covers:     2 tiles
767         */
768 
769     mid_tx << 8;
770     mid_tw << 2;
771 
772     top_tx << 0;
773     top_tw << 2;
774 
775     bottom_tx << 15;
776     bottom_tw << 1;
777 
778     left_tx << 0;
779     left_tw << 2;
780 
781     right_tx << 15;
782     right_tw << 2;
783 
784     pti.zoom = 4.0;
785     pti.zoomString = QStringLiteral("int zoom");
786 
787     pti.x = 0.5;
788     pti.y = 0.5;
789     pti.xyString = QStringLiteral("middle");
790 
791     test_group(pti, mid_tx, mid_tw, mid_tx, mid_tw);
792 
793     pti.x = 0.5;
794     pti.y = 0.0;
795     pti.xyString = QStringLiteral("top");
796 
797     test_group(pti, mid_tx, mid_tw, top_tx, top_tw);
798 
799     pti.x = 0.5;
800     pti.y = 15.0 / 16.0;
801     pti.xyString = QStringLiteral("bottom");
802 
803     test_group(pti, mid_tx, mid_tw, bottom_tx, bottom_tw);
804 
805     pti.x = 0.0;
806     pti.y = 0.5;
807     pti.xyString = QStringLiteral("left");
808 
809     test_group(pti, left_tx, left_tw, mid_tx, mid_tw);
810 
811     pti.x = 15.0 / 16.0;
812     pti.y = 0.5;
813     pti.xyString = QStringLiteral("right");
814 
815     test_group(pti, right_tx, right_tw, mid_tx, mid_tw);
816 
817     pti.zoom = 4.5;
818     pti.zoomString = QStringLiteral("frac zoom");
819     pti.w = pti.w * qPow(2.0, 0.5);
820     pti.h = pti.h * qPow(2.0, 0.5);
821 
822     pti.x = 0.5;
823     pti.y = 0.5;
824     pti.xyString = QStringLiteral("middle");
825 
826     test_group(pti, mid_tx, mid_tw, mid_tx, mid_tw);
827 
828     pti.x = 0.5;
829     pti.y = 0.0;
830     pti.xyString = QStringLiteral("top");
831 
832     test_group(pti, mid_tx, mid_tw, top_tx, top_tw);
833 
834     pti.x = 0.5;
835     pti.y = 15.0 / 16.0;
836     pti.xyString = QStringLiteral("bottom");
837 
838     test_group(pti, mid_tx, mid_tw, bottom_tx, bottom_tw);
839 
840     pti.x = 0.0;
841     pti.y = 0.5;
842     pti.xyString = QStringLiteral("left");
843 
844     test_group(pti, left_tx, left_tw, mid_tx, mid_tw);
845 
846     pti.x = 15.0 / 16.0;
847     pti.y = 0.5;
848     pti.xyString = QStringLiteral("right");
849 
850     test_group(pti, right_tx, right_tw, mid_tx, mid_tw);
851 
852     /*
853             width = t + 1
854         */
855 
856     QList<int> mid_tp1x;
857     QList<int> mid_tp1w;
858     QList<int> top_tp1x;
859     QList<int> top_tp1w;
860     QList<int> bottom_tp1x;
861     QList<int> bottom_tp1w;
862     QList<int> left_tp1x;
863     QList<int> left_tp1w;
864     QList<int> right_tp1x;
865     QList<int> right_tp1w;
866 
867     pti.w = t + 1;
868     pti.h = t + 1;
869     pti.wString = QStringLiteral("(1T + 1)");
870     pti.hString = QStringLiteral("(1T + 1)");
871 
872     /*
873 
874                 offset = 0
875                 + + + + + + + + + + + + + + + + + + + + +
876                 +       +       +       +       +       +
877                 +       +  * * *+* * *  +       +       +
878                 +       +  *    +    *  +       +       +
879                 + + + + + +*+ + T T T*T T + + + + + + + +
880                 +       +  *    T    *  T       +       +
881                 +       +  * * *T* * *  T       +       +
882                 +       +       T       T       +       +
883                 + + + + + + + + T T T T T + + + + + + + +
884 
885                 Starts at:  T - 1
886                 Covers:     2 tiles
887         */
888 
889     mid_tp1x << 7;
890     mid_tp1w << 2;
891 
892     top_tp1x << 0;
893     top_tp1w << 1;
894 
895     bottom_tp1x << 14;
896     bottom_tp1w << 2;
897 
898     left_tp1x << 15;
899     left_tp1w << 2;
900 
901     right_tp1x << 14;
902     right_tp1w << 2;
903 
904     /*
905                 offset = 1
906                 + + + + + + + + + + + + + + + + + + + + +
907                 +       +       +       +       +       +
908                 +       +    * *+* * * *+       +       +
909                 +       +    *  +      *+       +       +
910                 + + + + + + +*+ T T T T*T + + + + + + + +
911                 +       +    *  T      *T       +       +
912                 +       +    * *T* * * *T       +       +
913                 +       +       T       T       +       +
914                 + + + + + + + + T T T T T + + + + + + + +
915 
916                 Starts at:  T - 1
917                 Covers:     2 tiles
918         */
919 
920     mid_tp1x << 7;
921     mid_tp1w << 2;
922 
923     top_tp1x << 0;
924     top_tp1w << 1;
925 
926     bottom_tp1x << 14;
927     bottom_tp1w << 2;
928 
929     left_tp1x << 15;
930     left_tp1w << 2;
931 
932     right_tp1x << 14;
933     right_tp1w << 2;
934 
935     /*
936                 offset = 2
937                 + + + + + + + + + + + + + + + + + + + + +
938                 +       +       +       +       +       +
939                 +       +      *+* * * *+*      +       +
940                 +       +      *+       +*      +       +
941                 + + + + + + + +*T T T T T*+ + + + + + + +
942                 +       +      *T       T*      +       +
943                 +       +      *T* * * *T*      +       +
944                 +       +       T       T       +       +
945                 + + + + + + + + T T T T T + + + + + + + +
946 
947                 Starts at:  T - 1
948                 Covers:     3 tiles
949         */
950 
951     mid_tp1x << 7;
952     mid_tp1w << 3;
953 
954     top_tp1x << 0;
955     top_tp1w << 2;
956 
957     bottom_tp1x << 14;
958     bottom_tp1w << 2;
959 
960     left_tp1x << 15;
961     left_tp1w << 3;
962 
963     right_tp1x << 14;
964     right_tp1w << 3;
965 
966     /*
967                 offset = 3
968                 + + + + + + + + + + + + + + + + + + + + +
969                 +       +       +       +       +       +
970                 +       +       +* * * *+* *    +       +
971                 +       +       +*      +  *    +       +
972                 + + + + + + + + T*T T T T +*+ + + + + + +
973                 +       +       T*      T  *    +       +
974                 +       +       T* * * *T* *    +       +
975                 +       +       T       T       +       +
976                 + + + + + + + + T T T T T + + + + + + + +
977 
978                 Starts at:  T
979                 Covers:     2 tiles
980         */
981 
982     mid_tp1x << 8;
983     mid_tp1w << 2;
984 
985     top_tp1x << 0;
986     top_tp1w << 2;
987 
988     bottom_tp1x << 15;
989     bottom_tp1w << 1;
990 
991     left_tp1x << 0;
992     left_tp1w << 2;
993 
994     right_tp1x << 15;
995     right_tp1w << 2;
996 
997     /*
998                 offset = 4
999                 + + + + + + + + + + + + + + + + + + + + +
1000                 +       +       +       +       +       +
1001                 +       +       +  * * *+* * *  +       +
1002                 +       +       +  *    +    *  +       +
1003                 + + + + + + + + T T*T T T + +*+ + + + + +
1004                 +       +       T  *    T    *  +       +
1005                 +       +       T  * * *T* * *  +       +
1006                 +       +       T       T       +       +
1007                 + + + + + + + + T T T T T + + + + + + + +
1008 
1009                 Starts at:  T
1010                 Covers:     2 tiles
1011         */
1012 
1013     mid_tp1x << 8;
1014     mid_tp1w << 2;
1015 
1016     top_tp1x << 0;
1017     top_tp1w << 2;
1018 
1019     bottom_tp1x << 15;
1020     bottom_tp1w << 1;
1021 
1022     left_tp1x << 0;
1023     left_tp1w << 2;
1024 
1025     right_tp1x << 15;
1026     right_tp1w << 2;
1027 
1028     pti.zoom = 4.0;
1029     pti.zoomString = QStringLiteral("int zoom");
1030 
1031     pti.x = 0.5;
1032     pti.y = 0.5;
1033     pti.xyString = QStringLiteral("middle");
1034 
1035     test_group(pti, mid_tp1x, mid_tp1w, mid_tp1x, mid_tp1w);
1036 
1037     pti.x = 0.5;
1038     pti.y = 0.0;
1039     pti.xyString = QStringLiteral("top");
1040 
1041     test_group(pti, mid_tp1x, mid_tp1w, top_tp1x, top_tp1w);
1042 
1043     pti.x = 0.5;
1044     pti.y = 15.0 / 16.0;
1045     pti.xyString = QStringLiteral("bottom");
1046 
1047     test_group(pti, mid_tp1x, mid_tp1w, bottom_tp1x, bottom_tp1w);
1048 
1049     pti.x = 0.0;
1050     pti.y = 0.5;
1051     pti.xyString = QStringLiteral("left");
1052 
1053     test_group(pti, left_tp1x, left_tp1w, mid_tp1x, mid_tp1w);
1054 
1055     pti.x = 15.0 / 16.0;
1056     pti.y = 0.5;
1057     pti.xyString = QStringLiteral("right");
1058 
1059     test_group(pti, right_tp1x, right_tp1w, mid_tp1x, mid_tp1w);
1060 
1061     pti.zoom = 4.5;
1062     pti.zoomString = QStringLiteral("frac zoom");
1063     pti.w = pti.w * qPow(2.0, 0.5);
1064     pti.h = pti.h * qPow(2.0, 0.5);
1065 
1066     pti.x = 0.5;
1067     pti.y = 0.5;
1068     pti.xyString = QStringLiteral("middle");
1069 
1070     test_group(pti, mid_tp1x, mid_tp1w, mid_tp1x, mid_tp1w);
1071 
1072     pti.x = 0.5;
1073     pti.y = 0.0;
1074     pti.xyString = QStringLiteral("top");
1075 
1076     test_group(pti, mid_tp1x, mid_tp1w, top_tp1x, top_tp1w);
1077 
1078     pti.x = 0.5;
1079     pti.y = 15.0 / 16.0;
1080     pti.xyString = QStringLiteral("bottom");
1081 
1082     test_group(pti, mid_tp1x, mid_tp1w, bottom_tp1x, bottom_tp1w);
1083 
1084     pti.x = 0.0;
1085     pti.y = 0.5;
1086     pti.xyString = QStringLiteral("left");
1087 
1088     test_group(pti, left_tp1x, left_tp1w, mid_tp1x, mid_tp1w);
1089 
1090     pti.x = 15.0 / 16.0;
1091     pti.y = 0.5;
1092     pti.xyString = QStringLiteral("right");
1093 
1094     test_group(pti, right_tp1x, right_tp1w, mid_tp1x, mid_tp1w);
1095 
1096     /*
1097             width = 2t - 1
1098         */
1099 
1100     QList<int> mid_t2m1x;
1101     QList<int> mid_t2m1w;
1102     QList<int> top_t2m1x;
1103     QList<int> top_t2m1w;
1104     QList<int> bottom_t2m1x;
1105     QList<int> bottom_t2m1w;
1106     QList<int> left_t2m1x;
1107     QList<int> left_t2m1w;
1108     QList<int> right_t2m1x;
1109     QList<int> right_t2m1w;
1110 
1111     pti.w = 2 * t - 1;
1112     pti.h = 2 * t - 1;
1113     pti.wString = QStringLiteral("(2T - 1)");
1114     pti.hString = QStringLiteral("(2T - 1)");
1115 
1116     /*
1117                 offset = 0
1118                 + + + + + + + + + + + + + + + + + + + + +
1119                 +       +       +       +       +       +
1120                 +       +* * * *+* * * *+       +       +
1121                 +       +*      +      *+       +       +
1122                 + + + + +*+ + + T T T T*T + + + + + + + +
1123                 +       +*      T      *T       +       +
1124                 +       +* * * *T* * * *T       +       +
1125                 +       +       T       T       +       +
1126                 + + + + + + + + T T T T T + + + + + + + +
1127 
1128                 Starts at:  T - 1
1129                 Covers:     2 tiles
1130         */
1131 
1132     mid_t2m1x << 7;
1133     mid_t2m1w << 2;
1134 
1135     top_t2m1x << 0;
1136     top_t2m1w << 1;
1137 
1138     bottom_t2m1x << 14;
1139     bottom_t2m1w << 2;
1140 
1141     left_t2m1x << 15;
1142     left_t2m1w << 2;
1143 
1144     right_t2m1x << 14;
1145     right_t2m1w << 2;
1146 
1147     /*
1148                 offset = 1
1149                 + + + + + + + + + + + + + + + + + + + + +
1150                 +       +       +       +       +       +
1151                 +       +  * * *+* * * *+*      +       +
1152                 +       +  *    +       +*      +       +
1153                 + + + + + +*+ + T T T T T*+ + + + + + + +
1154                 +       +  *    T       T*      +       +
1155                 +       +  * * *T* * * *T*      +       +
1156                 +       +       T       T       +       +
1157                 + + + + + + + + T T T T T + + + + + + + +
1158 
1159                 Starts at:  T - 1
1160                 Covers:     3 tiles
1161         */
1162 
1163     mid_t2m1x << 7;
1164     mid_t2m1w << 3;
1165 
1166     top_t2m1x << 0;
1167     top_t2m1w << 2;
1168 
1169     bottom_t2m1x << 14;
1170     bottom_t2m1w << 2;
1171 
1172     left_t2m1x << 15;
1173     left_t2m1w << 3;
1174 
1175     right_t2m1x << 14;
1176     right_t2m1w << 3;
1177 
1178     /*
1179                 offset = 2
1180                 + + + + + + + + + + + + + + + + + + + + +
1181                 +       +       +       +       +       +
1182                 +       +    * *+* * * *+* *    +       +
1183                 +       +    *  +       +  *    +       +
1184                 + + + + + + +*+ T T T T T +*+ + + + + + +
1185                 +       +    *  T       T  *    +       +
1186                 +       +    * *T* * * *T* *    +       +
1187                 +       +       T       T       +       +
1188                 + + + + + + + + T T T T T + + + + + + + +
1189 
1190                 Starts at:  T - 1
1191                 Covers:     3 tiles
1192         */
1193 
1194     mid_t2m1x << 7;
1195     mid_t2m1w << 3;
1196 
1197     top_t2m1x << 0;
1198     top_t2m1w << 2;
1199 
1200     bottom_t2m1x << 14;
1201     bottom_t2m1w << 2;
1202 
1203     left_t2m1x << 15;
1204     left_t2m1w << 3;
1205 
1206     right_t2m1x << 14;
1207     right_t2m1w << 3;
1208 
1209     /*
1210                 offset = 3
1211                 + + + + + + + + + + + + + + + + + + + + +
1212                 +       +       +       +       +       +
1213                 +       +      *+* * * *+* * *  +       +
1214                 +       +      *+       +    *  +       +
1215                 + + + + + + + +*T T T T T + +*+ + + + + +
1216                 +       +      *T       T    *  +       +
1217                 +       +      *T* * * *T* * *  +       +
1218                 +       +       T       T       +       +
1219                 + + + + + + + + T T T T T + + + + + + + +
1220 
1221                 Starts at:  T - 1
1222                 Covers:     3 tiles
1223         */
1224 
1225     mid_t2m1x << 7;
1226     mid_t2m1w << 3;
1227 
1228     top_t2m1x << 0;
1229     top_t2m1w << 2;
1230 
1231     bottom_t2m1x << 14;
1232     bottom_t2m1w << 2;
1233 
1234     left_t2m1x << 15;
1235     left_t2m1w << 3;
1236 
1237     right_t2m1x << 14;
1238     right_t2m1w << 3;
1239 
1240     /*
1241                 offset = 4
1242                 + + + + + + + + + + + + + + + + + + + + +
1243                 +       +       +       +       +       +
1244                 +       +       +* * * *+* * * *+       +
1245                 +       +       +*      +      *+       +
1246                 + + + + + + + + T*T T T T + + +*+ + + + +
1247                 +       +       T*      T      *+       +
1248                 +       +       T* * * *T* * * *+       +
1249                 +       +       T       T       +       +
1250                 + + + + + + + + T T T T T + + + + + + + +
1251 
1252                 Starts at:  T
1253                 Covers:     2 tiles
1254         */
1255 
1256     mid_t2m1x << 8;
1257     mid_t2m1w << 2;
1258 
1259     top_t2m1x << 0;
1260     top_t2m1w << 2;
1261 
1262     bottom_t2m1x << 15;
1263     bottom_t2m1w << 1;
1264 
1265     left_t2m1x << 0;
1266     left_t2m1w << 2;
1267 
1268     right_t2m1x << 15;
1269     right_t2m1w << 2;
1270 
1271     pti.zoom = 4.0;
1272     pti.zoomString = QStringLiteral("int zoom");
1273 
1274     pti.x = 0.5;
1275     pti.y = 0.5;
1276     pti.xyString = QStringLiteral("middle");
1277 
1278     test_group(pti, mid_t2m1x, mid_t2m1w, mid_t2m1x, mid_t2m1w);
1279 
1280     pti.x = 0.5;
1281     pti.y = 0.0;
1282     pti.xyString = QStringLiteral("top");
1283 
1284     test_group(pti, mid_t2m1x, mid_t2m1w, top_t2m1x, top_t2m1w);
1285 
1286     pti.x = 0.5;
1287     pti.y = 15.0 / 16.0;
1288     pti.xyString = QStringLiteral("bottom");
1289 
1290     test_group(pti, mid_t2m1x, mid_t2m1w, bottom_t2m1x, bottom_t2m1w);
1291 
1292     pti.x = 0.0;
1293     pti.y = 0.5;
1294     pti.xyString = QStringLiteral("left");
1295 
1296     test_group(pti, left_t2m1x, left_t2m1w, mid_t2m1x, mid_t2m1w);
1297 
1298     pti.x = 15.0 / 16.0;
1299     pti.y = 0.5;
1300     pti.xyString = QStringLiteral("right");
1301 
1302     test_group(pti, right_t2m1x, right_t2m1w, mid_t2m1x, mid_t2m1w);
1303 
1304     pti.zoom = 4.5;
1305     pti.zoomString = QStringLiteral("frac zoom");
1306     pti.w = pti.w * qPow(2.0, 0.5);
1307     pti.h = pti.h * qPow(2.0, 0.5);
1308 
1309     pti.x = 0.5;
1310     pti.y = 0.5;
1311     pti.xyString = QStringLiteral("middle");
1312 
1313     test_group(pti, mid_t2m1x, mid_t2m1w, mid_t2m1x, mid_t2m1w);
1314 
1315     pti.x = 0.5;
1316     pti.y = 0.0;
1317     pti.xyString = QStringLiteral("top");
1318 
1319     test_group(pti, mid_t2m1x, mid_t2m1w, top_t2m1x, top_t2m1w);
1320 
1321     pti.x = 0.5;
1322     pti.y = 15.0 / 16.0;
1323     pti.xyString = QStringLiteral("bottom");
1324 
1325     test_group(pti, mid_t2m1x, mid_t2m1w, bottom_t2m1x, bottom_t2m1w);
1326 
1327     pti.x = 0.0;
1328     pti.y = 0.5;
1329     pti.xyString = QStringLiteral("left");
1330 
1331     test_group(pti, left_t2m1x, left_t2m1w, mid_t2m1x, mid_t2m1w);
1332 
1333     pti.x = 15.0 / 16.0;
1334     pti.y = 0.5;
1335     pti.xyString = QStringLiteral("right");
1336 
1337     test_group(pti, right_t2m1x, right_t2m1w, mid_t2m1x, mid_t2m1w);
1338 
1339     /*
1340             width = 2t
1341         */
1342 
1343 
1344     QList<int> mid_t2x;
1345     QList<int> mid_t2w;
1346     QList<int> top_t2x;
1347     QList<int> top_t2w;
1348     QList<int> bottom_t2x;
1349     QList<int> bottom_t2w;
1350     QList<int> left_t2x;
1351     QList<int> left_t2w;
1352     QList<int> right_t2x;
1353     QList<int> right_t2w;
1354 
1355     pti.w = 2 * t;
1356     pti.h = 2 * t;
1357     pti.wString = QStringLiteral("2T");
1358     pti.hString = QStringLiteral("2T");
1359 
1360     /*
1361 
1362                 offset = 0
1363                 + + + + + + + + + + + + + + + + + + + + +
1364                 +       +       +       +       +       +
1365                 +       * * * * * * * * *       +       +
1366                 +       *       +       *       +       +
1367                 + + + + * + + + T T T T O + + + + + + + +
1368                 +       *       T       O       +       +
1369                 +       * * * * O * * * O       +       +
1370                 +       +       T       T       +       +
1371                 + + + + + + + + T T T T T + + + + + + + +
1372 
1373                 Starts at:  T - 2
1374                 Covers:     4 tiles
1375         */
1376 
1377     mid_t2x << 6;
1378     mid_t2w << 4;
1379 
1380     top_t2x << 0;
1381     top_t2w << 2;
1382 
1383     bottom_t2x << 13;
1384     bottom_t2w << 3;
1385 
1386     left_t2x << 14;
1387     left_t2w << 4;
1388 
1389     right_t2x << 13;
1390     right_t2w << 4;
1391 
1392     /*
1393                 offset = 1
1394                 + + + + + + + + + + + + + + + + + + + + +
1395                 +       +       +       +       +       +
1396                 +       + * * * * * * * * *     +       +
1397                 +       + *     +         *     +       +
1398                 + + + + + * + + T T T T T * + + + + + + +
1399                 +       + *     T       T *     +       +
1400                 +       + * * * O * * * O *     +       +
1401                 +       +       T       T       +       +
1402                 + + + + + + + + T T T T T + + + + + + + +
1403 
1404                 Starts at:  T - 1
1405                 Covers:     3 tiles
1406         */
1407 
1408     mid_t2x << 7;
1409     mid_t2w << 3;
1410 
1411     top_t2x << 0;
1412     top_t2w << 2;
1413 
1414     bottom_t2x << 14;
1415     bottom_t2w << 2;
1416 
1417     left_t2x << 15;
1418     left_t2w << 3;
1419 
1420     right_t2x << 14;
1421     right_t2w << 3;
1422 
1423     /*
1424                 offset = 2
1425                 + + + + + + + + + + + + + + + + + + + + +
1426                 +       +       +       +       +       +
1427                 +       +   * * * * * * * * *   +       +
1428                 +       +   *   +           *   +       +
1429                 + + + + + + * + T T T T T + * + + + + + +
1430                 +       +   *   T       T   *   +       +
1431                 +       +   * * O * * * O * *   +       +
1432                 +       +       T       T       +       +
1433                 + + + + + + + + T T T T T + + + + + + + +
1434 
1435                 Starts at:  T - 1
1436                 Covers:     3 tiles
1437         */
1438 
1439     mid_t2x << 7;
1440     mid_t2w << 3;
1441 
1442     top_t2x << 0;
1443     top_t2w << 2;
1444 
1445     bottom_t2x << 14;
1446     bottom_t2w << 2;
1447 
1448     left_t2x << 15;
1449     left_t2w << 3;
1450 
1451     right_t2x << 14;
1452     right_t2w << 3;
1453 
1454     /*
1455                 offset = 3
1456                 + + + + + + + + + + + + + + + + + + + + +
1457                 +       +       +       +       +       +
1458                 +       +     * * * * * * * * * +       +
1459                 +       +     * +             * +       +
1460                 + + + + + + + * T T T T T + + * + + + + +
1461                 +       +     * T       T     * +       +
1462                 +       +     * O * * * O * * * +       +
1463                 +       +       T       T       +       +
1464                 + + + + + + + + T T T T T + + + + + + + +
1465 
1466                 Starts at:  T - 1
1467                 Covers:     3 tiles
1468         */
1469 
1470     mid_t2x << 7;
1471     mid_t2w << 3;
1472 
1473     top_t2x << 0;
1474     top_t2w << 2;
1475 
1476     bottom_t2x << 14;
1477     bottom_t2w << 2;
1478 
1479     left_t2x << 15;
1480     left_t2w << 3;
1481 
1482     right_t2x << 14;
1483     right_t2w << 3;
1484 
1485     /*
1486                 offset = 4
1487                 + + + + + + + + + + + + + + + + + + + + +
1488                 +       +       +       +       +       +
1489                 +       +       * * * * * * * * *       +
1490                 +       +       *               *       +
1491                 + + + + + + + + O T T T T + + + * + + + +
1492                 +       +       O       T       *       +
1493                 +       +       O * * * O * * * *       +
1494                 +       +       T       T       +       +
1495                 + + + + + + + + T T T T T + + + + + + + +
1496 
1497                 Starts at:  T - 1
1498                 Covers:     4 tiles
1499         */
1500 
1501     mid_t2x << 7;
1502     mid_t2w << 4;
1503 
1504     top_t2x << 0;
1505     top_t2w << 3;
1506 
1507     bottom_t2x << 14;
1508     bottom_t2w << 2;
1509 
1510     left_t2x << 15;
1511     left_t2w << 4;
1512 
1513     right_t2x << 14;
1514     right_t2w << 4;
1515 
1516     pti.zoom = 4.0;
1517     pti.zoomString = QStringLiteral("int zoom");
1518 
1519     pti.x = 0.5;
1520     pti.y = 0.5;
1521     pti.xyString = QStringLiteral("middle");
1522 
1523     test_group(pti, mid_t2x, mid_t2w, mid_t2x, mid_t2w);
1524 
1525     pti.x = 0.5;
1526     pti.y = 0.0;
1527     pti.xyString = QStringLiteral("top");
1528 
1529     test_group(pti, mid_t2x, mid_t2w, top_t2x, top_t2w);
1530 
1531     pti.x = 0.5;
1532     pti.y = 15.0 / 16.0;
1533     pti.xyString = QStringLiteral("bottom");
1534 
1535     test_group(pti, mid_t2x, mid_t2w, bottom_t2x, bottom_t2w);
1536 
1537     pti.x = 0.0;
1538     pti.y = 0.5;
1539     pti.xyString = QStringLiteral("left");
1540 
1541     test_group(pti, left_t2x, left_t2w, mid_t2x, mid_t2w);
1542 
1543     pti.x = 15.0 / 16.0;
1544     pti.y = 0.5;
1545     pti.xyString = QStringLiteral("right");
1546 
1547     test_group(pti, right_t2x, right_t2w, mid_t2x, mid_t2w);
1548 
1549     pti.zoom = 4.5;
1550     pti.zoomString = QStringLiteral("frac zoom");
1551     pti.w = pti.w * qPow(2.0, 0.5);
1552     pti.h = pti.h * qPow(2.0, 0.5);
1553 
1554     pti.x = 0.5;
1555     pti.y = 0.5;
1556     pti.xyString = QStringLiteral("middle");
1557 
1558     test_group(pti, mid_t2x, mid_t2w, mid_t2x, mid_t2w);
1559 
1560     pti.x = 0.5;
1561     pti.y = 0.0;
1562     pti.xyString = QStringLiteral("top");
1563 
1564     test_group(pti, mid_t2x, mid_t2w, top_t2x, top_t2w);
1565 
1566     pti.x = 0.5;
1567     pti.y = 15.0 / 16.0;
1568     pti.xyString = QStringLiteral("bottom");
1569 
1570     test_group(pti, mid_t2x, mid_t2w, bottom_t2x, bottom_t2w);
1571 
1572     pti.x = 0.0;
1573     pti.y = 0.5;
1574     pti.xyString = QStringLiteral("left");
1575 
1576     test_group(pti, left_t2x, left_t2w, mid_t2x, mid_t2w);
1577 
1578     pti.x = 15.0 / 16.0;
1579     pti.y = 0.5;
1580     pti.xyString = QStringLiteral("right");
1581 
1582     test_group(pti, right_t2x, right_t2w, mid_t2x, mid_t2w);
1583 
1584     /*
1585             width = 2t + 1
1586         */
1587 
1588     QList<int> mid_t2p1x;
1589     QList<int> mid_t2p1w;
1590     QList<int> top_t2p1x;
1591     QList<int> top_t2p1w;
1592     QList<int> bottom_t2p1x;
1593     QList<int> bottom_t2p1w;
1594     QList<int> left_t2p1x;
1595     QList<int> left_t2p1w;
1596     QList<int> right_t2p1x;
1597     QList<int> right_t2p1w;
1598 
1599     pti.w = 2 * t + 1;
1600     pti.h = 2 * t + 1;
1601     pti.wString = QStringLiteral("(2T + 1)");
1602     pti.hString = QStringLiteral("(2T + 1)");
1603 
1604     /*
1605 
1606                 offset = 0
1607                 + + + + + + + + + + + + + + + + + + + + +
1608                 +       +       +       +       +       +
1609                 +      *+* * * *+* * * *+*      +       +
1610                 +      *+       +       +*      +       +
1611                 + + + +*+ + + + T T T T T*+ + + + + + + +
1612                 +      *+       T       T*      +       +
1613                 +      *+* * * *T* * * *T*      +       +
1614                 +       +       T       T       +       +
1615                 + + + + + + + + T T T T T + + + + + + + +
1616 
1617                 Starts at:  T - 2
1618                 Covers:     4 tiles
1619         */
1620 
1621     mid_t2p1x << 6;
1622     mid_t2p1w << 4;
1623 
1624     top_t2p1x << 0;
1625     top_t2p1w << 2;
1626 
1627     bottom_t2p1x << 13;
1628     bottom_t2p1w << 3;
1629 
1630     left_t2p1x << 14;
1631     left_t2p1w << 4;
1632 
1633     right_t2p1x << 13;
1634     right_t2p1w << 4;
1635 
1636     /*
1637                 offset = 1
1638                 + + + + + + + + + + + + + + + + + + + + +
1639                 +       +       +       +       +       +
1640                 +       +* * * *+* * * *+* *    +       +
1641                 +       +*      +       +  *    +       +
1642                 + + + + +*+ + + T T T T T +*+ + + + + + +
1643                 +       +*      T       T  *    +       +
1644                 +       +* * * *T* * * *T* *    +       +
1645                 +       +       T       T       +       +
1646                 + + + + + + + + T T T T T + + + + + + + +
1647 
1648                 Starts at:  T - 1
1649                 Covers:     3 tiles
1650         */
1651 
1652     mid_t2p1x << 7;
1653     mid_t2p1w << 3;
1654 
1655     top_t2p1x << 0;
1656     top_t2p1w << 2;
1657 
1658     bottom_t2p1x << 14;
1659     bottom_t2p1w << 2;
1660 
1661     left_t2p1x << 15;
1662     left_t2p1w << 3;
1663 
1664     right_t2p1x << 14;
1665     right_t2p1w << 3;
1666 
1667     /*
1668                 offset = 2
1669                 + + + + + + + + + + + + + + + + + + + + +
1670                 +       +       +       +       +       +
1671                 +       +  * * *+* * * *+* * *  +       +
1672                 +       +  *    +       +    *  +       +
1673                 + + + + + +*+ + T T T T T + +*+ + + + + +
1674                 +       +  *    T       T    *  +       +
1675                 +       +  * * *T* * * *T* * *  +       +
1676                 +       +       T       T       +       +
1677                 + + + + + + + + T T T T T + + + + + + + +
1678 
1679                 Starts at:  T - 1
1680                 Covers:     3 tiles
1681         */
1682 
1683     mid_t2p1x << 7;
1684     mid_t2p1w << 3;
1685 
1686     top_t2p1x << 0;
1687     top_t2p1w << 2;
1688 
1689     bottom_t2p1x << 14;
1690     bottom_t2p1w << 2;
1691 
1692     left_t2p1x << 15;
1693     left_t2p1w << 3;
1694 
1695     right_t2p1x << 14;
1696     right_t2p1w << 3;
1697 
1698     /*
1699                 offset = 3
1700                 + + + + + + + + + + + + + + + + + + + + +
1701                 +       +       +       +       +       +
1702                 +       +    * *+* * * *+* * * *+       +
1703                 +       +    *  +       +      *+       +
1704                 + + + + + + +*+ T T T T T + + +*+ + + + +
1705                 +       +    *  T       T      *+       +
1706                 +       +    * *T* * * *T* * * *+       +
1707                 +       +       T       T       +       +
1708                 + + + + + + + + T T T T T + + + + + + + +
1709 
1710                 Starts at:  T - 1
1711                 Covers:     3 tiles
1712         */
1713 
1714     mid_t2p1x << 7;
1715     mid_t2p1w << 3;
1716 
1717     top_t2p1x << 0;
1718     top_t2p1w << 2;
1719 
1720     bottom_t2p1x << 14;
1721     bottom_t2p1w << 2;
1722 
1723     left_t2p1x << 15;
1724     left_t2p1w << 3;
1725 
1726     right_t2p1x << 14;
1727     right_t2p1w << 3;
1728 
1729     /*
1730                 offset = 4
1731                 + + + + + + + + + + + + + + + + + + + + +
1732                 +       +       +       +       +       +
1733                 +       +      *+* * * *+* * * *+*      +
1734                 +       +      *+       +       +*      +
1735                 + + + + + + + +*T T T T T + + + +*+ + + +
1736                 +       +      *T       T       +*      +
1737                 +       +      *T* * * *T* * * *+*      +
1738                 +       +       T       T       +       +
1739                 + + + + + + + + T T T T T + + + + + + + +
1740 
1741                 Starts at:  T - 1
1742                 Covers:     4 tiles
1743          */
1744 
1745     mid_t2p1x << 7;
1746     mid_t2p1w << 4;
1747 
1748     top_t2p1x << 0;
1749     top_t2p1w << 3;
1750 
1751     bottom_t2p1x << 14;
1752     bottom_t2p1w << 2;
1753 
1754     left_t2p1x << 15;
1755     left_t2p1w << 4;
1756 
1757     right_t2p1x << 14;
1758     right_t2p1w << 4;
1759 
1760     pti.zoom = 4.0;
1761     pti.zoomString = QStringLiteral("int zoom");
1762 
1763     pti.x = 0.5;
1764     pti.y = 0.5;
1765     pti.xyString = QStringLiteral("middle");
1766 
1767     test_group(pti, mid_t2p1x, mid_t2p1w, mid_t2p1x, mid_t2p1w);
1768 
1769     pti.x = 0.5;
1770     pti.y = 0.0;
1771     pti.xyString = QStringLiteral("top");
1772 
1773     test_group(pti, mid_t2p1x, mid_t2p1w, top_t2p1x, top_t2p1w);
1774 
1775     pti.x = 0.5;
1776     pti.y = 15.0 / 16.0;
1777     pti.xyString = QStringLiteral("bottom");
1778 
1779     test_group(pti, mid_t2p1x, mid_t2p1w, bottom_t2p1x, bottom_t2p1w);
1780 
1781     pti.x = 0.0;
1782     pti.y = 0.5;
1783     pti.xyString = QStringLiteral("left");
1784 
1785     test_group(pti, left_t2p1x, left_t2p1w, mid_t2p1x, mid_t2p1w);
1786 
1787     pti.x = 15.0 / 16.0;
1788     pti.y = 0.5;
1789     pti.xyString = QStringLiteral("right");
1790 
1791     test_group(pti, right_t2p1x, right_t2p1w, mid_t2p1x, mid_t2p1w);
1792 
1793     pti.zoom = 4.5;
1794     pti.zoomString = QStringLiteral("frac zoom");
1795     pti.w = pti.w * qPow(2.0, 0.5);
1796     pti.h = pti.h * qPow(2.0, 0.5);
1797 
1798     pti.x = 0.5;
1799     pti.y = 0.5;
1800     pti.xyString = QStringLiteral("middle");
1801 
1802     test_group(pti, mid_t2p1x, mid_t2p1w, mid_t2p1x, mid_t2p1w);
1803 
1804     pti.x = 0.5;
1805     pti.y = 0.0;
1806     pti.xyString = QStringLiteral("top");
1807 
1808     test_group(pti, mid_t2p1x, mid_t2p1w, top_t2p1x, top_t2p1w);
1809 
1810     pti.x = 0.5;
1811     pti.y = 15.0 / 16.0;
1812     pti.xyString = QStringLiteral("bottom");
1813 
1814     test_group(pti, mid_t2p1x, mid_t2p1w, bottom_t2p1x, bottom_t2p1w);
1815 
1816     pti.x = 0.0;
1817     pti.y = 0.5;
1818     pti.xyString = QStringLiteral("left");
1819 
1820     test_group(pti, left_t2p1x, left_t2p1w, mid_t2p1x, mid_t2p1w);
1821 
1822     pti.x = 15.0 / 16.0;
1823     pti.y = 0.5;
1824     pti.xyString = QStringLiteral("right");
1825 
1826     test_group(pti, right_t2p1x, right_t2p1w, mid_t2p1x, mid_t2p1w);
1827 }
1828 
1829 QTEST_GUILESS_MAIN(tst_QGeoCameraTiles)
1830 #include "tst_qgeocameratiles.moc"
1831