diff options
author | Michal Klocek <michal.klocek@theqtcompany.com> | 2015-07-03 15:20:46 +0200 |
---|---|---|
committer | Michal Klocek <michal.klocek@theqtcompany.com> | 2016-02-09 13:58:43 +0000 |
commit | 5fd9681a3563e2346c722bcd779e2b16cd4ac9fd (patch) | |
tree | 0d85e40638232803e25c0b42f0715e7d363a07ad /src/location/maps/qgeocameratiles.cpp | |
parent | f5f23c4279b454e2465e7f9835b04cc80332f3a0 (diff) | |
download | qtlocation-5fd9681a3563e2346c722bcd779e2b16cd4ac9fd.tar.gz |
Refactor prefetching tiles
Current implementation uses same QGeoCameraTiles object
to calculate visible tiles and tiles which should be
prefetched. This is semi optimal since frustum intersection
algorithm uses bunch of different parameters.
Simplify the logic and use separate objects, this way
values in both cases are cached and calculation is done when required.
This is important since prefetchData can be called
anytime from map's API.
Remove textured tiles from scene when clearCache called,
this will force redownload of all the tiles.
Add new unit test qgeotiledmap and move prefetch test
due to refactoring.
Change-Id: I6a906df405f212436cdd35ac76f95b559e6b7aae
Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com>
Diffstat (limited to 'src/location/maps/qgeocameratiles.cpp')
-rw-r--r-- | src/location/maps/qgeocameratiles.cpp | 85 |
1 files changed, 17 insertions, 68 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); |