Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qgeotilefetcher.cpp
Go to the documentation of this file.
1// Copyright (C) 2015 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
5#include <QtCore/QTimerEvent>
6
12#include "qgeotilespec_p.h"
13#include "qgeotiledmap_p.h"
14
15#include <algorithm>
16#include <iterator>
17
18QT_BEGIN_NAMESPACE
19
20QGeoTileFetcher::QGeoTileFetcher(QGeoMappingManagerEngine *parent)
21: QObject(*new QGeoTileFetcherPrivate(), parent)
22{
23 Q_D(QGeoTileFetcher);
24
25 d->enabled_ = true;
26 d->engine_ = parent;
27}
28
29QGeoTileFetcher::QGeoTileFetcher(QGeoTileFetcherPrivate &dd, QGeoMappingManagerEngine *parent)
30: QObject(dd,parent)
31{
32 Q_D(QGeoTileFetcher);
33 d->enabled_ = true;
34 d->engine_ = parent;
35}
36
37QGeoTileFetcher::~QGeoTileFetcher()
38{
39}
40
41void QGeoTileFetcher::updateTileRequests(const QSet<QGeoTileSpec> &tilesAdded,
42 const QSet<QGeoTileSpec> &tilesRemoved)
43{
44 Q_D(QGeoTileFetcher);
45
46 QMutexLocker ml(&d->queueMutex_);
47
48 cancelTileRequests(tilesRemoved);
49
50 std::copy(tilesAdded.cbegin(), tilesAdded.cend(), std::back_inserter(d->queue_));
51
52 if (d->enabled_ && initialized() && !d->queue_.isEmpty() && !d->timer_.isActive())
53 d->timer_.start(0, this);
54}
55
56void QGeoTileFetcher::cancelTileRequests(const QSet<QGeoTileSpec> &tiles)
57{
58 Q_D(QGeoTileFetcher);
59
60 typedef QSet<QGeoTileSpec>::const_iterator tile_iter;
61 // No need to lock: called only in updateTileRequests
62 tile_iter tile = tiles.constBegin();
63 tile_iter end = tiles.constEnd();
64 for (; tile != end; ++tile) {
65 QGeoTiledMapReply *reply = d->invmap_.value(*tile, 0);
66 if (reply) {
67 d->invmap_.remove(*tile);
68 reply->abort();
69 if (reply->isFinished())
70 reply->deleteLater();
71 }
72 d->queue_.removeAll(*tile);
73 }
74}
75
76void QGeoTileFetcher::requestNextTile()
77{
78 Q_D(QGeoTileFetcher);
79
80 QMutexLocker ml(&d->queueMutex_);
81
82 if (!d->enabled_)
83 return;
84
85 if (d->queue_.isEmpty())
86 return;
87
88 QGeoTileSpec ts = d->queue_.takeFirst();
89 if (d->queue_.isEmpty())
90 d->timer_.stop();
91
92 // Check against min/max zoom to prevent sending requests for not existing objects
93 const QGeoCameraCapabilities & cameraCaps = d->engine_->cameraCapabilities(ts.mapId());
94 // the ZL in QGeoTileSpec is relative to the native tile size of the provider.
95 // It gets denormalized in QGeoTiledMap.
96 if (ts.zoom() < cameraCaps.minimumZoomLevel() || ts.zoom() > cameraCaps.maximumZoomLevel() || !fetchingEnabled())
97 return;
98
99 QGeoTiledMapReply *reply = getTileImage(ts);
100 if (!reply)
101 return;
102
103 if (reply->isFinished()) {
104 handleReply(reply, ts);
105 } else {
106 connect(reply, &QGeoTiledMapReply::finished,
107 this, &QGeoTileFetcher::finished, Qt::QueuedConnection);
108
109 d->invmap_.insert(ts, reply);
110 }
111}
112
113void QGeoTileFetcher::finished()
114{
115 Q_D(QGeoTileFetcher);
116
117 QMutexLocker ml(&d->queueMutex_);
118
119 QGeoTiledMapReply *reply = qobject_cast<QGeoTiledMapReply *>(sender());
120 if (!reply)
121 return;
122
123 QGeoTileSpec spec = reply->tileSpec();
124
125 if (!d->invmap_.contains(spec)) {
126 reply->deleteLater();
127 return;
128 }
129
130 d->invmap_.remove(spec);
131
132 handleReply(reply, spec);
133}
134
135void QGeoTileFetcher::timerEvent(QTimerEvent *event)
136{
137 Q_D(QGeoTileFetcher);
138 if (event->timerId() != d->timer_.timerId()) {
139 QObject::timerEvent(event);
140 return;
141 }
142
143 QMutexLocker ml(&d->queueMutex_);
144 if (d->queue_.isEmpty() || !initialized()) {
145 d->timer_.stop();
146 return;
147 }
148 ml.unlock();
149
150 requestNextTile();
151}
152
153bool QGeoTileFetcher::initialized() const
154{
155 return true;
156}
157
158bool QGeoTileFetcher::fetchingEnabled() const
159{
160 return true;
161}
162
163void QGeoTileFetcher::handleReply(QGeoTiledMapReply *reply, const QGeoTileSpec &spec)
164{
165 Q_D(QGeoTileFetcher);
166
167 if (!d->enabled_) {
168 reply->deleteLater();
169 return;
170 }
171
172 if (reply->error() == QGeoTiledMapReply::NoError) {
173 emit tileFinished(spec, reply->mapImageData(), reply->mapImageFormat());
174 } else {
175 emit tileError(spec, reply->errorString());
176 }
177
178 reply->deleteLater();
179}
180
181/*******************************************************************************
182*******************************************************************************/
183
184QT_END_NAMESPACE