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