Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qgeotiledmap.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#include "qgeotiledmap_p.h"
4#include "qgeotiledmap_p_p.h"
7#include "qgeotilespec_p.h"
8#include "qgeoprojection_p.h"
9
10#include "qgeocameratiles_p.h"
12#include "qgeotiledmapscene_p.h"
14#include <cmath>
15
17#define PREFETCH_FRUSTUM_SCALE 2.0
18
20 : QGeoMap(*new QGeoTiledMapPrivate(engine), parent)
21{
22 Q_D(QGeoTiledMap);
23
24 d->m_tileRequests = new QGeoTileRequestManager(this, engine);
25
27 this,&QGeoTiledMap::handleTileVersionChanged);
29 [d](const QGeoCameraCapabilities &oldCameraCapabilities) {
30 d->onCameraCapabilitiesChanged(oldCameraCapabilities);
31 });
32}
33
35 : QGeoMap(dd, parent)
36{
37 Q_D(QGeoTiledMap);
38
39 d->m_tileRequests = new QGeoTileRequestManager(this, engine);
40
42 this,&QGeoTiledMap::handleTileVersionChanged);
44 [d](const QGeoCameraCapabilities &oldCameraCapabilities) {
45 d->onCameraCapabilitiesChanged(oldCameraCapabilities);
46 });
47}
48
50{
51 Q_D(QGeoTiledMap);
52 delete d->m_tileRequests;
53 d->m_tileRequests = nullptr;
54
55 if (!d->m_engine.isNull()) {
56 QGeoTiledMappingManagerEngine *engine = qobject_cast<QGeoTiledMappingManagerEngine*>(d->m_engine);
58 engine->releaseMap(this);
59 }
60}
61
63{
64 Q_D(QGeoTiledMap);
65 return d->m_tileRequests;
66}
67
69{
70 Q_D(QGeoTiledMap);
71 d->updateTile(spec);
72}
73
75{
76 Q_D(QGeoTiledMap);
77 d->m_prefetchStyle = style;
78}
79
81{
82 Q_D(QGeoTiledMap);
83 return d->m_cache;
84}
85
87{
88 Q_D(QGeoTiledMap);
89 return d->updateSceneGraph(oldNode, window);
90}
91
93{
94 Q_D(QGeoTiledMap);
95 d->prefetchTiles();
96}
97
99{
100 Q_D(QGeoTiledMap);
101 d->m_cache->clearAll();
102 d->m_mapScene->clearTexturedTiles();
103 d->updateScene();
105}
106
107QGeoMap::Capabilities QGeoTiledMap::capabilities() const
108{
109 return Capabilities(SupportsVisibleRegion
113}
114
116{
117 Q_D(QGeoTiledMap);
118 if (visible == d->m_copyrightVisible)
119 return;
120
122 if (visible)
123 evaluateCopyrights(d->m_mapScene->visibleTiles());
124}
125
127{
128 Q_D(QGeoTiledMap);
129 if (activeMapType().mapId() == mapId)
130 d->clearScene();
131}
132
133void QGeoTiledMap::handleTileVersionChanged()
134{
135 Q_D(QGeoTiledMap);
136 if (!d->m_engine.isNull()) {
137 QGeoTiledMappingManagerEngine* engine = qobject_cast<QGeoTiledMappingManagerEngine*>(d->m_engine);
139 d->changeTileVersion(engine->tileVersion());
140 }
141}
142
143void QGeoTiledMap::evaluateCopyrights(const QSet<QGeoTileSpec> &visibleTiles)
144{
145 Q_UNUSED(visibleTiles);
146}
147
150 m_cache(engine->tileCache()),
151 m_visibleTiles(new QGeoCameraTiles()),
152 m_prefetchTiles(new QGeoCameraTiles()),
153 m_mapScene(new QGeoTiledMapScene()),
154 m_tileRequests(nullptr),
155 m_maxZoomLevel(static_cast<int>(std::ceil(m_cameraCapabilities.maximumZoomLevel()))),
156 m_minZoomLevel(static_cast<int>(std::ceil(m_cameraCapabilities.minimumZoomLevel()))),
157 m_prefetchStyle(QGeoTiledMap::PrefetchTwoNeighbourLayers)
158{
160 QString pluginString(engine->managerName() + QLatin1Char('_') + QString::number(engine->managerVersion()));
163 m_visibleTiles->setPluginString(pluginString);
164 m_prefetchTiles->setPluginString(pluginString);
166}
167
169{
170 // controller_ is a child of map_, don't need to delete it here
171
172 delete m_mapScene;
173 delete m_visibleTiles;
174 delete m_prefetchTiles;
175
176 // TODO map items are not deallocated!
177 // However: how to ensure this is done in rendering thread?
178}
179
181{
183
184 QSet<QGeoTileSpec> tiles;
186 int currentIntZoom = static_cast<int>(std::floor(camera.zoomLevel()));
187
190 tiles = m_prefetchTiles->createTiles();
191
192 switch (m_prefetchStyle) {
193
195 double zoomFraction = camera.zoomLevel() - currentIntZoom;
196 int nearestNeighbourLayer = zoomFraction > 0.5 ? currentIntZoom + 1 : currentIntZoom - 1;
197 if (nearestNeighbourLayer <= m_maxZoomLevel && nearestNeighbourLayer >= m_minZoomLevel) {
198 camera.setZoomLevel(nearestNeighbourLayer);
199 // Approx heuristic, keeping total # prefetched tiles roughly independent of the
200 // fractional zoom level.
201 double neighbourScale = (1.0 + zoomFraction)/2.0;
204 tiles += m_prefetchTiles->createTiles();
205 }
206 }
207 break;
208
210 // This is a simpler strategy, we just prefetch from layer above and below
211 // for the layer below we only use half the size as this fills the screen
212 if (currentIntZoom > m_minZoomLevel) {
213 camera.setZoomLevel(currentIntZoom - 1);
216 tiles += m_prefetchTiles->createTiles();
217 }
218
219 if (currentIntZoom < m_maxZoomLevel) {
220 camera.setZoomLevel(currentIntZoom + 1);
223 tiles += m_prefetchTiles->createTiles();
224 }
225 }
226 break;
227
228 default:
229 break;
230 }
231
233 }
234}
235
240
241// Called before changeCameraData
243{
244 // Handle varying min/maxZoomLevel
245 if (oldCameraCapabilities.minimumZoomLevel() != m_cameraCapabilities.minimumZoomLevel())
246 m_minZoomLevel = static_cast<int>(std::ceil(m_cameraCapabilities.minimumZoomLevel()));
247 if (oldCameraCapabilities.maximumZoomLevel() != m_cameraCapabilities.maximumZoomLevel())
248 m_maxZoomLevel = static_cast<int>(std::ceil(m_cameraCapabilities.maximumZoomLevel()));
249
250 // Handle varying tile size
251 if (oldCameraCapabilities.tileSize() != m_cameraCapabilities.tileSize()) {
252 m_visibleTiles->setTileSize(oldCameraCapabilities.tileSize());
253 m_prefetchTiles->setTileSize(oldCameraCapabilities.tileSize());
254 m_mapScene->setTileSize(oldCameraCapabilities.tileSize());
255 }
256}
257
259{
260 Q_Q(QGeoTiledMap);
261
262 QGeoCameraData cam = cameraData;
263
264 // The incoming zoom level is intended for a tileSize of 256.
265 // Adapt it to the current tileSize
266 double zoomLevel = cameraData.zoomLevel();
267 if (m_visibleTiles->tileSize() != 256)
268 zoomLevel = std::log(std::pow(2.0, zoomLevel) * 256.0 / m_visibleTiles->tileSize()) * (1.0 / std::log(2.0));
269 cam.setZoomLevel(zoomLevel);
270
271 // For zoomlevel, "snap" 0.01 either side of a whole number.
272 // This is so that when we turn off bilinear scaling, we're
273 // snapped to the exact pixel size of the tiles
274 int izl = static_cast<int>(std::floor(cam.zoomLevel()));
275 float delta = cam.zoomLevel() - izl;
276
277 if (delta > 0.5) {
278 izl++;
279 delta -= 1.0;
280 }
281
282 // TODO: Don't do this if there's tilt or bearing.
283 if (qAbs(delta) < 0.01) {
284 cam.setZoomLevel(izl);
285 }
286
289
290 updateScene();
291 q->sgNodeChanged(); // ToDo: explain why emitting twice
292}
293
295{
296 Q_Q(QGeoTiledMap);
297 // detect if new tiles introduced
298 const QSet<QGeoTileSpec>& tiles = m_visibleTiles->createTiles();
299 bool newTilesIntroduced = !m_mapScene->visibleTiles().contains(tiles);
301
302 if (newTilesIntroduced && m_copyrightVisible)
303 q->evaluateCopyrights(tiles);
304
305 // don't request tiles that are already built and textured
306 QMap<QGeoTileSpec, QSharedPointer<QGeoTileTexture> > cachedTiles =
308
309 for (auto it = cachedTiles.cbegin(); it != cachedTiles.cend(); ++it)
310 m_mapScene->addTile(it.key(), it.value());
311
312 if (!cachedTiles.isEmpty())
313 emit q->sgNodeChanged();
314}
315
317{
318 Q_Q(QGeoTiledMap);
320 if (va == m_visibleArea)
321 return;
322
323 m_visibleArea = va;
325
329
331 q->evaluateCopyrights(m_mapScene->visibleTiles());
332 updateScene();
333 q->sgNodeChanged(); // ToDo: explain why emitting twice
334}
335
340
342{
346 m_visibleTiles->setMapType(mapType);
347 m_prefetchTiles->setMapType(mapType);
348 changeCameraData(m_cameraData); // Updates the zoom level to the possibly new tile size
349 // updateScene called in changeCameraData()
350}
351
358
360{
362 m_mapScene->setVisibleTiles(QSet<QGeoTileSpec>());
363 updateScene();
364}
365
367{
368 Q_Q(QGeoTiledMap);
369
373
374
375 if (!size.isEmpty() && m_cache) {
376 // absolute minimum size: one tile each side of display, 32-bit colour
377 int texCacheSize = (size.width() + m_visibleTiles->tileSize() * 2) *
378 (size.height() + m_visibleTiles->tileSize() * 2) * 4;
379
380 // multiply by 3 so the 'recent' list in the cache is big enough for
381 // an entire display of tiles
382 texCacheSize *= 3;
383 // TODO: move this reasoning into the tilecache
384
385 int newSize = qMax(m_cache->minTextureUsage(), texCacheSize);
386 m_cache->setMinTextureUsage(newSize);
387 }
388
390 q->evaluateCopyrights(m_mapScene->visibleTiles());
391 updateScene();
392}
393
395{
396 Q_Q(QGeoTiledMap);
397 // Only promote the texture up to GPU if it is visible
398 if (m_visibleTiles->createTiles().contains(spec)){
399 QSharedPointer<QGeoTileTexture> tex = m_tileRequests->tileTexture(spec);
400 if (!tex.isNull() && !tex->image.isNull()) {
401 m_mapScene->addTile(spec, tex);
402 emit q->sgNodeChanged();
403 }
404 }
405}
406
411
virtual void setMinTextureUsage(int textureUsage)=0
virtual int minTextureUsage() const =0
qreal minimumZoomLevel
\qmlproperty qreal cameraCapabilities::minimumZoomLevel
qreal maximumZoomLevel
\qmlproperty qreal cameraCapabilities::maximumZoomLevel
double zoomLevel() const
void setMapType(const QGeoMapType &mapType)
const QSet< QGeoTileSpec > & createTiles()
void setMapVersion(int mapVersion)
QGeoCameraData cameraData() const
QGeoMapType activeMapType() const
void setScreenSize(const QSize &size)
void setViewExpansion(double viewExpansion)
void setTileSize(int tileSize)
void setCameraData(const QGeoCameraData &camera)
void setPluginString(const QString &pluginString)
void setVisibleArea(const QRectF &visibleArea)
QGeoProjection * m_geoProjection
Definition qgeomap_p_p.h:78
QRectF clampVisibleArea(const QRectF &visibleArea) const
Definition qgeomap.cpp:364
QGeoCameraCapabilities m_cameraCapabilities
Definition qgeomap_p_p.h:83
QGeoCameraData m_cameraData
Definition qgeomap_p_p.h:80
bool m_copyrightVisible
Definition qgeomap_p_p.h:84
@ SupportsVisibleArea
Definition qgeomap_p.h:64
@ SupportsVisibleRegion
Definition qgeomap_p.h:60
@ SupportsAnchoringCoordinate
Definition qgeomap_p.h:62
@ SupportsSetBearing
Definition qgeomap_p.h:61
void sgNodeChanged()
virtual void setCopyrightVisible(bool visible)
Definition qgeomap.cpp:258
QGeoMapType activeMapType() const
Definition qgeomap.cpp:128
void cameraCapabilitiesChanged(const QGeoCameraCapabilities &oldCameraCapabilities)
virtual void setVisibleArea(const QRectF &visibleArea)=0
QMap< QGeoTileSpec, QSharedPointer< QGeoTileTexture > > requestTiles(const QSet< QGeoTileSpec > &tiles)
QSharedPointer< QGeoTileTexture > tileTexture(const QGeoTileSpec &spec)
void changeTileVersion(int version)
void changeViewportSize(const QSize &size) override
QRectF visibleArea() const override
QGeoTiledMapPrivate(QGeoTiledMappingManagerEngine *engine)
void changeActiveMapType(const QGeoMapType &mapType) override
void changeCameraData(const QGeoCameraData &cameraData) override
QGeoCameraTiles * m_visibleTiles
void updateTile(const QGeoTileSpec &spec)
void onCameraCapabilitiesChanged(const QGeoCameraCapabilities &oldCameraCapabilities)
QGeoCameraTiles * m_prefetchTiles
QGeoTiledMap::PrefetchStyle m_prefetchStyle
QGeoTileRequestManager * m_tileRequests
QGeoMapType activeMapType() const
void setVisibleArea(const QRectF &visibleArea) override
QAbstractGeoTileCache * m_cache
QGeoTiledMapScene * m_mapScene
QSGNode * updateSceneGraph(QSGNode *node, QQuickWindow *window)
const QSet< QGeoTileSpec > & visibleTiles() const
void setCameraData(const QGeoCameraData &cameraData)
void setScreenSize(const QSize &size)
void addTile(const QGeoTileSpec &spec, QSharedPointer< QGeoTileTexture > texture)
QSet< QGeoTileSpec > texturedTiles()
void setVisibleTiles(const QSet< QGeoTileSpec > &tiles)
QSGNode * updateSceneGraph(QSGNode *oldNode, QQuickWindow *window)
void setTileSize(int tileSize)
void setVisibleArea(const QRectF &visibleArea)
QGeoTileRequestManager * requestManager()
void clearData() override
void setCopyrightVisible(bool visible) override
void updateTile(const QGeoTileSpec &spec)
virtual ~QGeoTiledMap()
void prefetchData() override
QAbstractGeoTileCache * tileCache()
virtual void evaluateCopyrights(const QSet< QGeoTileSpec > &visibleTiles)
QSGNode * updateSceneGraph(QSGNode *, QQuickWindow *window) override
Capabilities capabilities() const override
QGeoTiledMap(QGeoTiledMappingManagerEngine *engine, QObject *parent)
void setPrefetchStyle(PrefetchStyle style)
virtual void clearScene(int mapId)
\inmodule QtCore
Definition qobject.h:103
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2960
\qmltype Window \instantiates QQuickWindow \inqmlmodule QtQuick
\inmodule QtCore\reentrant
Definition qrect.h:484
\group qtquick-scenegraph-nodes \title Qt Quick Scene Graph Node classes
Definition qsgnode.h:37
const_iterator cend() const noexcept
Definition qset.h:142
bool contains(const T &value) const
Definition qset.h:71
const_iterator cbegin() const noexcept
Definition qset.h:138
\inmodule QtCore
Definition qsize.h:25
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:8084
QCamera * camera
Definition camera.cpp:19
QSet< QString >::iterator it
Combined button and popup list for selecting options.
#define PREFETCH_FRUSTUM_SCALE
static QT_BEGIN_NAMESPACE const int tileSize
Definition qmemrotate.cpp:9
constexpr const T & qMax(const T &a, const T &b)
Definition qminmax.h:42
constexpr T qAbs(const T &t)
Definition qnumeric.h:328
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
#define emit
#define Q_UNUSED(x)
QObject::connect nullptr
aWidget window() -> setWindowTitle("New Window Title")
[2]
QJSEngine engine
[0]
\inmodule QtCore \reentrant
Definition qchar.h:18