1 /****************************************************************************
2 **
3 ** Copyright (C) 2018 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 "qgeotiledmap_test.h"
30 #include "qgeotilefetcher_test.h"
31 #include "qgeotiledmappingmanagerengine_test.h"
32 #include <QtCore/QString>
33 #include <QtTest/QtTest>
34 #include <QtTest/QSignalSpy>
35 #include <QtPositioning/private/qwebmercator_p.h>
36 #include <QtLocation/QGeoServiceProvider>
37 #include <QtLocation/private/qgeotiledmap_p.h>
38 #include <QtLocation/private/qgeomappingmanager_p.h>
39 #include <QtLocation/private/qgeocameracapabilities_p.h>
40 
41 QT_USE_NAMESPACE
42 
43 Q_DECLARE_METATYPE(QGeoTiledMap::PrefetchStyle)
44 
45 class FetchTileCounter: public QObject
46 {
47     Q_OBJECT
48 public Q_SLOTS:
tileFetched(const QGeoTileSpec & spec)49     void tileFetched(const QGeoTileSpec& spec) {
50         m_tiles << spec;
51     }
52 public:
53     QSet<QGeoTileSpec> m_tiles;
54 };
55 
56 class tst_QGeoTiledMap : public QObject
57 {
58     Q_OBJECT
59 
60 public:
61     tst_QGeoTiledMap();
62     ~tst_QGeoTiledMap();
63 
64 private:
65     void waitForFetch(int count);
66 
67 private Q_SLOTS:
68     void initTestCase();
69     void fetchTiles();
70     void fetchTiles_data();
71 
72 private:
73     QScopedPointer<QGeoTiledMapTest> m_map;
74     QScopedPointer<FetchTileCounter> m_tilesCounter;
75     QGeoTileFetcherTest *m_fetcher;
76 
77 };
78 
tst_QGeoTiledMap()79 tst_QGeoTiledMap::tst_QGeoTiledMap():
80     m_fetcher(0)
81 {
82 }
83 
~tst_QGeoTiledMap()84 tst_QGeoTiledMap::~tst_QGeoTiledMap()
85 {
86 }
87 
initTestCase()88 void tst_QGeoTiledMap::initTestCase()
89 {
90 #if QT_CONFIG(library)
91     // Set custom path since CI doesn't install test plugins
92 #ifdef Q_OS_WIN
93     QCoreApplication::addLibraryPath(QCoreApplication::applicationDirPath() +
94                                      QStringLiteral("/../../../../plugins"));
95 #else
96     QCoreApplication::addLibraryPath(QCoreApplication::applicationDirPath() +
97                                      QStringLiteral("/../../../plugins"));
98 #endif
99 #endif
100       QVariantMap parameters;
101       parameters["tileSize"] = 256;
102       parameters["maxZoomLevel"] = 8;
103       parameters["finishRequestImmediately"] = true;
104       QGeoServiceProvider *provider = new QGeoServiceProvider("qmlgeo.test.plugin",parameters);
105       provider->setAllowExperimental(true);
106       QGeoMappingManager *mappingManager = provider->mappingManager();
107       QVERIFY2(provider->error() == QGeoServiceProvider::NoError, "Could not load plugin: " + provider->errorString().toLatin1());
108       m_map.reset(static_cast<QGeoTiledMapTest*>(mappingManager->createMap(this)));
109       QVERIFY(m_map);
110       m_map->setViewportSize(QSize(256, 256));
111       m_map->setActiveMapType(m_map->m_engine->supportedMapTypes().first());
112       m_fetcher = static_cast<QGeoTileFetcherTest*>(m_map->m_engine->tileFetcher());
113       m_tilesCounter.reset(new FetchTileCounter());
114       connect(m_fetcher, SIGNAL(tileFetched(const QGeoTileSpec&)), m_tilesCounter.data(), SLOT(tileFetched(const QGeoTileSpec&)));
115 }
116 
fetchTiles()117 void tst_QGeoTiledMap::fetchTiles()
118 {
119     QFETCH(double, zoomLevel);
120     QFETCH(int, visibleCount);
121     QFETCH(int, prefetchCount);
122     QFETCH(QGeoTiledMap::PrefetchStyle, style);
123     QFETCH(int, nearestNeighbourLayer);
124 
125     m_map->setPrefetchStyle(style);
126 
127     QGeoCameraData camera;
128     camera.setCenter(QWebMercator::mercatorToCoord(QDoubleVector2D( 0.5 ,  0.5 )));
129 
130     //prev_visible
131     camera.setZoomLevel(zoomLevel-1);
132     // Delay needed on slow targets (e.g. Qemu)
133     QTest::qWait(10);
134     m_map->clearData();
135     m_tilesCounter->m_tiles.clear();
136     m_map->setCameraData(camera);
137     waitForFetch(visibleCount);
138     QSet<QGeoTileSpec> prev_visible = m_tilesCounter->m_tiles;
139 
140     //visible + prefetch
141     camera.setZoomLevel(zoomLevel);
142     // Delay needed on slow targets (e.g. Qemu)
143     QTest::qWait(10);
144     m_map->clearData();
145     m_tilesCounter->m_tiles.clear();
146     m_map->setCameraData(camera);
147     waitForFetch(visibleCount);
148     const QSet<QGeoTileSpec> visible = m_tilesCounter->m_tiles;
149     m_map->clearData();
150     m_tilesCounter->m_tiles.clear();
151     m_map->prefetchData();
152     waitForFetch(prefetchCount);
153     QSet<QGeoTileSpec> prefetched = m_tilesCounter->m_tiles;
154 
155     //next visible
156     camera.setZoomLevel(zoomLevel + 1);
157     // Delay needed on slow targets (e.g. Qemu)
158     QTest::qWait(10);
159     m_map->clearData();
160     m_tilesCounter->m_tiles.clear();
161     m_map->setCameraData(camera);
162     waitForFetch(visibleCount);
163     QSet<QGeoTileSpec> next_visible = m_tilesCounter->m_tiles;
164 
165     QVERIFY2(visibleCount == visible.size(), "visible count incorrect");
166     QVERIFY2(prefetchCount == prefetched.size(), "prefetch count incorrect");
167     for (const QGeoTileSpec &tile : visible)
168         QVERIFY2(prefetched.contains(tile),"visible tile missing from prefetched tiles");
169 
170     //for zoomLevels wihtout fractions more tiles are fetched for current zoomlevel due to ViewExpansion
171     if (qCeil(zoomLevel) != zoomLevel && style == QGeoTiledMap::PrefetchNeighbourLayer && nearestNeighbourLayer < zoomLevel)
172         QVERIFY2(prefetched == prev_visible + visible, "wrongly prefetched tiles");
173 
174     if (qCeil(zoomLevel) != zoomLevel && style == QGeoTiledMap::PrefetchNeighbourLayer && nearestNeighbourLayer > zoomLevel)
175         QVERIFY2(prefetched == next_visible + visible, "wrongly prefetched tiles");
176 
177     if (qCeil(zoomLevel) != zoomLevel && style == QGeoTiledMap::PrefetchTwoNeighbourLayers)
178         QVERIFY2(prefetched == prev_visible + visible + next_visible, "wrongly prefetched tiles");
179 }
180 
fetchTiles_data()181 void tst_QGeoTiledMap::fetchTiles_data()
182 {
183     QTest::addColumn<double>("zoomLevel");
184     QTest::addColumn<int>("visibleCount");
185     QTest::addColumn<int>("prefetchCount");
186     QTest::addColumn<QGeoTiledMap::PrefetchStyle>("style");
187     QTest::addColumn<int>("nearestNeighbourLayer");
188     QTest::newRow("zoomLevel: 4 , visible count: 4 : prefetch count: 16") << 4.0 << 4 << 4 + 16 << QGeoTiledMap::PrefetchNeighbourLayer << 3;
189     QTest::newRow("zoomLevel: 4.06 , visible count: 4 : prefetch count: 4") << 4.06 << 4 << 4 + 4 << QGeoTiledMap::PrefetchNeighbourLayer << 3;
190     QTest::newRow("zoomLevel: 4.1 , visible count: 4 : prefetch count: 4") << 4.1 << 4 << 4 + 4 << QGeoTiledMap::PrefetchNeighbourLayer << 3;
191     QTest::newRow("zoomLevel: 4.5 , visible count: 4 : prefetch count: 4") << 4.5 << 4 << 4 + 4 << QGeoTiledMap::PrefetchNeighbourLayer << 3;
192     QTest::newRow("zoomLevel: 4.6 , visible count: 4 : prefetch count: 4") << 4.6 << 4 << 4 + 4 << QGeoTiledMap::PrefetchNeighbourLayer << 5;
193     QTest::newRow("zoomLevel: 4.9 , visible count: 4 : prefetch count: 4") << 4.9 << 4 <<4 + 4 << QGeoTiledMap::PrefetchNeighbourLayer << 5;
194     QTest::newRow("zoomLevel: 4 , visible count: 4 : prefetch count: 4") << 4.0 << 4 << 16 + 4 + 4 << QGeoTiledMap::PrefetchTwoNeighbourLayers << 3;
195     QTest::newRow("zoomLevel: 4.1 , visible count: 4 : prefetch count: 4") << 4.1 << 4 << 4 + 4 + 4 << QGeoTiledMap::PrefetchTwoNeighbourLayers << 3;
196     QTest::newRow("zoomLevel: 4.6 ,visible count: 4 : prefetch count: 4") << 4.6 << 4 << 4 + 4  + 4 << QGeoTiledMap::PrefetchTwoNeighbourLayers << 5;
197 }
198 
waitForFetch(int count)199 void tst_QGeoTiledMap::waitForFetch(int count)
200 {
201     int timeout = 0;
202     while (m_tilesCounter->m_tiles.count() < count && timeout < count) {
203         //250ms for each tile fetch
204         QTest::qWait(250);
205         timeout++;
206     }
207 }
208 
209 QTEST_MAIN(tst_QGeoTiledMap)
210 
211 #include "tst_qgeotiledmap.moc"
212