summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/location/maps/qgeocameratiles.cpp85
-rw-r--r--src/location/maps/qgeocameratiles_p.h11
-rw-r--r--src/location/maps/qgeomapscene.cpp6
-rw-r--r--src/location/maps/qgeomapscene_p.h2
-rw-r--r--src/location/maps/qgeotiledmap.cpp112
-rw-r--r--src/location/maps/qgeotiledmap_p.h3
-rw-r--r--src/location/maps/qgeotiledmap_p_p.h5
7 files changed, 121 insertions, 103 deletions
diff --git a/src/location/maps/qgeocameratiles.cpp b/src/location/maps/qgeocameratiles.cpp
index d2783a5b..5eae7c0b 100644
--- a/src/location/maps/qgeocameratiles.cpp
+++ b/src/location/maps/qgeocameratiles.cpp
@@ -49,7 +49,6 @@
#include <cmath>
QT_BEGIN_NAMESPACE
-#define PREFETCH_FRUSTUM_SCALE 2.0
struct Frustum
{
@@ -77,7 +76,6 @@ public:
QGeoCameraData m_camera;
QSize m_screenSize;
int m_tileSize;
- int m_maxZoom;
QSet<QGeoTileSpec> m_tiles;
int m_intZoomLevel;
@@ -86,8 +84,9 @@ public:
bool m_dirtyGeometry;
bool m_dirtyMetadata;
+ double m_viewExpansion;
void updateMetadata();
- void updateGeometry(double viewExpansion = 1.0);
+ void updateGeometry();
Frustum createFrustum(double fieldOfViewGradient) const;
@@ -127,58 +126,6 @@ QGeoCameraTiles::~QGeoCameraTiles()
{
}
-QSet<QGeoTileSpec> QGeoCameraTiles::prefetchTiles(PrefetchStle style)
-{
- int currentIntZoom = static_cast<int>(std::floor(d_ptr->m_camera.zoomLevel()));
- double currentFloatZoom = d_ptr->m_camera.zoomLevel();
-
- d_ptr->m_tiles.clear();
- d_ptr->m_intZoomLevel = currentIntZoom;
- d_ptr->m_sideLength = 1 << d_ptr->m_intZoomLevel ;
- d_ptr->updateGeometry(PREFETCH_FRUSTUM_SCALE);
-
- switch (style) {
-
- case PrefetchNeighbourLayer: {
-
- double zoomFraction = d_ptr->m_camera.zoomLevel() - currentIntZoom;
- int nearestNeighbourLayer = zoomFraction > 0.5 ? currentIntZoom + 1 : currentIntZoom - 1;
- if (nearestNeighbourLayer <= d_ptr->m_maxZoom && nearestNeighbourLayer >= 0) {
- d_ptr->m_intZoomLevel = nearestNeighbourLayer;
- d_ptr->m_sideLength = 1 << d_ptr->m_intZoomLevel;
- d_ptr->m_camera.setZoomLevel(d_ptr->m_intZoomLevel);
- // Approx heuristic, keeping total # prefetched tiles roughly independent of the
- // fractional zoom level.
- double neighbourScale = (1.0 + zoomFraction)/2.0;
- d_ptr->updateGeometry(PREFETCH_FRUSTUM_SCALE * neighbourScale);
- }
- break;
- }
-
- case PrefetchTwoNeighbourLayers: {
- // This is a simpler strategy, we just prefetch from layer above and below
- // for the layer below we only use half the size as this fills the screen
- if (currentIntZoom > 0) {
- d_ptr->m_intZoomLevel = currentIntZoom - 1;
- d_ptr->m_sideLength = 1 << d_ptr->m_intZoomLevel;
- d_ptr->m_camera.setZoomLevel(d_ptr->m_intZoomLevel);
- d_ptr->updateGeometry(0.5);
- }
- if (currentIntZoom < d_ptr->m_maxZoom) {
- d_ptr->m_intZoomLevel = currentIntZoom + 1;
- d_ptr->m_sideLength = 1 << d_ptr->m_intZoomLevel;
- d_ptr->m_camera.setZoomLevel(d_ptr->m_intZoomLevel);
- d_ptr->updateGeometry(1.0);
- }
- }
- }
-
- d_ptr->m_intZoomLevel = currentIntZoom;
- d_ptr->m_sideLength = 1 << d_ptr->m_intZoomLevel;
- d_ptr->m_camera.setZoomLevel(currentFloatZoom);
- return d_ptr->m_tiles;
-}
-
void QGeoCameraTiles::setCameraData(const QGeoCameraData &camera)
{
if (d_ptr->m_camera == camera)
@@ -190,6 +137,11 @@ void QGeoCameraTiles::setCameraData(const QGeoCameraData &camera)
d_ptr->m_sideLength = 1 << d_ptr->m_intZoomLevel;
}
+QGeoCameraData QGeoCameraTiles::cameraData() const
+{
+ return d_ptr->m_camera;
+}
+
void QGeoCameraTiles::setScreenSize(const QSize &size)
{
if (d_ptr->m_screenSize == size)
@@ -235,21 +187,18 @@ void QGeoCameraTiles::setTileSize(int tileSize)
d_ptr->m_tileSize = tileSize;
}
-int QGeoCameraTiles::tileSize() const
+void QGeoCameraTiles::setViewExpansion(double viewExpansion)
{
- return d_ptr->m_tileSize;
+ d_ptr->m_viewExpansion = viewExpansion;
+ d_ptr->m_dirtyGeometry = true;
}
-void QGeoCameraTiles::setMaximumZoomLevel(int maxZoom)
+int QGeoCameraTiles::tileSize() const
{
- if (d_ptr->m_maxZoom == maxZoom)
- return;
-
- d_ptr->m_dirtyGeometry = true;
- d_ptr->m_maxZoom = maxZoom;
+ return d_ptr->m_tileSize;
}
-const QSet<QGeoTileSpec>& QGeoCameraTiles::visibleTiles()
+const QSet<QGeoTileSpec>& QGeoCameraTiles::createTiles()
{
if (d_ptr->m_dirtyGeometry) {
d_ptr->m_tiles.clear();
@@ -268,11 +217,11 @@ const QSet<QGeoTileSpec>& QGeoCameraTiles::visibleTiles()
QGeoCameraTilesPrivate::QGeoCameraTilesPrivate()
: m_mapVersion(-1),
m_tileSize(0),
- m_maxZoom(0),
m_intZoomLevel(0),
m_sideLength(0),
m_dirtyGeometry(false),
- m_dirtyMetadata(false)
+ m_dirtyMetadata(false),
+ m_viewExpansion(1.0)
{
}
@@ -295,11 +244,11 @@ void QGeoCameraTilesPrivate::updateMetadata()
m_tiles = newTiles;
}
-void QGeoCameraTilesPrivate::updateGeometry(double viewExpansion)
+void QGeoCameraTilesPrivate::updateGeometry()
{
// Find the frustum from the camera / screen / viewport information
// The larger frustum when stationary is a form of prefetching
- Frustum f = createFrustum(viewExpansion);
+ Frustum f = createFrustum(m_viewExpansion);
// Find the polygon where the frustum intersects the plane of the map
PolygonVector footprint = frustumFootprint(f);
diff --git a/src/location/maps/qgeocameratiles_p.h b/src/location/maps/qgeocameratiles_p.h
index e133f8e6..d10895f8 100644
--- a/src/location/maps/qgeocameratiles_p.h
+++ b/src/location/maps/qgeocameratiles_p.h
@@ -63,21 +63,16 @@ public:
QGeoCameraTiles();
~QGeoCameraTiles();
- enum PrefetchStle { PrefetchNeighbourLayer, PrefetchTwoNeighbourLayers};
-
void setCameraData(const QGeoCameraData &camera);
+ QGeoCameraData cameraData() const;
void setScreenSize(const QSize &size);
void setTileSize(int tileSize);
- void setMaximumZoomLevel(int maxZoom);
-
int tileSize() const;
-
+ void setViewExpansion(double viewExpansion);
void setPluginString(const QString &pluginString);
void setMapType(const QGeoMapType &mapType);
void setMapVersion(int mapVersion);
-
- const QSet<QGeoTileSpec>& visibleTiles();
- QSet<QGeoTileSpec> prefetchTiles(PrefetchStle style);
+ const QSet<QGeoTileSpec>& createTiles();
protected:
QScopedPointer<QGeoCameraTilesPrivate> d_ptr;
diff --git a/src/location/maps/qgeomapscene.cpp b/src/location/maps/qgeomapscene.cpp
index 4a457005..450be60b 100644
--- a/src/location/maps/qgeomapscene.cpp
+++ b/src/location/maps/qgeomapscene.cpp
@@ -196,6 +196,12 @@ QSet<QGeoTileSpec> QGeoMapScene::texturedTiles()
return textured;
}
+void QGeoMapScene::clearTexturedTiles()
+{
+ Q_D(QGeoMapScene);
+ d->m_textures.clear();
+}
+
QGeoMapScenePrivate::QGeoMapScenePrivate()
: QObjectPrivate(),
m_tileSize(0),
diff --git a/src/location/maps/qgeomapscene_p.h b/src/location/maps/qgeomapscene_p.h
index 34d4a11f..c38612bc 100644
--- a/src/location/maps/qgeomapscene_p.h
+++ b/src/location/maps/qgeomapscene_p.h
@@ -87,6 +87,8 @@ public:
bool verticalLock() const;
QSet<QGeoTileSpec> texturedTiles();
+ void clearTexturedTiles();
+
Q_SIGNALS:
void newTilesVisible(const QSet<QGeoTileSpec> &newTiles);
diff --git a/src/location/maps/qgeotiledmap.cpp b/src/location/maps/qgeotiledmap.cpp
index 97747049..7a56c548 100644
--- a/src/location/maps/qgeotiledmap.cpp
+++ b/src/location/maps/qgeotiledmap.cpp
@@ -47,7 +47,7 @@
#include <cmath>
QT_BEGIN_NAMESPACE
-
+#define PREFETCH_FRUSTUM_SCALE 2.0
QGeoTiledMap::QGeoTiledMap(QGeoTiledMappingManagerEngine *engine, QObject *parent)
: QGeoMap(*new QGeoTiledMapPrivate(engine), parent)
@@ -85,6 +85,12 @@ void QGeoTiledMap::updateTile(const QGeoTileSpec &spec)
d->updateTile(spec);
}
+void QGeoTiledMap::setPrefetchStyle(QGeoTiledMap::PrefetchStyle style)
+{
+ Q_D(QGeoTiledMap);
+ d->m_prefetchStyle = style;
+}
+
QAbstractGeoTileCache *QGeoTiledMap::tileCache()
{
Q_D(QGeoTiledMap);
@@ -107,6 +113,7 @@ void QGeoTiledMap::clearData()
{
Q_D(QGeoTiledMap);
d->m_cache->clearAll();
+ d->m_mapScene->clearTexturedTiles();
}
void QGeoTiledMap::handleTileVersionChanged()
@@ -157,14 +164,20 @@ QDoubleVector2D QGeoTiledMap::coordinateToItemPosition(const QGeoCoordinate &coo
QGeoTiledMapPrivate::QGeoTiledMapPrivate(QGeoTiledMappingManagerEngine *engine)
: QGeoMapPrivate(engine),
m_cache(engine->tileCache()),
- m_cameraTiles(new QGeoCameraTiles()),
+ m_visibleTiles(new QGeoCameraTiles()),
+ m_prefetchTiles(new QGeoCameraTiles()),
m_mapScene(new QGeoMapScene()),
- m_tileRequests(0)
+ m_tileRequests(0),
+ m_maxZoomLevel(static_cast<int>(std::ceil(engine->cameraCapabilities().maximumZoomLevel()))),
+ m_prefetchStyle(QGeoTiledMap::PrefetchTwoNeighbourLayers)
{
- m_cameraTiles->setMaximumZoomLevel(static_cast<int>(std::ceil(engine->cameraCapabilities().maximumZoomLevel())));
- m_cameraTiles->setTileSize(engine->tileSize().width());
- m_cameraTiles->setPluginString(engine->managerName() + QLatin1Char('_') + QString::number(engine->managerVersion()));
- m_mapScene->setTileSize(engine->tileSize().width());
+ int tileSize = engine->tileSize().width();
+ QString pluginString(engine->managerName() + QLatin1Char('_') + QString::number(engine->managerVersion()));
+ m_visibleTiles->setTileSize(tileSize);
+ m_prefetchTiles->setTileSize(tileSize);
+ m_visibleTiles->setPluginString(pluginString);
+ m_prefetchTiles->setPluginString(pluginString);
+ m_mapScene->setTileSize(tileSize);
}
QGeoTiledMapPrivate::~QGeoTiledMapPrivate()
@@ -172,17 +185,65 @@ QGeoTiledMapPrivate::~QGeoTiledMapPrivate()
// controller_ is a child of map_, don't need to delete it here
delete m_mapScene;
- delete m_cameraTiles;
+ delete m_visibleTiles;
+ delete m_prefetchTiles;
// TODO map items are not deallocated!
// However: how to ensure this is done in rendering thread?
}
+
void QGeoTiledMapPrivate::prefetchTiles()
{
- if (m_tileRequests)
- m_tileRequests->requestTiles(m_cameraTiles->prefetchTiles(QGeoCameraTiles::PrefetchTwoNeighbourLayers)
- - m_mapScene->texturedTiles());
+ if (m_tileRequests) {
+
+ QSet<QGeoTileSpec> tiles;
+ QGeoCameraData camera = m_visibleTiles->cameraData();
+ int currentIntZoom = static_cast<int>(std::floor(camera.zoomLevel()));
+
+ m_prefetchTiles->setCameraData(camera);
+ m_prefetchTiles->setViewExpansion(PREFETCH_FRUSTUM_SCALE);
+ tiles = m_prefetchTiles->createTiles();
+
+ switch (m_prefetchStyle) {
+
+ case QGeoTiledMap::PrefetchNeighbourLayer: {
+ double zoomFraction = camera.zoomLevel() - currentIntZoom;
+ int nearestNeighbourLayer = zoomFraction > 0.5 ? currentIntZoom + 1 : currentIntZoom - 1;
+ if (nearestNeighbourLayer <= m_maxZoomLevel && nearestNeighbourLayer >= 0) {
+ camera.setZoomLevel(nearestNeighbourLayer);
+ // Approx heuristic, keeping total # prefetched tiles roughly independent of the
+ // fractional zoom level.
+ double neighbourScale = (1.0 + zoomFraction)/2.0;
+ m_prefetchTiles->setCameraData(camera);
+ m_prefetchTiles->setViewExpansion(PREFETCH_FRUSTUM_SCALE * neighbourScale);
+ tiles += m_prefetchTiles->createTiles();
+ }
+ }
+ break;
+
+ case QGeoTiledMap::PrefetchTwoNeighbourLayers: {
+ // This is a simpler strategy, we just prefetch from layer above and below
+ // for the layer below we only use half the size as this fills the screen
+ if (currentIntZoom > 0) {
+ camera.setZoomLevel(currentIntZoom - 1);
+ m_prefetchTiles->setCameraData(camera);
+ m_prefetchTiles->setViewExpansion(0.5);
+ tiles += m_prefetchTiles->createTiles();
+ }
+
+ if (currentIntZoom < m_maxZoomLevel) {
+ camera.setZoomLevel(currentIntZoom + 1);
+ m_prefetchTiles->setCameraData(camera);
+ m_prefetchTiles->setViewExpansion(1.0);
+ tiles += m_prefetchTiles->createTiles();
+ }
+
+ }
+ }
+
+ m_tileRequests->requestTiles(tiles - m_mapScene->texturedTiles());
+ }
}
void QGeoTiledMapPrivate::changeCameraData(const QGeoCameraData &oldCameraData)
@@ -210,7 +271,7 @@ void QGeoTiledMapPrivate::changeCameraData(const QGeoCameraData &oldCameraData)
cam.setZoomLevel(izl);
}
- m_cameraTiles->setCameraData(cam);
+ m_visibleTiles->setCameraData(cam);
m_mapScene->setCameraData(cam);
updateScene();
}
@@ -219,7 +280,7 @@ void QGeoTiledMapPrivate::updateScene()
{
Q_Q(QGeoTiledMap);
// detect if new tiles introduced
- const QSet<QGeoTileSpec>& tiles = m_cameraTiles->visibleTiles();
+ const QSet<QGeoTileSpec>& tiles = m_visibleTiles->createTiles();
bool newTilesIntroduced = !m_mapScene->visibleTiles().contains(tiles);
m_mapScene->setVisibleTiles(tiles);
@@ -228,7 +289,7 @@ void QGeoTiledMapPrivate::updateScene()
// don't request tiles that are already built and textured
QList<QSharedPointer<QGeoTileTexture> > cachedTiles =
- m_tileRequests->requestTiles(m_cameraTiles->visibleTiles() - m_mapScene->texturedTiles());
+ m_tileRequests->requestTiles(m_visibleTiles->createTiles() - m_mapScene->texturedTiles());
foreach (const QSharedPointer<QGeoTileTexture> &tex, cachedTiles) {
m_mapScene->addTile(tex->spec, tex);
@@ -240,29 +301,30 @@ void QGeoTiledMapPrivate::updateScene()
void QGeoTiledMapPrivate::changeActiveMapType(const QGeoMapType mapType)
{
- m_cameraTiles->setMapType(mapType);
+ m_visibleTiles->setMapType(mapType);
+ m_prefetchTiles->setMapType(mapType);
}
void QGeoTiledMapPrivate::changeTileVersion(int version)
{
- m_cameraTiles->setMapVersion(version);
+ m_visibleTiles->setMapVersion(version);
+ m_prefetchTiles->setMapVersion(version);
updateScene();
}
void QGeoTiledMapPrivate::mapResized(int width, int height)
{
Q_Q(QGeoTiledMap);
- if (m_cameraTiles)
- m_cameraTiles->setScreenSize(QSize(width, height));
- if (m_mapScene)
- m_mapScene->setScreenSize(QSize(width, height));
+ m_visibleTiles->setScreenSize(QSize(width, height));
+ m_prefetchTiles->setScreenSize(QSize(width, height));
+ m_mapScene->setScreenSize(QSize(width, height));
if (q)
q->setCameraData(q->cameraData());
- if (width > 0 && height > 0 && m_cache && m_cameraTiles) {
+ if (width > 0 && height > 0 && m_cache) {
// absolute minimum size: one tile each side of display, 32-bit colour
- int texCacheSize = (width + m_cameraTiles->tileSize() * 2) *
- (height + m_cameraTiles->tileSize() * 2) * 4;
+ int texCacheSize = (width + m_visibleTiles->tileSize() * 2) *
+ (height + m_visibleTiles->tileSize() * 2) * 4;
// multiply by 3 so the 'recent' list in the cache is big enough for
// an entire display of tiles
@@ -272,14 +334,14 @@ void QGeoTiledMapPrivate::mapResized(int width, int height)
int newSize = qMax(m_cache->minTextureUsage(), texCacheSize);
m_cache->setMinTextureUsage(newSize);
}
- q->evaluateCopyrights(m_cameraTiles->visibleTiles());
+ q->evaluateCopyrights(m_visibleTiles->createTiles());
}
void QGeoTiledMapPrivate::updateTile(const QGeoTileSpec &spec)
{
Q_Q(QGeoTiledMap);
// Only promote the texture up to GPU if it is visible
- if (m_cameraTiles->visibleTiles().contains(spec)){
+ if (m_visibleTiles->createTiles().contains(spec)){
QSharedPointer<QGeoTileTexture> tex = m_tileRequests->tileTexture(spec);
if (!tex.isNull()) {
m_mapScene->addTile(spec, tex);
diff --git a/src/location/maps/qgeotiledmap_p.h b/src/location/maps/qgeotiledmap_p.h
index 87dac5d1..9e1d1596 100644
--- a/src/location/maps/qgeotiledmap_p.h
+++ b/src/location/maps/qgeotiledmap_p.h
@@ -74,14 +74,15 @@ class Q_LOCATION_EXPORT QGeoTiledMap : public QGeoMap
{
Q_OBJECT
Q_DECLARE_PRIVATE(QGeoTiledMap)
-
public:
+ enum PrefetchStyle { PrefetchNeighbourLayer, PrefetchTwoNeighbourLayers };
QGeoTiledMap(QGeoTiledMappingManagerEngine *engine, QObject *parent);
virtual ~QGeoTiledMap();
QAbstractGeoTileCache *tileCache();
QGeoTileRequestManager *requestManager();
void updateTile(const QGeoTileSpec &spec);
+ void setPrefetchStyle(PrefetchStyle style);
QGeoCoordinate itemPositionToCoordinate(const QDoubleVector2D &pos, bool clipToViewport = true) const Q_DECL_OVERRIDE;
QDoubleVector2D coordinateToItemPosition(const QGeoCoordinate &coordinate, bool clipToViewport = true) const Q_DECL_OVERRIDE;
diff --git a/src/location/maps/qgeotiledmap_p_p.h b/src/location/maps/qgeotiledmap_p_p.h
index 2e93a006..15442bd1 100644
--- a/src/location/maps/qgeotiledmap_p_p.h
+++ b/src/location/maps/qgeotiledmap_p_p.h
@@ -93,9 +93,12 @@ private:
private:
QAbstractGeoTileCache *m_cache;
- QGeoCameraTiles *m_cameraTiles;
+ QGeoCameraTiles *m_visibleTiles;
+ QGeoCameraTiles *m_prefetchTiles;
QGeoMapScene *m_mapScene;
QGeoTileRequestManager *m_tileRequests;
+ int m_maxZoomLevel;
+ QGeoTiledMap::PrefetchStyle m_prefetchStyle;
Q_DISABLE_COPY(QGeoTiledMapPrivate)
};